5.1 规则语法基础

基本语法结构

iptables [-t table] command [chain] [parameters] [target/jump]

语法组成部分

  1. 表选择-t table(可选,默认为 filter)
  2. 命令:操作类型(增加、删除、列出等)
  3. 链名:目标链(INPUT、OUTPUT、FORWARD 等)
  4. 匹配参数:数据包匹配条件
  5. 目标动作:匹配后的处理方式

常用命令详解

规则管理命令

# 添加规则
iptables -A INPUT -p tcp --dport 80 -j ACCEPT    # 追加到链末尾
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT  # 插入到指定位置

# 删除规则
iptables -D INPUT -p tcp --dport 80 -j ACCEPT    # 按规则内容删除
iptables -D INPUT 1                              # 按行号删除

# 替换规则
iptables -R INPUT 1 -p tcp --dport 8080 -j ACCEPT

# 清空规则
iptables -F INPUT                                # 清空指定链
iptables -F                                      # 清空所有链

查看命令

# 基本查看
iptables -L                                      # 列出所有规则
iptables -L INPUT                                # 列出指定链
iptables -L -n                                   # 不解析域名和端口名
iptables -L -v                                   # 显示详细信息
iptables -L --line-numbers                       # 显示行号

# 组合参数
iptables -L INPUT -n -v --line-numbers           # 常用组合

# 查看特定表
iptables -t nat -L -n -v
iptables -t mangle -L -n -v

策略管理命令

# 设置默认策略
iptables -P INPUT ACCEPT                         # 设置 INPUT 链默认策略为接受
iptables -P INPUT DROP                           # 设置 INPUT 链默认策略为丢弃
iptables -P FORWARD DROP                         # 设置 FORWARD 链默认策略为丢弃

# 查看当前策略
iptables -L | grep "Chain"

5.2 匹配条件详解

基本匹配条件

协议匹配

# TCP 协议
iptables -A INPUT -p tcp -j ACCEPT

# UDP 协议
iptables -A INPUT -p udp -j ACCEPT

# ICMP 协议
iptables -A INPUT -p icmp -j ACCEPT

# 所有协议
iptables -A INPUT -p all -j ACCEPT
iptables -A INPUT -j ACCEPT                      # 省略 -p all

# 协议号
iptables -A INPUT -p 6 -j ACCEPT                 # TCP (协议号 6)
iptables -A INPUT -p 17 -j ACCEPT                # UDP (协议号 17)

源地址和目标地址匹配

# 源地址匹配
iptables -A INPUT -s 192.168.1.100 -j ACCEPT              # 单个 IP
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT             # 网段
iptables -A INPUT -s 192.168.1.1,192.168.1.2 -j ACCEPT   # 多个 IP(某些版本支持)

# 目标地址匹配
iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT                   # 单个 IP
iptables -A OUTPUT -d 8.8.8.0/24 -j ACCEPT                # 网段

# 排除地址(取反)
iptables -A INPUT ! -s 192.168.1.0/24 -j DROP             # 非内网地址
iptables -A OUTPUT ! -d 192.168.1.0/24 -j ACCEPT          # 非内网目标

网络接口匹配

# 输入接口
iptables -A INPUT -i eth0 -j ACCEPT                       # 指定接口
iptables -A INPUT -i eth+ -j ACCEPT                       # 接口通配符
iptables -A INPUT -i lo -j ACCEPT                         # 本地回环

# 输出接口
iptables -A OUTPUT -o eth0 -j ACCEPT                      # 指定接口
iptables -A FORWARD -o ppp+ -j ACCEPT                     # PPP 接口通配符

# 接口取反
iptables -A INPUT ! -i lo -j DROP                         # 非本地回环接口

端口匹配

# 源端口
iptables -A INPUT -p tcp --sport 80 -j ACCEPT             # 单个端口
iptables -A INPUT -p tcp --sport 1024:65535 -j ACCEPT     # 端口范围
iptables -A INPUT -p tcp --sport :1023 -j DROP            # 小于等于 1023
iptables -A INPUT -p tcp --sport 1024: -j ACCEPT          # 大于等于 1024

# 目标端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT             # SSH
iptables -A INPUT -p tcp --dport 80 -j ACCEPT             # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT            # HTTPS
iptables -A INPUT -p tcp --dport 8000:8999 -j ACCEPT      # 端口范围

# 端口取反
iptables -A INPUT -p tcp ! --dport 22 -j DROP             # 非 SSH 端口

扩展匹配条件

multiport 模块(多端口匹配)

# 多个源端口
iptables -A INPUT -p tcp -m multiport --sports 80,443,8080 -j ACCEPT

