CentOS系统封端口:firewalld与iptables双方案
服务器一上线,端口就是第一道门。门没关好,扫描器分分钟教你做人。CentOS下想封端口,有人只懂systemctl stop firewalld,结果裸奔;也有人抱着iptables脚本不放,重启一次规则全丢。今天把两种工具掰开揉碎,给你一套能直接复制粘贴的“双保险”操作,保准既稳又快。

先搞清楚:firewalld和iptables到底谁管谁
CentOS 7之后默认用firewalld,它底层照样喊iptables干活,只是多套了层nftables框架。理解这一点,你就明白:
/tab1. firewalld适合“新手+动态环境”,命令短,区(zone)概念清晰,改完立即生效,重启不丢。
/tab2. iptables适合“老鸟+固化场景”,规则写进文件,一条一条看得见,批量机器同步方便。
两者可以同时装,但别同时开,否则谁先谁后全靠运气,端口放不放行也靠运气。
方案A:firewalld三步封端口——30秒搞定

场景:临时封掉外界狂扫的22、3389,只允许公司出口IP连接。
步骤1 查当前活跃区,别瞎写
firewall-cmd --get-active-zones
一般回显public,那就只在public区动刀。
步骤2 一次性封,写进永久配置
firewall-cmd --permanent --zone=public --remove-port=22/tcp

firewall-cmd --permanent --zone=public --remove-port=3389/tcp
步骤3 加重载,让配置落地
firewall-cmd --reload
reload完再用nmap -p 22 本机IP扫一眼,端口状态filtered,说明已丢进黑洞。想放行公司IP?先加源地址:
firewall-cmd --permanent --zone=trusted --add-source=203.0.113.0/24
firewall-cmd --permanent --zone=trusted --add-port=22/tcp
trusted区默认全放行,源地址匹配就走trusted,其他来源继续吃闭门羹。
方案B:iptables四行命令——重启也稳
场景:机器装了旧脚本,firewalld早被阉割,或者你就是喜欢手写链。
第1行 先保存当前规则,防手滑
iptables-save > /etc/sysconfig/iptables.bak
第2行 在INPUT链最前面插入拒绝规则
iptables -I INPUT 1 -p tcp --dport 22 -s ! 203.0.113.0/24 -j DROP
注意“! 203.0.113.0/24”代表非该网段全部干掉,顺序别写反。
第3行 同理封3389
iptables -I INPUT 2 -p tcp --dport 3389 -j DROP
第4行 立即保存,让重启不丢
service iptables save
CentOS 7若提示没service,直接iptables-save > /etc/sysconfig/iptables一样生效。保存完systemctl restart iptables再扫,端口消失。
混合打法:firewalld做日常,iptables守底线
有的安全合规要求“双层异构”,那就让firewalld管常规业务,iptables写最后一条“兜底拒绝”。
/tab1. firewalld照常开放80、443,关闭高危口。
/tab2. 在iptables的尾部加一条:
iptables -A INPUT -j LOG --log-prefix "DROP_ALL "
iptables -A INPUT -j DROP
这样即使firewalld被误操作放行,iptables最后一把大锁依旧能把包扔进日志再丢弃。排障时翻/var/log/messages,看前缀DROP_ALL就能定位漏网之鱼。
常见翻车点提前踩坑
1. 只关服务不关规则
有人systemctl stop firewalld就以为安全,其实规则还在内存,重启又自动起,端口重新被扫。正确姿势是systemctl disable firewalld再配iptables。
2. 富规则语法写错
firewalld富规则长这样:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="22" protocol="tcp" drop'
引号、family、protocol一个都不能少,写错直接报错,还不提示在哪。
3. iptables顺序乱插
iptables按链顺序匹配,-A追加到尾部常被前面的放行规则覆盖。用-I INPUT 1插到最前才保险。
4. IPv6忘关
现在扫描器双栈齐下,只封IPv4不管ip6tables,等于门没关严。同理:
ip6tables -A INPUT -p tcp --dport 22 -j DROP
一条命令,别偷懒。
一键脚本:懒人直接跑
把下面内容存成close_port.sh,chmod +x后root执行,自动判断系统用firewalld还是iptables,封掉指定端口。
#!/bin/bash
PORT=$1
if [[ -z $PORT ]];then echo "Usage: $0 <port>";exit;fi
if systemctl is-active firewalld &>/dev/null;then
firewall-cmd --permanent --remove-port=$PORT/tcp
firewall-cmd --permanent --remove-port=$PORT/udp
firewall-cmd --reload
else
iptables -I INPUT -p tcp --dport $PORT -j DROP
iptables -I INPUT -p udp --dport $PORT -j DROP
service iptables save
fi
echo "Port $PORT closed."
执行./close_port.sh 6379,Redis默认端口瞬间隐身。
检查生效:最笨也最有效的三招
1. 外部扫描:nmap -p 端口号 服务器公网IP,状态filtered或closed都算安全。
2. 本地监听:ss -tunlp | grep 端口号,看进程是否还绑着,防止业务自己拉端口。
3. 日志跟踪:tail -f /var/log/messages,iptables若加LOG,能实时看到被丢的包的源IP,顺势加黑名单。
封端口不是一次性买卖,是持续运营。今天封22,明天可能冒出新的高危服务,脚本+巡检+日志,三件套跑起来,才算把门真正锁死。
