很多站长部署完网站就”万事大吉”,防火墙保持默认放行策略,直到某天在日志里看到满屏的端口扫描和暴力破解记录才慌了神。事实上,Linux 服务器面临的第一波攻击往往不是高深的漏洞利用,而是端口扫描、弱口令爆破、异常流量这些”基本功”——攻击者先扫出你开放了哪些端口,再针对性地发起爆破或漏洞探测。本文从策略设计讲起,手把手带你用 firewalld 与 iptables 搭建一套”默认拒绝、按需放行”的防火墙体系,并给出可直接执行的防扫描、限速封禁命令,让你服务器的每一扇”门”都处于受控状态。
一、先想清楚:防火墙策略设计的三个原则
动手敲命令之前,先明确三条设计原则,否则规则越多越乱,最后连自己都分不清放行了什么:
- 默认拒绝优于默认放行:默认策略(Policy)设为 DROP,只对明确需要的端口放行。被扫描器”扫不出来”,比被扫出来后靠规则拦截更省心。
- 最小开放原则:对外只开放 Web(80/443)和管理端口(22),数据库、Redis、面板等一律只监听内网或受信 IP,不暴露公网。很多入侵事件都是因为 3306、6379 端口裸奔公网导致。
- 分层防护:云厂商安全组/防火墙、系统防火墙(firewalld/iptables)、应用层 WAF 三者是叠加关系,系统防火墙负责”关窗关门”,WAF 负责”拦人”。规则冲突时以最严格的为准。
另外必须理解 iptables 的规则匹配顺序:规则从上到下逐条匹配,命中即停止。所以”放行”规则要写在”拒绝”规则之前,而全局限速、防扫描规则适合放在放行规则之后兜底。顺序写反是新手最常见的错误。
顺便提醒:云服务器默认安全组一般也是放行制,改系统防火墙规则前先确认安全组没有同时放行高危端口,否则规则写了等于白写。
二、firewalld 实战:站点场景下的精准放行
CentOS 7+/Rocky/AlmaLinux 默认使用 firewalld,基于 zone(区域)管理规则,配置直观、支持运行时与永久两种状态,适合绝大多数站点场景。先确认服务状态并查看当前生效区域:
systemctl start firewalld
systemctl enable firewalld
systemctl status firewalld
firewall-cmd --get-active-zones # 查看各区域绑定的网卡
firewall-cmd --list-all # 查看当前区域所有规则
以最常见的 Web 站点场景为例,只放行 80/443/22 三个端口,其余一律拒绝:
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=22/tcp
firewall-cmd --reload
如果担心 SSH 被爆破,更稳妥的做法是默认关闭 22 端口,仅放行你办公网段的固定 IP,配合上一篇文章讲过的日志分析先确认自己的出口 IP:
# 先移除默认的 ssh 服务放行
firewall-cmd --permanent --zone=public --remove-service=ssh
# 仅放行指定来源 IP 的 22 端口(把 IP 换成你自己的出口 IP)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="120.36.x.x" port port="22" protocol="tcp" accept'
# 同理可以限定宝塔面板端口(默认 8888)只对固定 IP 开放
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="120.36.x.x" port port="8888" protocol="tcp" accept'
firewall-cmd --reload
重要警告:执行 remove-service=ssh 前,务必先确认上一条 rich-rule 添加成功,否则 reload 后你当前这条 SSH 连接会立即断开。云服务器可以通过控制台 VNC 应急登录,实体机就只能跑机房了。谨慎起见,可以先只添加 rich-rule、不删除 ssh 服务,观察一段时间再收紧。
如果需要回退或清理误加规则,用 –remove-rich-rule 同样格式移除即可;如需端口转发(例如内网机器 8080 映射到本机 80),一条命令搞定:
firewall-cmd --permanent --zone=public --add-forward-port=port=8080:proto=tcp:toport=80
firewall-cmd --reload
三、iptables 高级规则:防扫描、限速与封禁
firewalld 处理日常放行足够,但遇到需要”精准打击”的场景(封禁 IP 段、限制连接频率、防 SYN Flood),iptables 直接操作更灵活。注意两者会互相影响,生产环境建议二选一作为主防火墙,以下规则在 iptables 场景下使用。
第一步,收紧默认策略并放行必要流量:
# 修改默认策略:INPUT/FORWARD 默认丢弃
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 放行回环与已建立的连接(避免把自己和正常访问挡掉)
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 放行 80/443/22
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
第二步,封禁日志分析中发现的恶意 IP 段(参考本站《Linux 服务器日志分析实战》先揪出攻击源):
iptables -A INPUT -s 45.155.205.0/24 -j DROP
iptables -A INPUT -s 103.79.76.0/24 -j DROP
# 查看封禁结果
iptables -L INPUT -n | grep DROP
第三步,限制 SSH 新连接频率,从源头压制暴力破解:
# 每个来源 IP 每分钟最多 5 次新建 SSH 连接,超出即丢弃
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m limit --limit 5/minute --limit-burst 5 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
第四步,用 hashlimit 防端口扫描和 SYN Flood:
# 同一来源 IP 每秒 SYN 包超过 10 个即丢包(防端口扫描/半连接攻击)
iptables -A INPUT -p tcp --syn \
-m hashlimit --hashlimit-above 10/second --hashlimit-burst 20 \
--hashlimit-mode srcip --hashlimit-name syn-flood -j DROP
# 开启内核 SYN Cookies,抗小流量 SYN Flood
sysctl -w net.ipv4.tcp_syncookies=1
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf
sysctl -p
若想审计被丢弃的流量,可加一条 LOG 规则(放在 DROP 规则之前),配合日志分析持续封堵攻击源:
iptables -A INPUT -j LOG --log-prefix "IPT-DROP: " --log-level 4
# 查看丢包日志(配合 grep 过滤)
journalctl -k | grep IPT-DROP
四、规则持久化与验证
iptables 规则重启即失,必须持久化保存。Debian/Ubuntu 用 iptables-persistent,CentOS 用 iptables-services:
# Debian/Ubuntu
apt install iptables-persistent -y
iptables-save > /etc/iptables/rules.v4
iptables-restore < /etc/iptables/rules.v4 # 验证恢复
# CentOS/Rocky
yum install iptables-services -y
service iptables save
firewalld 的 –permanent 参数本身已写入配置文件,reload 后永久生效,无需额外保存。宝塔面板用户在”安全”菜单也能看到系统防火墙的端口放行列表,但面板只是入口,规则本质仍由系统防火墙执行。
最后做三层验证,确认没有把自己锁在门外:
# 1. 查看规则是否按预期生效
iptables -L -n --line-numbers
firewall-cmd --list-all
# 2. 本机测试端口连通性
curl -I http://127.0.0.1
curl -I https://127.0.0.1
# 3. 另开一个终端 SSH 保持连接,再重启防火墙服务
systemctl restart firewalld # 确认 SSH 未断,再继续后续操作
实战建议:把命令整理为初始化脚本(如 /root/fw_init.sh),新服务器上线时直接执行,既省时间又避免漏配;同时把规则变更记录到运维文档,方便后续审计回溯。
总结
防火墙优化不是”加几条规则”的孤立操作,而是”默认拒绝 + 最小开放 + 分层联动”的系统工程。本文的配置可以直接复制到你的服务器:firewalld 负责日常放行与来源限制,iptables 负责限速封禁与防扫描,配合日志分析持续封堵攻击源,就能把服务器暴露面压到最小。需要提醒的是,防火墙只能挡住”敲门”的人,真正的高强度攻击(大流量 DDoS、CC、应用层漏洞利用)还需要 WAF 和高防 CDN 配合。如果你觉得规则维护麻烦,或服务器正遭受攻击,欢迎联系速度网络,我们提供专业的服务器安全加固与高防 CDN 防护方案,帮你把每一层防线都落到实处。
