Linux服务器防火墙实战:iptables与firewalld规则配置与排错全解


一、服务器防火墙为什么必须自己把控

云厂商虽然有安全组,但它是"机房外围"的过滤,无法覆盖主机内部的应用端口、本机回环和细化到进程的规则。真正的纵深防御,要在系统层面再设一道防火墙。Linux 上两套主流方案:传统 iptables(直接操作 netfilter 规则表)和更上层的 firewalld(RHEL 7+ 默认,把 iptables 管理得面向"区域 zone"和"服务 service",支持动态重载)。Ubuntu/Debian 默认也装 iptables 或 nftables。掌握它们,你才能真正做到"该开的端口才开,不该开的全封"。

二、iptables 的链与规则:一分钟建立直觉

iptables 用"表 + 链 + 规则",最常见的 filter 表有INPUT、OUTPUT、FORWARD 三条链,规则从上到下匹配,命中即决定 DROP/ACCEPT。看当前规则:

sudo iptables -L -n -v
sudo iptables -t nat -L -n   # NAT 表,端口/地址转发

这是一套"默认拒绝 + 白名单放行"的稳健起点(注意先别在远程环境一次性锁死自己):

# 允许已建立连接及回环
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT

# 开放 SSH、HTTP、HTTPS
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 默认丢弃其它入站
sudo iptables -P INPUT DROP

三、iptables 常用运维命令

# 追加/删除/插入规则(删除需与规则完全一致或用行号)
sudo iptables -A INPUT ...            # 追加到末尾
sudo iptables -I INPUT 1 ...          # 插入到第 1 位
sudo iptables -D INPUT 5              # 删除第 5 行
sudo iptables -L -n --line-numbers    # 带行号查看

# 端口转发示例:把本机 8080 转发到 127.0.0.1:9000
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 127.0.0.1:9000

# 命令行即时生效但重启丢失,需保存
sudo service iptables save            # RHEL 系
sudo iptables-save > /etc/iptables/rules.v4   # Debian/Ubuntu 手动保存

关键坑:iptables 规则即时生效但非持久化,写完后必须保存,否则重启就没了。对远程服务器改 POSTROUTING/默认策略时,一定要保留当前 SSH 连接或先加一条-I INPUT -p tcp --dport 22 -j ACCEPT,否则把自己拒之门外。

四、firewalld:面向区域的现代方案

firewalld 把网络按"区域"分组(public、trusted、internal…),通过 "rich rules" 和服务白名单来管理,改动可立即生效且无需中断连接:

# 查看默认区域与当前规则
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-all

# 永久 + 立即开放/移除某个服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reload        # 让 --permanent 生效

# 开放指定端口(Tcp 例)与重载
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload

# 禁止某 IP
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=1.2.3.4 reject'

# 指定端口转发
sudo firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=9000
sudo firewall-cmd --reload

firewalld 用 xml 保存规则到 /usr/lib/firewalld 与 /etc/firewalld,后者优先且改动用 --reload(热加载)或 --complete-reload(完全重读)。默认区域若为 public,未显式放行的端口通常都会被挡,恰好符合"默认闭合"的安全姿态。

五、iptables 与 firewalld 的取舍与共存

RHEL 系默认 firewalld 底层仍走 nftables/iptables,二者直接用规则文件会打架,应在两者间选其一为主。判断当前启用:systemctl status firewalld。混用时常见问题:用 iptables -A 加的规则被 firewalld 的全局策略覆盖或顺序冲突,导致"明明 ACCEPT 了还是不通"。稳妥做法是:firewalld 平台一律走 firewall-cmd;纯 iptables 平台(或 Ubuntu)则统一 iptables。不要一会用 iptables 一会用 firewalld 去管理同一套规则。

六、排错:为什么端口还是不通

"防火墙没放行,但连不上"要按层次排查:

# 1. 服务本身在监听吗
sudo ss -tlnp | grep :80

# 2. 防火墙是否放行
sudo iptables -L -n | grep :80
sudo firewall-cmd --list-all | grep 80

# 3. 内核 netfilter 是否被第三方(如 fail2ban、Docker、云安全组)额外拦截
sudo iptables -L -n
# Docker 会自建链,可能影响端口

# 4. 云厂商安全组/防火墙如果较严,也要在控制台放行端口

按"服务监听 → 系统防火墙 → 叠加工具链 → 云安全组"自下而上逐个排除,90% 的端口不通问题都能定位。

写在最后

防火墙是服务器安全的第一道也是最后一道闸。核心不是记命令,而是建立"默认拒绝、按需放行"的观念。实践建议:保留 SSH 端口前提下,先把 INPUT 默认策略收紧;用白名单放行 Web、数据库等确定需要的端口;规则改动即时生效必须记得持久化保存;在 iptables/firewalld 中选择一套为主,避免规则互相打架。配合 fail2ban、SSH 密钥等前面讲过的措施,你的服务器就能把暴露面压到最低。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Linux性能监控与故障排查实战:top扶手、vmstat、iostat与ss定位瓶颈

MySQL数据库优化与运维实战:慢查询、缓冲池调优与备份恢复

评 论
更换验证码