# 多个目标端口
iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT

# 源端口和目标端口
iptables -A INPUT -p tcp -m multiport --ports 80,443,8080 -j ACCEPT

# 端口范围组合
iptables -A INPUT -p tcp -m multiport --dports 80,443,8000:8999 -j ACCEPT

state 模块(连接状态匹配)

# 连接状态
iptables -A INPUT -m state --state NEW -j ACCEPT                    # 新连接
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT            # 已建立连接
iptables -A INPUT -m state --state RELATED -j ACCEPT                # 相关连接
iptables -A INPUT -m state --state INVALID -j DROP                  # 无效连接

# 组合状态
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    # 常用组合
iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT        # 新建和已建立

conntrack 模块(连接跟踪)

# 连接状态(新版本推荐使用 conntrack 替代 state)
iptables -A INPUT -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 连接方向
iptables -A INPUT -m conntrack --ctdir ORIGINAL -j ACCEPT           # 原始方向
iptables -A INPUT -m conntrack --ctdir REPLY -j ACCEPT              # 回复方向

# 连接状态和方向组合
iptables -A INPUT -m conntrack --ctstate ESTABLISHED --ctdir REPLY -j ACCEPT

limit 模块(速率限制)

# 基本限速
iptables -A INPUT -p icmp -m limit --limit 1/s -j ACCEPT            # 每秒 1 个
iptables -A INPUT -p icmp -m limit --limit 10/m -j ACCEPT           # 每分钟 10 个
iptables -A INPUT -p icmp -m limit --limit 100/h -j ACCEPT          # 每小时 100 个

# 突发限制
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 5 -j ACCEPT

# 日志限制
iptables -A INPUT -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix "[FIREWALL]: "

recent 模块(最近访问记录)

# 记录 IP 地址
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --set

# 检查最近访问
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --rcheck --seconds 60 --hitcount 3 -j DROP

# 更新记录
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --update --seconds 60 --hitcount 3 -j DROP

# 移除记录
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --remove

# 完整的防暴力破解配置
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --rcheck --seconds 300 --hitcount 5 -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

connlimit 模块(连接数限制)

# 限制每个 IP 的连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j DROP

# 限制每个网段的连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 --connlimit-mask 24 -j DROP

# 限制每个源 IP 的连接数(更严格)
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 5 --connlimit-mask 32 -j DROP

time 模块(时间限制)

# 时间段限制
iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 -j ACCEPT

# 工作日限制
iptables -A INPUT -p tcp --dport 22 -m time --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

# 日期限制
iptables -A INPUT -p tcp --dport 80 -m time --datestart 2024-01-01 --datestop 2024-12-31 -j ACCEPT

# 组合时间条件
iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

string 模块(字符串匹配)

# HTTP 请求匹配
iptables -A INPUT -p tcp --dport 80 -m string --string "GET /admin" --algo bm -j DROP

# 阻止特定 User-Agent
iptables -A INPUT -p tcp --dport 80 -m string --string "User-Agent: BadBot" --algo bm -j DROP

# 阻止 SQL 注入尝试
iptables -A INPUT -p tcp --dport 80 -m string --string "union select" --algo bm -j DROP
iptables -A INPUT -p tcp --dport 80 -m string --string "' or 1=1" --algo bm -j DROP

# 字符串匹配算法
iptables -A INPUT -p tcp --dport 80 -m string --string "malware" --algo kmp -j DROP  # KMP 算法
iptables -A INPUT -p tcp --dport 80 -m string --string "virus" --algo bm -j DROP     # Boyer-Moore 算法

owner 模块(进程所有者匹配)

# 用户 ID 匹配
iptables -A OUTPUT -m owner --uid-owner 1000 -j ACCEPT              # 特定用户
iptables -A OUTPUT -m owner --uid-owner 0 -p tcp --dport 25 -j DROP # 禁止 root 发送邮件

# 组 ID 匹配
iptables -A OUTPUT -m owner --gid-owner 100 -j ACCEPT

# 进程 ID 匹配
iptables -A OUTPUT -m owner --pid-owner 1234 -j ACCEPT

# 进程名匹配
iptables -A OUTPUT -m owner --cmd-owner firefox -p tcp --dport 80 -j ACCEPT

# 组合条件
iptables -A OUTPUT -m owner --uid-owner 1000 --cmd-owner chrome -j ACCEPT

5.3 目标动作详解

终止动作

ACCEPT(接受)

# 基本接受
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 条件接受
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

DROP(丢弃)

# 静默丢弃
iptables -A INPUT -s 192.168.1.100 -j DROP

