检查开放端口与关闭高危服务
用 ss/nmap 摸清服务器到底开了哪些端口,把不该暴露的服务收回内网,守住最小暴露面。
服务器被入侵,十有八九是因为某个「你都忘了它在跑」的服务对着公网敞开着门。数据库、缓存、调试面板、旧版应用……每多开一个端口,就多一个被扫描、被爆破的入口。定期盘点端口、关掉不用的服务,是投入产出比最高的一项安全动作。
第一步:看本机在监听哪些端口
登录服务器,先看本机自己开了哪些监听端口。推荐用 ss(现代替代 netstat):
# -t TCP -u UDP -n 数字端口 -l 监听中 -p 显示进程
sudo ss -tunlp
重点看 Local Address:Port 这一列:
- 127.0.0.1:5432 —— 只绑在本地回环,外部访问不到,安全。
- 0.0.0.0:5432 或 :5432 —— 绑在所有网卡,公网可达,危险。
- [::]:3306 —— IPv6 的「所有地址」,同样对外暴露。
0.0.0.0 和 :: 是最需要警惕的信号。旧系统上也可以用 sudo netstat -tunlp,输出含义一致。
第二步:从外部扫一遍
本机视角会漏掉防火墙、云安全组的影响。真正要确认的是「从公网能连到什么」。在另一台机器(或你的电脑)上用 nmap 扫服务器的公网 IP:
# 扫常见 1000 端口
nmap <你的服务器IP>
# 全端口 + 服务版本识别(较慢,但更全)
nmap -p- -sV <你的服务器IP>
外部扫描结果才是攻击者眼中的真实暴露面。如果 3306(MySQL)、5432(PostgreSQL)、6379(Redis)、27017(MongoDB)、9200(Elasticsearch)出现在这里,几乎可以肯定是配置失误。
第三步:识别不该开的服务
对照下面这类高危项逐一排查:
- 数据库对公网:MySQL、PostgreSQL、MongoDB 直接暴露,极易被扫库爆破。
- Redis/Memcached 无密码裸奔:6379 对公网 = 主动交出服务器,是被挖矿的头号入口。
- 旧的、忘记关的服务:测试环境、上一版应用、临时开的调试端口。
- 管理面板:数据库管理页、监控后台不应直接对外。
判断原则很简单:这个端口需要被公网访问吗? 不需要,就收回去。
第四步:收口——绑内网、停服务、上防火墙
按下面的顺序处理,层层收窄:
1. 只绑本地回环。 服务如果只给本机用,改配置绑到 127.0.0.1。例如 Redis 的 redis.conf:
bind 127.0.0.1 -::1
PostgreSQL 改 listenaddresses = 'localhost',MySQL 设 bind-address = 127.0.0.1。改完重启服务,再回到第一步验证。
2. 停用并卸载不需要的服务。
sudo systemctl disable --now <服务名> # 停止并禁止开机自启
sudo apt purge <包名> # 确定不用了就彻底卸载
3. 用防火墙兜底。 即便服务绑了 0.0.0.0,防火墙也能挡在外面。用 ufw 白名单放行,默认拒绝:
sudo ufw default deny incoming
sudo ufw allow 22/tcp # SSH,别把自己关外面
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
若云厂商提供安全组,同样按最小化配置,与主机防火墙形成双保险。
小结
安全的核心是最小暴露面:每个开放端口都必须有明确理由。养成习惯——先 ss -tunlp 看本机监听,再 nmap 从外部核实,盯紧 0.0.0.0 和数据库/Redis 端口;不用的服务就绑回 127.0.0.1、停用卸载,最后用防火墙默认拒绝兜底。每次上线新服务后重扫一遍,把「无意间敞开的门」在被人发现之前关上。