Linux 服务暴露风险的核心在于默认不开放端口、按需显式开启必要服务;盲目监听 0.0.0.0 等于暴露钥匙;应确认服务绑定 127.0.0.1,用 ss -tlnp 检查,修改 bind 配置,强化防火墙策略,默认 DROP 并精确放行,结合 systemd 依赖控制与 socket 禁用,落实最小开放原则。

Linux 服务暴露风险的核心在于:默认不开放任何 端口,只按需显式开启必要服务。盲目启用 sshd、httpd 或 mysqld 且监听 0.0.0.0,等于把钥匙挂在门口。
确认服务监听地址是否为 127.0.0.1
很多服务(如 redis-server、postgresql)默认监听 127.0.0.1,这是安全基线。一旦改配成 0.0.0.0 或空绑定,就可能被外部访问。
检查方法:
ss -tlnp | grep ':端口号'
关键看第二列(Local Address:Port)是否含 127.0.0.1;若显示 *:22 或 0.0.0.0:3306,说明已全网暴露。
- 修改
/etc/redis/redis.conf中的bind行为bind 127.0.0.1(禁用bind 0.0.0.0) - PostgreSQL 需同步调整
postgresql.conf的listen_addresses和pg_hba.conf的访问控制行 - 某些服务(如
dockerd)默认监听unix:///var/run/docker.sock,但若配置了-H tcp://0.0.0.0:2375,则直接暴露容器管理接口
防火墙 必须作为第二道防线
即使服务配置为本地监听,内核 路由 或容器网络可能绕过该限制。因此 iptables 或 nftables 不是可选项,而是强制兜底手段。
典型策略:
- 默认策略设为
DROP:iptables -P INPUT DROP - 仅放行明确需要的端口,例如仅允许 SSH 从指定 IP 段接入:
iptables -A INPUT -s 192.168.10.0/24 -p tcp --dport 22 -j ACCEPT - 禁止所有对
3306、6379、27017等数据库端口的外部连接,除非有反向代理或跳板机场景 - 使用
ufw时,避免执行ufw allow 22这类无源限制的命令;应写成ufw allow from 10.0.5.0/24 to any port 22
systemd 服务的 BindTo + BindsTo 容易被忽略
有些服务依赖其他组件(如 nginx 依赖 openssl 或上游 API),但 systemd 默认不校验依赖链是否完整。结果是服务启动了,但实际功能不可用,管理员误以为“开了就行”,反而放松了网络侧防护。
正确做法:
- 在
/etc/systemd/system/myservice.service中添加:BindTo=network.target和After=network.target,确保网络就绪后再启动 - 若服务必须配合防火墙规则生效,可增加
ExecStartPre=/usr/bin/iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null || /usr/bin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT - 禁用非必要 socket 激活:
systemctl disable myservice.socket,防止未预期的 socket 触发服务启动
最小开放原则不是“少开几个端口”,而是每次开放都伴随明确的访问来源、协议版本、TLS 强制要求和日志审计能力。最常被绕过的点是:容器内部服务监听 0.0.0.0、docker-compose.yml 中漏写 extra_hosts 导致回环调用走外网、以及云平台安全组与主机防火墙策略冲突。