# 丢弃无效连接
iptables -A INPUT -m state --state INVALID -j DROP

# 丢弃特定端口
iptables -A INPUT -p tcp --dport 23 -j DROP                # Telnet

REJECT(拒绝)

# 基本拒绝(发送 ICMP 错误消息)
iptables -A INPUT -p tcp --dport 23 -j REJECT

# 指定拒绝类型
iptables -A INPUT -p tcp --dport 135 -j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p tcp --dport 139 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp --dport 137 -j REJECT --reject-with icmp-port-unreachable

# 常用拒绝类型
# icmp-net-unreachable        # 网络不可达
# icmp-host-unreachable       # 主机不可达
# icmp-port-unreachable       # 端口不可达(默认)
# icmp-proto-unreachable      # 协议不可达
# icmp-net-prohibited         # 网络被禁止
# icmp-host-prohibited        # 主机被禁止
# tcp-reset                   # TCP 重置

非终止动作

LOG(日志记录)

# 基本日志
iptables -A INPUT -p tcp --dport 23 -j LOG

# 自定义日志前缀
iptables -A INPUT -p tcp --dport 23 -j LOG --log-prefix "[TELNET-ATTEMPT]: "

# 设置日志级别
iptables -A INPUT -p tcp --dport 23 -j LOG --log-level 4  # warning

# 完整日志配置
iptables -A INPUT -p tcp --dport 23 -j LOG --log-prefix "[FIREWALL-TELNET]: " --log-level 4
iptables -A INPUT -p tcp --dport 23 -j DROP

# 限制日志频率
iptables -A INPUT -p tcp --dport 23 -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix "[TELNET]: "
iptables -A INPUT -p tcp --dport 23 -j DROP

ULOG(用户空间日志)

# 发送到用户空间日志程序
iptables -A INPUT -p tcp --dport 23 -j ULOG --ulog-nlgroup 1
iptables -A INPUT -p tcp --dport 23 -j ULOG --ulog-prefix "TELNET" --ulog-cprange 64

MARK(数据包标记)

# 标记数据包
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -s 192.168.2.0/24 -j MARK --set-mark 2

# 基于端口标记
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 10
iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 11

# 标记位操作
iptables -t mangle -A PREROUTING -j MARK --set-xmark 0x1/0x1    # 设置标记位
iptables -t mangle -A PREROUTING -j MARK --and-mark 0xfffffffe  # 清除标记位
iptables -t mangle -A PREROUTING -j MARK --or-mark 0x1          # 设置标记位

NAT 动作

SNAT(源地址转换)

# 基本 SNAT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.1

# 多个源地址
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.1-203.0.113.10

# 指定端口范围
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -p tcp -o eth0 -j SNAT --to-source 203.0.113.1:1024-65535

DNAT(目标地址转换)

# 基本 DNAT
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10

# 端口映射
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80

# 多个目标(负载均衡)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10-192.168.1.12

# 指定端口范围
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:8080-8090

MASQUERADE(地址伪装)

# 动态 IP 的 NAT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE

# 指定端口范围
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -p tcp -o ppp0 -j MASQUERADE --to-ports 1024-65535

REDIRECT(重定向)

# 端口重定向
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

# 透明代理
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3128

# 指定端口范围
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080-8090

5.4 规则编写最佳实践

规则顺序原则

#!/bin/bash
# 正确的规则顺序示例

# 1. 清空现有规则
iptables -F
iptables -t nat -F
iptables -t mangle -F

# 2. 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 3. 允许本地回环(最高优先级)
iptables -A INPUT -i lo -j ACCEPT

# 4. 允许已建立的连接(第二优先级)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 5. 特殊规则(如防攻击规则)
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# 6. 具体服务规则(按重要性和使用频率排序)
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT  # SSH(管理)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT                    # HTTP(常用)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT                   # HTTPS(常用)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT                    # SMTP(较少)

# 7. 日志和拒绝规则(最后)
iptables -A INPUT -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix "[FIREWALL-DENIED]: "
iptables -A INPUT -j DROP

性能优化原则

1. 最常用规则放在前面

# 错误示例(低频规则在前)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT    # SMTP(使用较少)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT    # HTTP(使用频繁)

# 正确示例(高频规则在前)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT    # HTTP(使用频繁)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT    # SMTP(使用较少)

2. 使用具体匹配条件

# 错误示例(模糊匹配)
iptables -A INPUT -j ACCEPT

# 正确示例(具体匹配)
iptables -A INPUT -p tcp --dport 80 -s 192.168.1.0/24 -j ACCEPT

