强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 03 章:基本语法与操作

第 03 章:基本语法与操作

本章目标:掌握 iptables 命令行的所有基本操作,能够独立完成规则的添加、删除、插入、查看和管理。


3.1 命令格式总览

3.1.1 通用语法

iptables [-t 表名] 命令 [链名] [匹配条件...] [-j 目标动作]
组成部分说明默认值
-t 表名指定操作的表filter
命令执行的操作(-A、-I、-D 等)必填
链名操作的目标链必填
匹配条件数据包匹配规则可选
-j 目标动作匹配后执行的动作可选

3.1.2 命令速查表

命令长选项说明
-A--append追加规则到链末尾
-I--insert插入规则到指定位置(默认第 1 位)
-D--delete删除指定规则
-R--replace替换指定位置的规则
-L--list列出链中的规则
-F--flush清空链中的所有规则
-Z--zero将规则的计数器清零
-N--new-chain创建自定义链
-X--delete-chain删除自定义链
-P--policy设置链的默认策略
-E--rename-chain重命名自定义链

3.2 查看规则(-L)

3.2.1 基本查看

# 查看 filter 表所有链的规则
sudo iptables -L

# 查看指定链的规则
sudo iptables -L INPUT

# 查看 nat 表的规则
sudo iptables -t nat -L

3.2.2 常用选项组合

# -n:以数字形式显示地址和端口(不做 DNS 反解,速度更快)
sudo iptables -L -n

# -v:显示详细信息(包计数、字节计数、接口信息)
sudo iptables -L -n -v

# --line-numbers:显示规则编号(便于删除和插入操作)
sudo iptables -L -n -v --line-numbers

# -x:显示精确的字节数(不使用 K/M/G 等缩写)
sudo iptables -L -n -v -x

3.2.3 输出解读

$ sudo iptables -L INPUT -n -v --line-numbers

