1. 出站连接明明可控,为什么大多数服务器还是裸奔
先说个我一直很困惑的现象:很多团队在服务器上花大力气配安全组、配防火墙,入站规则写得密密麻麻,恨不得只留 80/443 和 SSH 端口,但出站连接几乎不设防。默认情况下,CentOS/RHEL 的防火墙只拦入站,不拦出站,也就是说一旦机器被种了木马、被拿到 shell,攻击者想往外传数据、想下载工具、想连回控制端,基本都是畅通无阻的。
出站连接控制的价值就在这儿:它不是为了拦住别人进来,而是为了拦住“这台机器主动出去”。它解决的是两种情况,一是机器已经被攻破后的横向移动和反向连接,二是机器上某些业务进程在偷偷往外发数据。如果你只做入站防护,等于只锁了前门,但后门和所有窗户都是敞开的。很多安全基线检查里也会明确要求“禁止服务器主动外联”,这在等保、PCI-DSS 这些标准里尤其常见。
这篇文章就是围绕 CentOS / RHEL 上如何把出站连接管起来展开的。我会从 firewalld 和 iptables 两条路线分别讲清楚,也会把默认拒绝出站、按目标 IP 拦截、按用户限制外联这些操作细节一并给你。内容适合两类人看:一是要加固服务器、应付合规检查的运维同学,二是刚接触防火墙、想搞明白 OUTPUT 链到底怎么玩的初学者。我会尽量讲得像做实验一样,每一条命令你都能直接拿到机器上去试。
这里先抛一个结论:出站拦截不是“把 OUTPUT 链设成 DROP”就完事了。难的不是那一条 DROP 规则,难的是在白名单里放行哪些必要流量,以及规则写错之后怎么快速定位问题。后面我踩过的坑,基本都集中在这两个地方。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前先把家底盘清楚
2.1 先判断当前用的是 firewalld 还是 iptables
CentOS 6 默认是 iptables,CentOS 7 以后默认换成了 firewalld,但很多人在 CentOS 7/8 上仍然手动装回 iptables-services,或者干脆把 firewalld 停掉,自己用 iptables 命令灌规则。RHEL 8/9 的情况就更特殊一点,默认 firewalld 的后端是 nftables,你敲 iptables 命令也能用,但它其实是 nftables 的兼容层,规则展示方式和老版本不完全一样。
在开始改配置之前,先确认系统现在到底是谁在管网络过滤:
bash复制systemctl status firewalld
看输出如果是 active,后面就用 firewall-cmd。如果提示 Unit firewalld.service could not be found,或者状态是 inactive,那大概率是 iptables-services 或者裸的 nftables 在管。
再看一下当前 nftables 规则集,能帮助你了解现有的防火墙全家桶:
bash复制nft list ruleset
这一步不是多此一举。我见过不少机器,明明 firewalld 关了,但 nftables 里还留着 Docker 或 libvirt 塞进去的一大堆链;也见过 firewalld 开着的机器,却有人手动往 iptables 里加规则,两条通道同时在跑。你连底层是谁都不清楚,后面排查出站拦截不生效的时候,很容易被这种“双轨制”坑到怀疑人生。
2.2 规则备份和可回滚方案
修改防火墙规则之前,把当前规则完整导出来做备份,这是最便宜的一道保险。
firewalld 下可以直接导出所有永久配置目录,或者把当前运行时规则打出来:
bash复制mkdir -p /root/fw-backup
firewall-cmd --direct --get-all-rules > /root/fw-backup/direct-rules.txt
firewall-cmd --list-all > /root/fw-backup/zone-default.txt
iptables 模式下更简单,一行命令就把规则集存下来了:
bash复制iptables-save > /root/fw-backup/iptables.rules.$(date +%F_%H%M)
万一后面规则把自己锁死了,至少还能用备份文件恢复。尤其是你要在远程服务器上做默认拒绝出站这种高危操作,强烈建议先把当前 SSH 连接保持住,再用 tmux/screen 挂一个会话,或者准备一个定时任务来释放规则,给自己留一条后路。
2.3 一张表看明白 OUTPUT/FORWARD/INPUT 的关系
很多新手混淆出站和转发,我先给一个简单的对照表,后面所有操作都基于这个概念。
| 链 | 流量方向 | 典型场景 |
|---|---|---|
| INPUT | 进入本机的数据包 | 别人访问你的 80 端口,外部包进到本机进程 |
| OUTPUT | 本机进程主动发出去的数据包 | 你用 curl 访问外网、服务器主动连接数据库 |
| FORWARD | 经过本机但不住在本机的数据包 | Docker 容器访问外网、路由器转发流量 |
拦截出站连接,核心操作的是 OUTPUT 链。但要注意,如果这台机器上跑着 Docker,容器访问外网走的通常不是宿主机