3. 合并相似规则

# 错误示例(分散规则)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

# 正确示例(合并规则)
iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT

安全性原则

1. 默认拒绝策略

# 设置严格的默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT  # 或者也设置为 DROP,然后明确允许需要的出站流量

2. 最小权限原则

# 错误示例(权限过大)
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# 正确示例(最小权限)
iptables -A INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT

3. 防攻击规则

# 防止常见攻击
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP           # NULL 扫描
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP            # XMAS 扫描
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP    # XMAS 扫描变种
iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

# 防止 SYN 洪水攻击
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# 防止端口扫描
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A INPUT -m recent --name portscan --set -j LOG --log-prefix "[PORT-SCAN]: "
iptables -A INPUT -m recent --name portscan --set -j DROP

可维护性原则

1. 使用注释和文档

#!/bin/bash
# Web 服务器防火墙配置
# 作者:管理员
# 日期:2024-01-01
# 版本:1.0

# === 基础配置 ===
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# === 本地回环 ===
iptables -A INPUT -i lo -j ACCEPT

# === 已建立连接 ===
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# === Web 服务 ===
iptables -A INPUT -p tcp --dport 80 -j ACCEPT   # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT  # HTTPS

# === 管理访问 ===
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT  # SSH 仅内网

# === 拒绝其他 ===
iptables -A INPUT -j DROP

2. 模块化配置

#!/bin/bash
# 主配置文件

source /etc/iptables/basic-rules.sh
source /etc/iptables/web-rules.sh
source /etc/iptables/ssh-rules.sh
source /etc/iptables/logging-rules.sh
#!/bin/bash
# /etc/iptables/basic-rules.sh
# 基础规则

iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#!/bin/bash
# /etc/iptables/web-rules.sh
# Web 服务规则

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

3. 配置验证

#!/bin/bash
# 配置验证脚本

# 应用新规则前备份当前规则
iptables-save > /tmp/iptables-backup-$(date +%Y%m%d-%H%M%S)

# 应用新规则
source /etc/iptables/firewall.sh

# 验证关键服务可访问性
echo "验证 SSH 连接..."
if nc -z localhost 22; then
    echo "SSH 可访问"
else
    echo "警告:SSH 不可访问!"
fi

echo "验证 HTTP 连接..."
if nc -z localhost 80; then
    echo "HTTP 可访问"
else
    echo "警告:HTTP 不可访问!"
fi

# 显示当前规则
echo "当前规则:"
iptables -L -n -v

5.5 常见规则模板

Web 服务器规则模板

#!/bin/bash
# Web 服务器防火墙配置模板

# 清空现有规则
iptables -F
iptables -t nat -F
iptables -t mangle -F

# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 防攻击规则
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Web 服务
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# SSH 管理(限制源地址)
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT

# 防暴力破解
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22 -m recent --name SSH --rcheck --seconds 300 --hitcount 5 -j DROP

# 限制连接数
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j DROP
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 -j DROP

# 防 DDoS
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# ICMP 限制
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

# 日志记录
iptables -A INPUT -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix "[WEB-FIREWALL]: "

# 默认拒绝
iptables -A INPUT -j DROP

数据库服务器规则模板

#!/bin/bash
# 数据库服务器防火墙配置模板

# 清空现有规则
iptables -F

# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 基础规则
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP

# SSH 管理
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT

# 数据库访问(仅允许应用服务器)
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.10 -j ACCEPT  # MySQL from App Server 1
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.11 -j ACCEPT  # MySQL from App Server 2

# 数据库复制(如果需要)
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.20 -j ACCEPT  # MySQL from Slave

# 监控访问
iptables -A INPUT -p tcp --dport 9100 -s 192.168.1.100 -j ACCEPT # Node Exporter

# 严格的连接限制
iptables -A INPUT -p tcp --dport 3306 -m connlimit --connlimit-above 20 -j DROP

# 防暴力破解
iptables -A INPUT -p tcp --dport 3306 -m recent --name MYSQL --set
iptables -A INPUT -p tcp --dport 3306 -m recent --name MYSQL --rcheck --seconds 600 --hitcount 10 -j DROP

# 日志记录
iptables -A INPUT -p tcp --dport 3306 -j LOG --log-prefix "[DB-ACCESS]: "
iptables -A INPUT -m limit --limit 3/m --limit-burst 5 -j LOG --log-prefix "[DB-DENIED]: "

# 默认拒绝
iptables -A INPUT -j DROP

NAT 网关规则模板

#!/bin/bash
# NAT 网关防火墙配置模板

