linux服务-iptables 原理及示例详解
iptables 原理及示例详解
一、核心原理
iptables 是 Linux 内核中的包过滤防火墙工具,基于 netfilter 框架工作。它在数据包传输的关键路径上设置 “钩子点”,通过一系列规则链对数据包进行检查、修改或丢弃,是 Linux 系统网络安全防护的核心工具。
-
工作流程
-
数据包到达网卡后,进入内核网络协议栈;
-
数据包按顺序经过不同的 链(Chain),链中包含若干按顺序排列的 规则(Rule);
-
规则按添加顺序依次匹配,匹配成功则执行指定 动作(Target),后续规则不再生效;
-
若所有规则均不匹配,数据包将执行该链的 默认策略(Policy)。
-
二、核心结构:四表五链
iptables 的核心是 “表” 和 “链”,表按功能分类规则,链定义数据包的流转路径
2.1、四表五链说明
-
四表(功能分类,按优先级从高到低)
表名 核心作用 常用链 优先级 raw 最高优先级,用于跳过数据包的连接跟踪处理,减少系统资源占用,提升转发性能 PREROUTING、OUTPUT 1 mangle 用于修改数据包的标记信息(如 TTL、TOS、MAC 地址、IP 选项等) PREROUTING、POSTROUTING、OUTPUT、INPUT、FORWARD 2 nat 实现网络地址转换(IP / 端口映射、源地址伪装等),适用于网关型防火墙(多网卡) PREROUTING、POSTROUTING、OUTPUT 3 filter 最常用表,负责数据包的过滤(允许 / 拒绝),适用于主机型防火墙(单网卡) INPUT、FORWARD、OUTPUT 4 -
五链(数据包流转路径)
链名 核心作用 适用场景 PREROUTING 路由选择前处理数据包,可修改目标地址 / 端口 端口映射(DNAT)、拦截访问 INPUT 处理目标为本机的入站数据包 限制外部访问本机端口 FORWARD 处理目标非本机、需转发到其他主机的数据包 网关转发、跨网段数据过滤 OUTPUT 处理从本机发出的出站数据包 限制本机访问外部网络 / 端口 POSTROUTING 路由选择后处理数据包,可修改源地址 / 端口 源地址转换(SNAT)、地址伪装 - 数据包流转示例
- 外部主机访问本机 80 端口:
PREROUTING → INPUT - 本机访问外部网站:
OUTPUT → POSTROUTING - 内网机器通过网关访问外网:
PREROUTING → FORWARD → POSTROUTING
- 外部主机访问本机 80 端口:
- 数据包流转示例
2.2、示意图
-
图表 1:数据包入站 + 路由选择流程(含 PREROUTING/INPUT/FORWARD)
-
图表 2:数据包出站流程(含 OUTPUT 链)
-
图表 3:数据包最终转发 / 出站(含 POSTROUTING)
-
三张图表的逻辑关联:
- 图表 1 负责「入站接收 + 路由判断」:处理外部进来的数据包,区分 “目标本机” 和 “需要转发” 两条路径;
- 图表 2 负责「本机出站」:处理本机应用发出的数据包,完成出站过滤和地址转换;
- 图表 3 负责「最终出站 / 转发」:所有需要离开服务器的数据包(转发的、本机出站的),最终经过 POSTROUTING 链完成源地址转换后离开网卡。
三、iptables 常用参数
3.1、核心参数(全局操作)
| 参数 | 作用 |
|---|---|
-t <表名> | 指定操作的表(默认 filter 表),可选值:filter、nat、mangle、raw |
-L | 列出指定表的所有规则(默认列出 filter 表) |
-F | 清空指定表的所有规则(默认清空 filter 表) |
-X | 删除指定表的自定义链(默认删除 filter 表) |
-Z | 重置指定表的链计数器(包数、字节数)(默认重置 filter 表) |
-P <链名> <动作> | 设置指定链的默认策略(动作:ACCEPT、DROP) |
-N <链名> | 创建自定义链(需配合 -t 指定表) |
-E <旧链名> <新链名> | 重命名自定义链 |
3.2、规则操作参数
(添加 / 删除 / 修改规则)
| 参数 | 作用 |
|---|---|
-A <链名> | 在指定链的末尾添加一条规则 |
-I <链名> [编号] | 在指定链的开头(或指定编号位置)插入一条规则(编号默认 1) |
-D <链名> <编号> | 删除指定链中指定编号的规则 |
-R <链名> <编号> | 修改指定链中指定编号的规则 |
-S <链名> | 显示指定链的规则(含详细参数) |
3.3、匹配条件参数
(过滤数据包的依据)
-
基本匹配条件(无需额外模块)
参数 作用 -s <源IP/网段>匹配数据包的源 IP 地址或网段(如 192.168.1.100、192.168.1.0/24)-d <目标IP/网段>匹配数据包的目标 IP 地址或网段 -p <协议>匹配数据包的协议(如 tcp、udp、icmp、all)-i <网卡名>匹配数据包的入站网卡(如 eth0、lo)-o <网卡名>匹配数据包的出站网卡(如 eth0、lo) -
扩展匹配条件(需加载对应模块,用
-m指定)参数 模块 作用 --dport <端口>tcp/udp匹配目标端口(如 --dport 80匹配 HTTP 端口)--sport <端口>tcp/udp匹配源端口 --state <状态>state匹配连接状态(如 ESTABLISHED、NEW、RELATED、INVALID)--limit <速率>limit限制数据包速率(如 --limit 10/s每秒最多 10 个包)--limit-burst <数>limit允许突发数据包数量(配合 --limit使用,如--limit-burst 20)--string <字符串>string匹配数据包中的字符串(如 --string "/admin"匹配 URL 路径)--seconds <秒>recent设定近期列表的时间范围(如 --seconds 60匹配 60 秒内的连接)--hitcount <次数>recent匹配近期列表中 IP 的连接次数(如 --hitcount 5匹配 5 次以上连接)
3.4、动作参数
(匹配规则后的处理方式)
| 动作名称 | 适用表 | 核心作用 | 典型场景 |
|---|---|---|---|
| ACCEPT | 所有表 | 允许数据包通过,继续后续网络流程 | 开放合法端口(如 80、443)、允许信任 IP 访问 |
| DROP | 所有表 | 直接丢弃数据包,不返回任何响应(对端显示超时) | 屏蔽恶意 IP、拒绝非法端口访问(隐藏服务存在) |
| REJECT | 所有表 | 拒绝数据包,返回错误响应(如 Connection refused),明确告知对端连接失败 | 拒绝访问时需明确反馈(如内部服务对外拒绝) |
DNAT --to-destination <IP:端口> | nat 表 | 修改数据包的目标 IP / 端口 | 公网端口映射到内网服务(如 80→内网 192.168.1.5:8080) |
SNAT --to-source <IP> | nat 表 | 修改数据包的源 IP / 端口 | 内网机器共享固定公网 IP 上网 |
| MASQUERADE | nat 表 | 动态 SNAT,自动适配出口网卡的公网 IP(无需手动指定) | 拨号上网、云服务器弹性 IP 等公网 IP 不固定场景 |
LOG --log-prefix <前缀> --log-level <级别> | 所有表 | 记录数据包信息到系统日志(不影响流转) | 审计访问行为、排查攻击尝试、故障定位 |
REDIRECT --to-ports <端口> | nat表 | 端口重定向 | 将请求重定向到本机其他端口(如 80 → 8080) |
四、基础操作示例
centos7以上默认使用
firewalld,但实际使用iptables还是蛮多的,比如docker就是用iptables转发,7以上需要安装yum install -y iptables-services
4.1、规则查看与管理
# 查看所有表的规则(不解析域名,显示端口号)
iptables -nL# 查看指定表(如 nat 表)规则,显示规则编号
iptables -t nat -nL --line-numbers# 清空所有表的规则(谨慎使用)
iptables -F# 删除 INPUT 链第 3 条规则
iptables -D INPUT 3# 设置 INPUT 链默认策略为拒绝(增强安全性)
iptables -P INPUT DROP# 保存规则(CentOS 7+/Ubuntu)
iptables-save > /etc/iptables/rules.v4# 恢复规则(CentOS 7+/Ubuntu)
iptables-restore < /etc/iptables/rules.v4# 保存当前 iptables 规则到系统默认配置文件
iptables-save > /etc/sysconfig/iptables# 保存 nat 表规则(若配置了端口映射等 NAT 规则)
iptables-save -t nat > /etc/sysconfig/iptables-config# 保存规则(CentOS 6)
service iptables save
4.2、基础过滤规则(filter 表)
# 允许本地回环接口
[root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0# 允许已建立的连接及相关连接(避免断开现有会话,如 SSH 连接)
[root@localhost ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED# 拒绝所有来自 192.168.1.100 的入站请求
[root@localhost ~]# iptables -A INPUT -s 192.168.1.100 -j DROP
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
DROP all -- 192.168.1.100 0.0.0.0/0 # 开放 80 端口(HTTP)和 443 端口(HTTPS)
[root@localhost ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -p tcp --dport 443 -j ACCEPT
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443# 开放 22 端口(SSH),仅允许 192.168.1.0/24 网段访问
[root@localhost ~]# iptables -A INPUT -s 192.168.1.0/24 -p tcp -j ACCEPT
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
ACCEPT tcp -- 192.168.1.0/24 0.0.0.0/0
4.3、NAT 地址转换(nat 表)
# 端口映射:公网 80 端口映射到内网 192.168.1.5:8080(Web 服务)
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.5:8080
[root@localhost ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:192.168.1.5:8080
Chain INPUT (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)# 源地址转换(SNAT):内网 192.168.1.0/24 网段通过公网 IP 203.0.113.10 上网
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 203.0.113.10
[root@localhost ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
Chain INPUT (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 192.168.1.0/24 0.0.0.0/0 to:203.0.113.10# 动态 SNAT(MASQUERADE):公网 IP 不固定时,自动使用出口网卡 IP 伪装
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens33 -j MASQUERADE
[root@localhost ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
Chain INPUT (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 192.168.1.0/24 0.0.0.0/0
4.4、转发规则(FORWARD 链)
# 启用内核 IP 转发(网关服务器必备)
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf # 永久生效# 允许内网 192.168.1.0/24 网段访问外网
[root@localhost ~]# iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
[root@localhost ~]# iptables -A FORWARD -d 192.168.1.0/24 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost ~]# iptables -nL -t filter
Chain INPUT (policy ACCEPT)Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 192.168.1.0/24 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 192.168.1.0/24 state RELATED,ESTABLISHEDChain OUTPUT (policy ACCEPT)# 禁止转发其他数据包
[root@localhost ~]# iptables -P FORWARD DROP
[root@localhost ~]# iptables -nL -t filter
Chain INPUT (policy ACCEPT)Chain FORWARD (policy DROP) <---- 注意看这里的状态
target prot opt source destination
ACCEPT all -- 192.168.1.0/24 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 192.168.1.0/24 state RELATED,ESTABLISHEDChain OUTPUT (policy ACCEPT)
五、生产环境实战示例
不需要记,需要用的时候直接ai查就行,过一下思路
5.1、Web 服务器防护
Web 服务器防护(防 CC 攻击 + 敏感路径限制)
-
需求
- 开放 80/443 端口,限制单 IP 每秒最多 10 个新连接(防 CC 攻击);
- 禁止访问
/admin、/wp-login.php等敏感路径; - 只允许合法浏览器 User-Agent 访问。
-
示例
# 允许已建立的连接 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT# 限制单 IP 每秒最多 10 个新连接,突发上限 20 个 iptables -A INPUT -p tcp --dport 80 -m limit --limit 10/s --limit-burst 20 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -m limit --limit 10/s --limit-burst 20 -j ACCEPT# 禁止访问敏感路径(string 模块匹配 URL) iptables -A INPUT -p tcp --dport 80 -m string --string "/admin" --algo bm -j DROP iptables -A INPUT -p tcp --dport 443 -m string --string "/admin" --algo bm -j DROP iptables -A INPUT -p tcp --dport 80 -m string --string "/wp-login.php" --algo bm -j DROP# 只允许浏览器 User-Agent 访问(反向匹配) iptables -A INPUT -p tcp --dport 80 -m string ! --string "Mozilla/5.0" --algo bm -j DROP iptables -A INPUT -p tcp --dport 443 -m string ! --string "Mozilla/5.0" --algo bm -j DROP# 允许本地回环接口 iptables -A INPUT -i lo -j ACCEPT# 其他入站请求默认拒绝 iptables -P INPUT DROP
5.2、数据库安全加固
-
数据库服务器安全加固(限制访问源 + 禁用 Ping)
-
需求
- MySQL(3306 端口)仅允许内网 192.168.1.0/24 网段和运维机 203.0.113.20 访问;
- SSH(22 端口)仅开放给运维机,禁止其他 IP 访问;
- 禁止外部主机 Ping 服务器(防端口扫描)。
-
示例
# 允许本地回环接口 iptables -A INPUT -i lo -j ACCEPT# 允许已建立的连接 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT# SSH 仅允许运维机访问 iptables -A INPUT -s 203.0.113.20 -p tcp --dport 22 -j ACCEPT# MySQL 仅允许内网和运维机访问 iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 3306 -j ACCEPT iptables -A INPUT -s 203.0.113.20 -p tcp --dport 3306 -j ACCEPT# 禁止所有 ICMP 请求(防 Ping) iptables -A INPUT -p icmp -j DROP# 其他入站请求默认拒绝 iptables -P INPUT DROP
-
5.3、防端口扫描
-
防端口扫描(限制异常连接)
-
需求
- 禁止短时间内对多个端口发起连接(防 nmap 等扫描工具);
- 限制单 IP 每分钟最多 5 个新连接请求。
-
示例
# 允许已建立的连接 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT# 限制单 IP 60 秒内最多 5 个新连接(防扫描) iptables -A INPUT -m recent --name port_scan --rcheck --seconds 60 --hitcount 5 -j DROP iptables -A INPUT -m recent --name port_scan --set -j ACCEPT# 开放必要端口(SSH、HTTP、HTTPS) iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT# 其他入站请求默认拒绝 iptables -P INPUT DROP
-
5.4、日志审计
-
日志审计(记录关键行为)
日志默认存储路径:CentOS 为
/var/log/messages,Ubuntu 为/var/log/kern.log。-
需求
- 记录所有 SSH 访问请求(便于审计运维操作);
- 记录所有被拒绝的入站请求(便于分析攻击行为)。
-
示例
# 记录 SSH 访问日志(前缀 SSH_ACCESS,日志级别 4) iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH_ACCESS:" --log-level 4# 记录被拒绝的入站请求 iptables -A INPUT -j LOG --log-prefix "REJECTED_INPUT:" --log-level 4 iptables -A INPUT -j DROP# 记录被拒绝的转发请求 iptables -A FORWARD -j LOG --log-prefix "REJECTED_FORWARD:" --log-level 4 iptables -A FORWARD -j DROP
-
六、生产环境注意事项
- 规则顺序:先允许已建立的连接(
ESTABLISHED,RELATED),再配置具体限制规则,最后设置默认拒绝,避免误封正常连接;iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT - 测试验证:新规则配置后,先通过
iptables -nL检查规则正确性,再测试业务连通性(如 SSH、Web 访问),确认无问题后保存; - 规则保存:临时规则重启后失效,需通过
iptables-save命令保存到配置文件,确保服务器重启后规则生效; - 避免过度限制:仅开放业务必需的端口,禁止不必要的端口访问,同时避免规则过于复杂(可能影响数据包转发性能);
- 避免误封 SSH:配置规则时,先确保 SSH 端口(22)已开放,尤其是远程操作服务器时,防止被锁定。
