一、防火墙核心原理与架构
1.1 防火墙本质与分类
防火墙是网络边界的访问控制设备 / 机制,核心是按预设规则过滤数据包,实现 "允许合法流量、阻断非法流量" 的目标,主要分为两类:
- 硬件防火墙:专用硬件设备(如华为 USG、思科 ASA),操作系统极简,仅保留数据包过滤核心功能,性能高、稳定性强,适合企业级组网;
- 软件防火墙 :基于操作系统内核 / 应用层实现的防护机制,Linux 下核心是Netfilter 内核模块,iptables/firewalld 是其用户态管理工具,轻量化、灵活,适合服务器单机防护。
1.2 Netfilter 内核机制(Linux 防火墙的核心)
Netfilter 是 Linux 内核 2.4 及以上版本内置的数据包过滤框架,嵌入在 TCP/IP 协议栈中,可在数据包流经内核的 5 个关键节点(钩子函数)执行过滤 / 修改操作,对应 OSI 模型的 2/3/4 层(数据链路层、网络层、传输层):
- 核心能力 :
- 基于 IP(源 / 目标)、端口(源 / 目标)、协议(TCP/UDP/ICMP)过滤;
- 基于 MAC 地址、TCP 标志位(SYN/ACK/FIN 等)过滤;
- 网络地址转换(NAT)、端口转发、流量整形;
- 局限性 :
- 无法识别应用层内容(如 HTTP 请求的 URL、病毒特征),需结合 WAF/IDS/IPS;
- 对内部 LAN 的攻击(如 ARP 欺骗)防护能力弱,需配合其他安全工具;
- 仅能过滤 "路过" 的数据包,无法阻止合法端口下的恶意流量(如 80 端口的 SQL 注入)。
1.3 iptables vs firewalld 核心差异
| 维度 | iptables | firewalld |
|---|---|---|
| 工作模式 | 静态:修改规则需重载全部规则 | 动态:仅更新变更的规则,无需重载 |
| 核心概念 | 表 - 链 - 规则 | 区域(Zone)- 服务 - 端口 - 富规则 |
| 规则持久化 | 需手动保存(iptables-save) | 支持临时 / 永久规则(--permanent) |
| 适用场景 | 复杂自定义规则、脚本化管理 | 快速配置、动态变更、多区域切换 |
| 依赖 | 直接操作 Netfilter 钩子 | 底层仍调用 iptables 规则,封装更友好 |
二、iptables 深度详解
2.1 核心架构:表 - 链 - 规则
iptables 通过 "表" 组织不同功能的 "链",链中存放具体的 "规则",数据包流经内核时,按表→链→规则的顺序匹配执行:
(1)4 张核心表(功能分类)
| 表名 | 核心功能 | 包含的链 |
|---|---|---|
| filter | 数据包过滤(默认表) | INPUT、OUTPUT、FORWARD |
| nat | 网络地址转换(NAT) | PREROUTING、POSTROUTING、OUTPUT |
| mangle | 数据包修改(TTL、标记等) | 所有 5 条链 |
| raw | 禁用连接追踪(加速流量) | PREROUTING、OUTPUT |
(2)5 条内置链(数据包处理位置)
| 链名 | 数据包流经时机 | 典型用途 |
|---|---|---|
| PREROUTING | 路由选择前(进入网卡后、路由表查询前) | 目标地址转换(DNAT)、端口转发 |
| INPUT | 路由后(目标为本机,进入用户空间前) | 过滤流入本机的流量(如 SSH/80 端口) |
| OUTPUT | 本机产生的流量(离开用户空间后、路由前) | 过滤本机流出的流量 |
| FORWARD | 路由后(目标为其他主机,转发至其他网卡) | 过滤转发的流量(如路由器场景) |
| POSTROUTING | 路由后(离开本机网卡前) | 源地址转换(SNAT)、伪装(MASQUERADE) |
(3)规则匹配顺序
- 数据包进入内核,先经过 raw 表→mangle 表→nat 表(PREROUTING 链);
- 路由表判断:目标为本机→INPUT 链(filter/mangle 表)→用户空间程序;目标为其他主机→FORWARD 链(filter/mangle 表)→POSTROUTING 链(nat/mangle 表);
- 本机产生的流量:OUTPUT 链(raw/mangle/nat/filter 表)→POSTROUTING 链;
- 规则按 "从上到下" 匹配,匹配成功立即执行动作,无匹配则执行链的默认策略(ACCEPT/REJECT/DROP)。
2.2 完整命令语法与扩展参数
iptables [-t 表名] [操作命令] [链名] [规则号] [匹配条件] [-j 动作]
(1)操作命令(核心)
| 命令 | 完整参数 | 说明 |
|---|---|---|
| -A | --append | 在链末尾追加规则(不影响已有规则) |
| -I | --insert | 在指定位置插入规则(默认第 1 条),如iptables -I INPUT 3(插入到第 3 条) |
| -D | --delete | 删除规则(可指定规则号或完整规则),如iptables -D INPUT 1 |
| -R | --replace | 替换指定规则,如iptables -R INPUT 2 -p tcp --dport 80 -j ACCEPT |
| -F | --flush | 清空链中所有规则(iptables -F清空所有表的所有链) |
| -P | --policy | 设置链的默认策略,仅内置链支持,如iptables -P INPUT DROP |
| -L | --list | 列出规则(-n数字显示 IP / 端口,--line-numbers显示规则号) |
| -Z | --zero | 清零规则的流量计数器(包数 / 字节数) |
(2)匹配条件(基础 + 扩展)
| 类型 | 参数 | 说明 |
|---|---|---|
| 协议匹配 | -p tcp/udp/icmp/all |
匹配指定协议,-p all匹配所有协议 |
| IP 匹配 | -s 192.168.1.100 |
源 IP / 子网,! -s表示排除,如! -s 192.168.1.0/24 |
-d 10.0.0.1 |
目标 IP / 子网,用法同-s |
|
| 端口匹配 | --sport 22 |
源端口(仅 TCP/UDP),支持范围--sport 1000:2000 |
--dport 80 |
目标端口,用法同--sport |
|
| 网卡匹配 | -i eth0 |
入站网卡(仅 INPUT/FORWARD/PREROUTING) |
-o eth1 |
出站网卡(仅 OUTPUT/FORWARD/POSTROUTING) | |
| TCP 标志位 | --tcp-flags SYN,ACK SYN |
匹配 TCP 标志位(第一个参数是要检查的标志,第二个是必须匹配的),如阻止 SYN 洪水 |
| ICMP 类型 | --icmp-type 8 |
匹配 ICMP 类型(8 = 请求回显,0 = 回显应答),如禁止 ping:-p icmp --icmp-type 8 -j DROP |
(3)动作(target)
| 动作 | 说明 |
|---|---|
| ACCEPT | 放行数据包(继续流经内核) |
| REJECT | 拒绝数据包,返回错误报文(如 ICMP port unreachable),客户端知道被拒绝 |
| DROP | 丢弃数据包(无任何回应),客户端超时,更隐蔽 |
| LOG | 记录日志(/var/log/messages),需配合-j LOG --log-prefix "iptables: " |
| SNAT/DNAT | 地址转换(仅 nat 表),如-j SNAT --to-source 公网IP |
| MASQUERADE | 动态源地址转换(适用于公网 IP 动态分配,如拨号上网) |
2.3 高级实操案例
案例 1:基础防护规则(默认拒绝,仅放行必要端口)
# 1. 清空所有规则,设置默认策略
iptables -F
iptables -P INPUT DROP # 入站默认拒绝
iptables -P OUTPUT ACCEPT # 出站默认允许
iptables -P FORWARD DROP # 禁止转发(非路由器场景)
# 2. 允许回环网卡(lo)流量(本机内部通信必需)
iptables -I INPUT -i lo -j ACCEPT
# 3. 允许已建立的连接(如本机主动访问外网后的回应流量)
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 4. 放行SSH(22端口)、HTTP(80)、HTTPS(443)
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# 5. 仅允许指定IP段(192.168.1.0/24)访问SSH
iptables -R INPUT 4 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
# 6. 禁止ping(ICMP请求),但允许本机ping外网
iptables -I INPUT -p icmp --icmp-type 8 -j DROP
iptables -I OUTPUT -p icmp --icmp-type 8 -j ACCEPT
# 7. 记录所有被拒绝的流量(日志前缀标记)
iptables -I INPUT -j LOG --log-prefix "iptables_DROP: " --log-level 6
案例 2:NAT 地址转换(内网访问外网)
# 场景:本机作为网关,内网段192.168.1.0/24通过eth0(公网IP:203.0.113.10)访问外网
# 1. 开启内核转发(必需)
echo "1" > /proc/sys/net/ipv4/ip_forward
# 永久生效:echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p
# 2. nat表POSTROUTING链设置SNAT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.10
# 动态IP场景(如拨号上网),用MASQUERADE替代SNAT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
案例 3:端口转发(外网访问内网 Web 服务)
# 场景:外网访问本机8080端口,转发到内网192.168.1.50的80端口
# 1. PREROUTING链(DNAT)修改目标地址/端口
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.50:80
# 2. 放行转发流量(filter表FORWARD链)
iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 80 -j ACCEPT
案例 4:规则持久化(重启不丢失)
# 保存当前规则到文件
iptables-save > /etc/sysconfig/iptables
# 开机自动加载规则(CentOS7)
systemctl enable iptables
# 手动加载规则
iptables-restore < /etc/sysconfig/iptables
三、firewalld 深度详解
3.1 核心概念:区域(Zone)
firewalld 将不同的网络环境抽象为 "区域",每个区域预设一套规则模板,可根据网卡 / 源 IP 绑定不同区域,实现 "不同网络环境不同策略":
(1)9 个预设区域(优先级从高到低)
| 区域 | 安全级别 | 核心策略 | 适用场景 |
|---|---|---|---|
| trusted | 最高 | 允许所有入站 / 出站流量 | 内网可信环境(如服务器集群) |
| home/work | 中高 | 拒绝入站流量,仅允许与出站相关的回应流量 + 预定义服务(SSH/MDNS 等) | 家庭 / 办公内网 |
| internal | 中高 | 同 home,适用于 "内部网络" 标识 | 企业内网 |
| public | 中等 | 不信任外部网络,仅允许指定服务 / 端口(默认区域) | 公网服务器(云服务器) |
| dmz | 中低 | 仅允许指定服务(如 HTTP/SSH),隔离区(非军事区) | 对外服务的中间服务器 |
| external | 中低 | 拒绝入站流量,允许 SSH + 出站回应,自动 SNAT(适用于网关) | 外网网关 |
| block | 低 | 拒绝所有入站流量,返回 ICMP 不可达报文 | 高安全需求的服务器 |
| drop | 最低 | 丢弃所有入站流量,无任何回应(最隐蔽) | 防攻击的关键服务器 |
(2)区域绑定方式
- 按网卡绑定 :将物理网卡绑定到区域,如
firewall-cmd --permanent --zone=public --add-interface=eth0; - 按源 IP 绑定 :将指定 IP / 子网流量导向区域,如
firewall-cmd --permanent --zone=trusted --add-source=192.168.1.0/24; - 默认区域 :未绑定的网卡 / IP 均使用默认区域(public),可修改:
firewall-cmd --set-default-zone=work。
3.2 核心管理工具:firewall-cmd
(1)规则生效模式
| 模式 | 命令特征 | 生效时机 | 重启后是否保留 |
|---|---|---|---|
| 临时生效 | 无--permanent参数 |
立即生效 | 不保留 |
| 永久生效 | 加--permanent参数 |
执行firewall-cmd --reload或重启后生效 |
保留 |
(2)高频操作命令
# 1. 基础信息查询
firewall-cmd --get-default-zone # 查询默认区域
firewall-cmd --get-active-zones # 查询当前活跃区域(绑定的网卡/IP)
firewall-cmd --list-all --zone=public # 查看public区域的所有规则
firewall-cmd --list-services --zone=dmz # 查看dmz区域允许的服务
# 2. 区域配置
firewall-cmd --permanent --set-default-zone=dmz # 设置默认区域为dmz
firewall-cmd --permanent --zone=trusted --add-source=10.0.0.0/8 # 允许10段IP进入trusted区域
firewall-cmd --permanent --zone=public --remove-interface=eth1 # 解绑eth1网卡
# 3. 服务/端口管理
# 允许HTTP服务(永久)
firewall-cmd --permanent --add-service=http
# 允许8080/tcp端口(永久)
firewall-cmd --permanent --add-port=8080/tcp
# 禁止SSH服务(临时)
firewall-cmd --remove-service=ssh
# 批量允许端口范围(1000-2000/tcp)
firewall-cmd --permanent --add-port=1000-2000/tcp
# 4. 规则重载与查看
firewall-cmd --reload # 重载永久规则(不中断现有连接)
firewall-cmd --list-ports # 查看当前区域允许的端口
firewall-cmd --list-services # 查看当前区域允许的服务
(3)富规则(Rich Rules):复杂规则配置
firewalld 的 "富规则" 支持更精细的流量控制(IP、端口、协议、动作、日志),语法类似 XML,适用于复杂场景:
# 语法模板
firewall-cmd --permanent --add-rich-rule='rule [family="ipv4/ipv6"] [source address="IP/子网"] [destination address="IP/子网"] [service name="服务名"] [port port="端口" protocol="tcp/udp"] [log] [accept/reject/drop]'
富规则案例:
# 案例1:仅允许192.168.1.100访问SSH,拒绝其他IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100/32" service name="ssh" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="ssh" reject'
# 案例2:禁止10.0.0.5访问80端口,记录日志
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5/32" port port="80" protocol="tcp" log prefix="BLOCK_80_PORT: " level="warning" reject'
# 案例3:端口转发(172.24.8.0/24访问5423→80端口)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="172.24.8.0/24" forward-port port="5423" protocol="tcp" toport="80" toaddr="172.24.8.128"'
# 案例4:SNAT(内网192.168.1.0/24通过eth0出口伪装成公网IP)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" masquerade'
3.3 图形化工具:firewall-config
适用于桌面版 CentOS7,通过firewall-config命令启动,可视化操作:
- 左侧选择区域,右侧可配置 "服务、端口、富规则、源 IP、网卡";
- 顶部 "永久 / 运行时" 切换生效模式;
- 支持一键重载规则、添加自定义服务。
四、常见服务的防火墙规则配置(实战)
4.1 NTP 服务(网络时间同步,123/udp)
iptables 配置
# 允许入站NTP(123/udp)
iptables -I INPUT -p udp --dport 123 -j ACCEPT
# 仅允许内网192.168.1.0/24访问NTP
iptables -I INPUT -p udp -s 192.168.1.0/24 --dport 123 -j ACCEPT
firewalld 配置
# 永久允许NTP服务
firewall-cmd --permanent --add-service=ntp
# 仅允许192.168.1.0/24访问NTP(富规则)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ntp" accept'
firewall-cmd --reload
4.2 SSH 服务(远程登录,22/tcp)
iptables 配置(仅允许指定 IP)
iptables -F INPUT
iptables -P INPUT DROP
# 允许回环网卡+已建立连接
iptables -I INPUT -i lo -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 仅允许192.168.1.0/24和203.0.113.5访问SSH
iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -s 203.0.113.5/32 --dport 22 -j ACCEPT
firewalld 配置(禁止特定 IP)
# 永久允许SSH服务
firewall-cmd --permanent --add-service=ssh
# 禁止10.0.0.100访问SSH
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.100/32" service name="ssh" reject'
firewall-cmd --reload
4.3 Nginx 服务(80/tcp、443/tcp)
iptables 配置
# 允许HTTP/HTTPS入站
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# 限制单IP并发连接数(防CC攻击)
iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 100 -j DROP
firewalld 配置
# 永久允许HTTP/HTTPS服务
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 允许8080端口(Nginx反向代理)
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
4.4 NFS 服务(2049/tcp/udp、111/tcp/udp)
iptables 配置
# 允许RPC绑定(111端口)
iptables -I INPUT -p tcp --dport 111 -j ACCEPT
iptables -I INPUT -p udp --dport 111 -j ACCEPT
# 允许NFS(2049端口)
iptables -I INPUT -p tcp --dport 2049 -j ACCEPT
iptables -I INPUT -p udp --dport 2049 -j ACCEPT
# 仅允许内网192.168.1.0/24访问
iptables -R INPUT 1 -p tcp -s 192.168.1.0/24 --dport 111 -j ACCEPT
iptables -R INPUT 3 -p tcp -s 192.168.1.0/24 --dport 2049 -j ACCEPT
firewalld 配置
# 永久允许NFS和rpc-bind服务
firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
# 仅允许192.168.1.0/24访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="nfs" accept'
firewall-cmd --reload
4.5 DNS 服务(53/tcp、53/udp)
iptables 配置
# 允许DNS查询(53/udp为主,53/tcp用于区域传输)
iptables -I INPUT -p udp --dport 53 -j ACCEPT
iptables -I INPUT -p tcp --dport 53 -j ACCEPT
# 仅允许内网访问DNS
iptables -R INPUT 1 -p udp -s 192.168.0.0/16 --dport 53 -j ACCEPT
firewalld 配置
# 永久允许DNS服务
firewall-cmd --permanent --add-service=dns
# 限制仅内网访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/16" service name="dns" accept'
firewall-cmd --permanent --remove-service=dns # 移除全局DNS允许
firewall-cmd --reload
五、防火墙运维与排错
5.1 常见问题排查
- 规则不生效 :
- 检查 iptables/firewalld 是否冲突(仅启动一个);
- firewalld 规则需确认
--permanent和--reload; - iptables 规则检查匹配顺序(默认策略是否覆盖)。
- 端口无法访问 :
- 用
telnet 目标IP 端口测试连通性; - 检查规则是否放行对应协议(TCP/UDP);
- 查看内核转发是否开启(
sysctl net.ipv4.ip_forward)。
- 用
- 日志分析 :
- iptables 日志:
grep iptables /var/log/messages; - firewalld 日志:
journalctl -u firewalld。
- iptables 日志:
5.2 最佳实践
- 最小权限原则:仅放行必要的端口 / 服务,默认策略设为拒绝(iptables-P INPUT DROP/firewalld 用 drop/block 区域);
- 规则分层:先放行回环网卡、已建立连接,再放行特定服务;
- 持久化规则:确保重启后规则不丢失(iptables-save/firewalld --permanent);
- 避免冲突:同一服务器仅启用 iptables 或 firewalld,禁止同时运行;
- 监控审计:定期检查规则(iptables -L -n/firewall-cmd --list-all),记录规则变更。