# 清空现有规则
iptables -F
iptables -t nat -F
iptables -t mangle -F

# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf

# INPUT 链规则
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT  # DNS
iptables -A INPUT -p udp --dport 67 -j ACCEPT  # DHCP

# FORWARD 链规则
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT

# 内容过滤
iptables -A FORWARD -p tcp --dport 25 -j DROP   # 阻止 SMTP
iptables -A FORWARD -p tcp --dport 6881:6999 -j DROP  # 阻止 P2P

# QoS 标记
iptables -t mangle -A FORWARD -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -p tcp --dport 443 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -p tcp --dport 22 -j MARK --set-mark 2

# NAT 规则
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# 端口转发
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 192.168.1.10:443

# 日志记录
iptables -A FORWARD -m limit --limit 10/m --limit-burst 20 -j LOG --log-prefix "[NAT-FORWARD]: "
iptables -A INPUT -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix "[NAT-INPUT]: "

# 默认拒绝
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP

5.6 规则测试和调试

规则测试方法

1. 逐步测试

#!/bin/bash
# 逐步测试脚本

# 保存当前规则
iptables-save > /tmp/iptables-current

# 清空规则进行测试
iptables -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

echo "测试基础连通性..."
ping -c 3 8.8.8.8

# 逐步添加规则
echo "添加基础规则..."
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

echo "测试 SSH 连接..."
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
nc -z localhost 22 && echo "SSH OK" || echo "SSH Failed"

echo "测试 HTTP 连接..."
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
nc -z localhost 80 && echo "HTTP OK" || echo "HTTP Failed"

# 设置默认策略
echo "设置默认拒绝策略..."
iptables -P INPUT DROP

echo "最终测试..."
nc -z localhost 22 && echo "SSH Still OK" || echo "SSH Blocked"
nc -z localhost 80 && echo "HTTP Still OK" || echo "HTTP Blocked"

2. 连接测试工具

# 端口连通性测试
nc -z target_host port                    # 测试 TCP 端口
nc -u -z target_host port                 # 测试 UDP 端口

# 批量端口测试
for port in 22 80 443 3306; do
    nc -z localhost $port && echo "Port $port: Open" || echo "Port $port: Closed"
done

# HTTP 服务测试
curl -I http://localhost/
wget --spider http://localhost/

# SSH 连接测试
ssh -o ConnectTimeout=5 user@localhost 'echo "SSH OK"'

3. 流量模拟测试

# 使用 hping3 进行流量测试

# SYN 洪水测试
hping3 -S -p 80 --flood target_host

# 连接数测试
for i in {1..100}; do
    nc target_host 80 &
done

# 速率限制测试
for i in {1..10}; do
    ping -c 1 target_host
    sleep 0.1
done

调试技巧

1. 规则匹配统计

# 查看规则匹配次数
iptables -L -n -v

# 重置计数器
iptables -Z

# 监控规则匹配
watch -n 1 'iptables -L -n -v | head -20'

2. 日志分析

# 实时查看防火墙日志
tail -f /var/log/messages | grep "\[FIREWALL\]"

# 分析日志统计
grep "\[FIREWALL\]" /var/log/messages | awk '{print $9}' | sort | uniq -c | sort -nr

# 提取被阻止的 IP
grep "\[FIREWALL\]" /var/log/messages | grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr

3. 连接跟踪调试

# 查看连接跟踪表
cat /proc/net/nf_conntrack

# 查看连接跟踪统计
cat /proc/net/stat/nf_conntrack

# 监控连接跟踪
watch -n 1 'cat /proc/net/nf_conntrack | wc -l'

本章小结

本章详细介绍了 iptables 基础规则的编写:

  1. 语法基础:命令结构、参数使用、常用选项
  2. 匹配条件:基本匹配和扩展匹配的详细用法
  3. 目标动作:各种动作的使用场景和配置方法
  4. 最佳实践:规则顺序、性能优化、安全性原则
  5. 规则模板:常见场景的完整配置示例
  6. 测试调试:规则验证和问题排查方法

本章练习

  1. 基础练习

    • 编写一个基本的 Web 服务器防火墙规则
    • 实现基于时间的访问控制
    • 配置防暴力破解规则
  2. 进阶练习

    • 编写一个完整的企业网关规则
    • 实现基于用户的访问控制
    • 配置 QoS 流量标记
  3. 实战练习

    • 为现有服务器设计防火墙策略
    • 实现多层安全防护
    • 编写规则测试和验证脚本
  4. 调试练习

    • 分析防火墙日志
    • 排查连接问题
    • 优化规则性能

下一章我们将学习高级匹配条件的使用方法。