只开必要端口:nmap 自查与端口最小化
每多开一个端口,就多一个被扫描的目标。小够讲端口最小化原则:用 nmap 从外网视角自查、用 ss 从本机视角核对,关掉用不上的服务,只保留业务必需的端口,防火墙规则同步收紧。
我是小够。安全加固里有一条朴素的原则:用不上的端口,一个都别开。攻击者只能攻击"看得见"的东西,你暴露得越少,他能下手的地方越少。今天讲怎么自查和收紧。
第一步:从外网视角看自己
找另一台机器(或用在线端口扫描工具),nmap 扫你的公网 IP:
nmap -sV 你的公网IP
-sV 还会识别服务版本。扫出来的每一个开放端口,你都要能回答:这是什么服务?谁需要访问它?答不上来的,记下来,准备关。
第二步:从本机视角核对
sudo ss -tlnp
列出本机所有监听中的 TCP 端口。-p 参数会显示是哪个进程在监听,看到陌生进程名先去查,别急着杀——有可能是你装的某个软件的组件。重点看监听地址:0.0.0.0:3306 表示全网可访问,127.0.0.1:3306 表示只有本机能连。数据库、缓存这类服务,只监听 127.0.0.1,需要远程访问就走 SSH 隧道(本站有跳板机教程),别直接暴露。
ss 输出怎么读
ss -tlnp 的输出列:Netid、State、Recv-Q、Local Address:Port、Process。初学者重点看两列:Local Address:Port(监听在哪)和 Process(谁在监听)。比如看到 0.0.0.0:8080 users:(("java",pid=1234)),就知道是某个 Java 应用在监听 8080,再去确认这个应用该不该对外。Recv-Q 长期非零可能是服务处理不过来,顺带能发现性能问题,一举两得。
第三步:关服务,收端口
本机在监听、但业务用不上的服务,直接停掉并禁用自启:
sudo systemctl stop 服务名
sudo systemctl disable 服务名
常见的"默认开着但用不上":rpcbind、cups(打印)、avahi(局域网发现)。云镜像为了通用性预装了一堆东西,精简掉才是你的服务器。
第四步:防火墙同步收紧
服务关了,防火墙规则也要同步删。UFW 里删规则:
sudo ufw status numbered
sudo ufw delete 3
规则和实际服务要对得上:防火墙放行的端口,必须是业务必需的;业务必需的端口,必须在防火墙里有明确规则。两边对不齐,等于没管。
常见服务端口速查
自查时对照这张表,快速判断每个端口是干嘛的:
| 端口 | 服务 | 该不该暴露公网 |
|---|---|---|
| 22/2222 | SSH | 只对你的 IP(或经跳板机) |
| 80/443 | Web | 可以,但配好 WAF/限流 |
| 3306 | MySQL | 不该,只监听内网 |
| 5432 | PostgreSQL | 不该,只监听内网 |
| 6379 | Redis | 不该,只监听内网,且设密码 |
| 27017 | MongoDB | 不该,只监听内网,且开认证 |
| 8888/面板端口 | 宝塔/1Panel | 只对你的 IP,或走隧道 |
| 25/587 | 邮件 | 按需,25 端口很多商家默认封 |
数据库和缓存类(3306/5432/6379/27017)是重灾区:历史上大量数据泄露都是因为这些端口直接暴露在公网且没设密码。记住:数据库不出内网,这是铁律。
进阶:用 systemd socket 激活减少常驻端口
有些服务不需要 24 小时监听,比如偶尔用的管理后台。systemd 的 socket 激活可以让服务"有人连才启动":平时端口是关着的,有连接进来才拉起服务。配置稍复杂,适合爱折腾的人;普通用户把"关服务 + 防火墙"做好就够了,知道有这招就行。
写个巡检小脚本
把自查自动化,每月跑一次:
#!/bin/bash
echo "=== 监听端口 ==="
ss -tlnp | grep -v 127.0.0.1
echo "=== UFW 规则 ==="
ufw status numbered
echo "=== 可疑:监听 0.0.0.0 的非业务端口,请人工确认 ==="
输出重定向到文件,每月对比一次 diff,有新增的一目了然。自动化 + 人工确认,比纯靠记性靠谱。
多久查一次
业务变更时查(上了新应用、装了新面板),每月巡检时顺带查。nmap 自查 + ss 核对,十分钟搞定。
小够的总结:端口最小化是"免费的安全"。不花钱、不装软件,就能把攻击面砍掉一大半。记住判断标准:从公网能看到的端口,数量应该等于你的业务端口数,多一个都是多的。