Chain INPUT (policy ACCEPT 1042 packets, 89536 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      156 12096 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 /* SSH */
2       89  7120 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
3       23  1840 DROP       all  --  *      *       10.0.0.0/8           0.0.0.0/0
字段含义
num规则编号(需 --line-numbers
pkts该规则已匹配的数据包数量
bytes该规则已匹配的字节数
target匹配后执行的动作
prot协议(tcp/udp/icmp/all)
opt选项(通常为 --
in入接口(* 表示任意)
out出接口
source源地址
destination目的地址

技巧pktsbytes 是排查规则是否命中的重要依据。如果某条规则的 pkts 为 0,说明它从未匹配过任何数据包。


3.3 添加规则(-A / -I)

3.3.1 追加规则(-A)

-A 将规则添加到链的末尾

# 在 INPUT 链末尾追加一条允许 HTTP 的规则
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 在 OUTPUT 链末尾追加一条允许 DNS 的规则
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

3.3.2 插入规则(-I)

-I 将规则插入到链的指定位置,默认是第 1 位:

# 插入到 INPUT 链的第 1 位(最前面)
sudo iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 插入到 INPUT 链的第 3 位
sudo iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT

3.3.3 常用匹配条件

# 按源 IP
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# 按网段
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# 按目的端口
sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

# 按入接口
sudo iptables -A INPUT -i eth0 -j ACCEPT

# 按出接口
sudo iptables -A OUTPUT -o eth0 -j ACCEPT

# 组合条件
sudo iptables -A INPUT -i eth0 -p tcp -s 10.0.0.0/8 --dport 8080 -j ACCEPT

3.3.4 添加注释

# 使用 comment 模块为规则添加注释
sudo iptables -A INPUT -p tcp --dport 22 \
  -m comment --comment "Allow SSH from management network" \
  -j ACCEPT

# 查看时会显示注释
sudo iptables -L INPUT -n | grep ssh
# ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22 /* Allow SSH from management network */

最佳实践:为每条规则添加注释,标注规则的用途、创建日期和负责人,便于后续维护。


3.4 删除规则(-D)

3.4.1 按规则内容删除

# 删除一条规则(必须完全匹配)
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT

3.4.2 按规则编号删除

# 先查看规则编号
sudo iptables -L INPUT -n --line-numbers

# 输出:
# Chain INPUT (policy ACCEPT)
# num  target   prot opt source     destination
# 1    ACCEPT   tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22
# 2    ACCEPT   tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80
# 3    DROP     all  --  10.0.0.0/8 0.0.0.0/0

# 删除第 2 条规则
sudo iptables -D INPUT 2

注意:删除一条规则后,后面的规则编号会自动前移。如果要删除多条规则,建议从后往前删,避免编号变化导致误删。

# 从后往前删除(安全做法)
sudo iptables -D INPUT 3
sudo iptables -D INPUT 2
sudo iptables -D INPUT 1

3.5 插入与替换(-I / -R)

3.5.1 在指定位置插入

# 查看当前规则
sudo iptables -L INPUT -n --line-numbers
# 1  ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22
# 2  ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80
# 3  DROP    all  --  0.0.0.0/0  0.0.0.0/0

# 在第 2 位插入一条新规则(原来的第 2 条变成第 3 条)
sudo iptables -I INPUT 2 -p tcp --dport 443 -j ACCEPT

# 插入后的结果:
# 1  ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22
# 2  ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:443  ← 新插入
# 3  ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80
# 4  DROP    all  --  0.0.0.0/0  0.0.0.0/0

3.5.2 替换规则(-R)

# 替换第 2 条规则
sudo iptables -R INPUT 2 -p tcp --dport 8443 -j ACCEPT

3.6 清空规则(-F / -Z)

3.6.1 清空指定链

# 清空 INPUT 链的所有规则
sudo iptables -F INPUT

# 清空 OUTPUT 链的所有规则
sudo iptables -F OUTPUT

3.6.2 清空所有表

# 清空 filter 表所有链
sudo iptables -F

# 清空 nat 表所有链
sudo iptables -t nat -F

# 清空 mangle 表所有链
sudo iptables -t mangle -F

# 清空 raw 表所有链
sudo iptables -t raw -F

3.6.3 清零计数器(-Z)

# 清零所有链的计数器
sudo iptables -Z

# 清零指定链的计数器
sudo iptables -Z INPUT

# 清零指定链的指定规则的计数器
sudo iptables -Z INPUT 2

3.7 默认策略(-P)

3.7.1 设置默认策略

# 设置 INPUT 链默认策略为 DROP
sudo iptables -P INPUT DROP

# 设置 FORWARD 链默认策略为 DROP
sudo iptables -P FORWARD DROP

# 设置 OUTPUT 链默认策略为 ACCEPT
sudo iptables -P OUTPUT ACCEPT

限制:默认策略只能设置为 ACCEPTDROP,不能设置为 REJECT 或其他动作。

3.7.2 业务场景:Web 服务器加固

# 第一步:允许已建立的连接(避免中断现有 SSH 会话)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 第二步:允许回环接口
sudo iptables -A INPUT -i lo -j ACCEPT

# 第三步:允许 SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 第四步:允许 HTTP/HTTPS
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# 第五步:允许 ICMP(ping)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 第六步:设置默认拒绝策略
sudo iptables -P INPUT DROP

3.8 自定义链管理

3.8.1 创建自定义链

# 创建名为 HTTP_RULES 的自定义链
sudo iptables -N HTTP_RULES

# 在自定义链中添加规则
sudo iptables -A HTTP_RULES -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A HTTP_RULES -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A HTTP_RULES -j LOG --log-prefix "HTTP-DENIED: "
sudo iptables -A HTTP_RULES -j DROP

# 在主链中引用自定义链
sudo iptables -A INPUT -p tcp --dport 80 -j HTTP_RULES

3.8.2 删除自定义链

# 先清空自定义链中的规则
sudo iptables -F HTTP_RULES

# 再删除自定义链
sudo iptables -X HTTP_RULES

注意:删除自定义链前必须先清空其中的规则,并且不能有其他链引用该自定义链。

3.8.3 重命名自定义链

# 将 HTTP_RULES 重命名为 WEB_FILTER
sudo iptables -E HTTP_RULES WEB_FILTER

3.9 规则导出与导入

3.9.1 导出规则

# 以 iptables-save 格式导出所有规则
sudo iptables-save

# 只导出 filter 表
sudo iptables-save -t filter

# 只导出 nat 表
sudo iptables-save -t nat

# 保存到文件
sudo iptables-save > /tmp/iptables-rules-backup.rules

3.9.2 导入规则

# 从文件恢复规则
sudo iptables-restore < /tmp/iptables-rules-backup.rules

# 原子性恢复(使用 --noflush 保留现有规则)
sudo iptables-restore --noflush < /tmp/new-rules.rules

3.9.3 iptables-save 输出格式解读

$ sudo iptables-save
# Generated by iptables-save v1.8.7
*filter                              # ← 表名
:INPUT ACCEPT [0:0]                  # ← 链的默认策略和计数器
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j DROP
COMMIT                               # ← 提交该表
*nat                                 # ← nat 表
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

3.10 实战:完整的服务器防火墙脚本

#!/bin/bash
# ==================================================
# 基础防火墙脚本 - 适用于 Web 服务器
# ==================================================

# 定义变量
IPT="/usr/sbin/iptables"
SSH_PORT="22"
HTTP_PORTS="80,443"

# 清空所有现有规则
$IPT -F
$IPT -t nat -F
$IPT -t mangle -F
$IPT -t raw -F

# 删除自定义链
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
$IPT -t raw -X

# 设置默认策略:全部 DROP
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT

# ─────────────── INPUT 链规则 ───────────────

# 1. 允许已建立的连接
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED \
  -m comment --comment "Allow established connections" -j ACCEPT

# 2. 允许回环接口
$IPT -A INPUT -i lo \
  -m comment --comment "Allow loopback" -j ACCEPT

# 3. 允许 SSH(限管理网段)
$IPT -A INPUT -p tcp --dport $SSH_PORT -s 192.168.1.0/24 \
  -m comment --comment "Allow SSH from management network" -j ACCEPT

# 4. 允许 HTTP/HTTPS
$IPT -A INPUT -p tcp -m multiport --dports $HTTP_PORTS \
  -m comment --comment "Allow HTTP/HTTPS" -j ACCEPT

# 5. 允许 ICMP
$IPT -A INPUT -p icmp --icmp-type echo-request \
  -m comment --comment "Allow ping" -j ACCEPT

# 6. 记录并丢弃其他所有数据包
$IPT -A INPUT \
  -m comment --comment "Log and drop everything else" \
  -j LOG --log-prefix "IPT-INPUT-DROP: " --log-level 4
$IPT -A INPUT -j DROP

echo "Firewall rules applied successfully."

3.11 常用操作速查

操作命令
查看所有规则iptables -L -n -v --line-numbers
查看 nat 表iptables -t nat -L -n -v
添加允许规则iptables -A INPUT -p tcp --dport <端口> -j ACCEPT
删除规则(按编号)iptables -D INPUT <编号>
插入规则到首位iptables -I INPUT <规则>
清空所有规则iptables -F && iptables -t nat -F
设置默认拒绝iptables -P INPUT DROP
导出规则iptables-save > rules.bak
导入规则iptables-restore < rules.bak

3.12 注意事项

⚠️ 不要在远程会话中直接执行 iptables -F:清空规则后,如果默认策略是 DROP,你会立即断开连接。

⚠️ 使用脚本时加入断路器:在自动化脚本中加入超时机制,如果脚本执行失败,自动恢复旧规则。

# 安全的规则应用方式
RULES_FILE="/tmp/new-rules.rules"
BACKUP_FILE="/tmp/backup-rules.rules"

# 备份当前规则
iptables-save > $BACKUP_FILE

# 应用新规则
iptables-restore < $RULES_FILE

# 设置 30 秒超时,如果管理员没有确认则自动回滚
echo "New rules applied. Press Enter within 30s to confirm, or they will be rolled back."
if ! read -t 30; then
    iptables-restore < $BACKUP_FILE
    echo "Rules rolled back due to timeout."
fi

3.13 扩展阅读

资源说明
man iptables官方手册
man iptables-save规则导出手册
man iptables-restore规则导入手册
iptables --help快速查看所有命令选项

本章小结

操作命令说明
追加规则-A添加到链末尾
插入规则-I [num]插入到指定位置
删除规则-D [num]按内容或编号删除
查看规则-L -n -v数字形式、详细信息
清空规则-F清空指定表的所有规则
默认策略-P设置链的默认动作
自定义链-N / -X创建/删除自定义链
导出/导入iptables-save/restore规则的备份与恢复

下一章第 04 章:filter 表详解,将深入讲解最常用的 filter 表的三大链。