概述

iptablesLinux 系统中一个极其强大的用户空间防火墙工具,它基于内核的 Netfilter 框架工作。通过 iptables,你可以创建规则来过滤、修改、转发网络数据包,从而实现网络安全防护、网络地址转换(NAT)等高级功能。

常用命令语法

iptables 命令的基本格式如下:

iptables [-t table] command [chain] [rules] [-j target]
  • -t table:指定要操作的表,如果省略,默认为 filter 表。
  • command:主要的操作命令。
  • chain:指定要操作的链。
  • rules:具体的规则匹配条件。
  • -j target:指定匹配成功后的目标动作。

常用 command 选项:

  • -L, --list:查看指定表和链的规则。

    • -n:以数字形式显示 IP 地址和端口,不进行 DNS 反向解析。
    • -v:显示更详细的信息,包括数据包和字节计数器。
    • --line-numbers:显示规则的行号。
  • -A, --append:在链的末尾追加一条新规则。
  • -I, --insert:在链的开头插入一条新规则(可以指定行号)。
  • -D, --delete:删除一条规则(可以指定规则内容或行号)。
  • -P, --policy:设置链的默认策略(当没有规则匹配时执行的动作)。
  • -F, --flush:清空指定链中的所有规则。
  • -Z, --zero:将数据包和字节计数器清零。

设置方法

查看、清空和设置默认策略

# 查看 filter 表的所有规则(最常用)
# -n: 不解析域名,速度快
# -v: 显示详细信息
# --line-numbers: 显示行号,方便删除
sudo iptables -t filter -L -n -v --line-numbers

# 清空所有表的所有规则 (危险操作,会清除所有现有防火墙规则)
sudo iptables -F          # 清空 filter 表所有链的规则
sudo iptables -t nat -F   # 清空 nat 表所有链的规则
sudo iptables -t mangle -F # 清空 mangle 表所有链的规则
sudo iptables -X          # 删除所有用户自定义的链

# 设置默认策略为“拒绝所有” (安全的基石)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT # 允许本机主动发出的所有流量,如果想更严格可以设为 DROP

警告:执行 iptables -P INPUT DROP 后,如果没有设置任何 ACCEPT 规则,你可能会立即失去对服务器的 SSH 连接。请务必在同一终端会话中继续添加允许 SSH 的规则。

开放必要端口

# 1. 允许回环接口 (loopback) 的所有通信,本机服务间通信需要
sudo iptables -A INPUT -i lo -j ACCEPT

# 2. 允许已建立的、相关的连接通过
# 这是非常重要的一条规则,它允许服务器对收到的请求进行响应
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 3. 允许 SSH (端口 22) 的新连接
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 4. 允许 HTTP (端口 80) 的新连接
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 5. 允许 HTTPS (端口 443) 的新连接
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 6. (可选) 允许 ping (ICMP echo-request)
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

# 7. 此时,默认策略 DROP 会阻止所有其他未经允许的入站流量

端口转发 (DNAT)

场景:将服务器公网 IP (<Public_IP>) 的 8080 端口收到的流量,转发给内网服务器 192.168.1.100 的 80 端口。

# 1. 开启内核的 IP 转发功能
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# 2. 在 nat 表的 PREROUTING 链中添加 DNAT 规则

# -p tcp: 协议为 TCP
# -d <Public_IP>: 目标地址是本机公网 IP
# --dport 8080: 目标端口是 8080
# --to-destination 192.168.1.100:80: 转发到内网机器的 80 端口
sudo iptables -t nat -A PREROUTING -p tcp -d <Public_IP> --dport 8080 -j DNAT --to-destination 192.168.1.100:80

# 3. 在 filter 表的 FORWARD 链中允许这个转发流量通过
sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT

共享上网 (SNAT / MASQUERADE)

场景:让内网 192.168.1.0/24 网段的机器通过这台 Linux 服务器(网卡 eth0 连接公网)上网。

# 1. 开启内核的 IP 转发功能 (如果上面没开)
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# 2. 在 nat 表的 POSTROUTING 链中添加规则
# -s 192.168.1.0/24: 源地址来自内网网段
# -o eth0: 从公网接口 eth0 出去
# -j MASQUERADE: 动态地将源 IP 地址伪装成 eth0 的 IP 地址。如果你的公网 IP 是固定的,也可以用 SNAT
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# 使用 SNAT (如果公网 IP 是固定的 <Static_Public_IP>)
# sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source <Static_Public_IP>

# 3. 允许相关的转发流量
sudo iptables -A FORWARD -s 192.168.1.0/24 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -i eth0 -j ACCEPT

防止简单 DoS 攻击(限制连接速率)

场景:防止对 SSH 端口的暴力破解,限制来自同一 IP 的新建连接速率。

# -m limit: 使用 limit 模块
# --limit 2/min: 平均每分钟最多允许 2 个
# --limit-burst 5: 峰值允许 5 个
# 超过这个限制的包会被 DROP
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 2/min --limit-burst 5 -j ACCEPT

# 对于超过限制的新连接,直接 DROP
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP

注意:要将这条规则放在允许所有SSH连接的规则 (iptables -A INPUT -p tcp --dport 22 -j ACCEPT) 之前。iptables 规则是按顺序匹配的。

保存和恢复规则

方法一:使用 iptables-saveiptables-restore (通用方法)

# 保存当前规则到文件
sudo iptables-save > /etc/iptables/rules.v4

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

方法二:使用 iptables-persistent (Debian/Ubuntu)

# 安装工具
sudo apt-get update
sudo apt-get install iptables-persistent

# 安装过程中会提示你是否保存当前的 IPv4 和 IPv6 规则,选择 "Yes"。
# 如果之后修改了规则,需要手动保存
sudo netfilter-persistent save

方法三:使用 firewalldsystemd 服务 (RHEL/CentOS 7+)

# 安装服务
sudo yum install iptables-services

# 启动并设置开机自启
sudo systemctl start iptables
sudo systemctl enable iptables

# 当你修改了规则后,保存它们
sudo service iptables save

重要提示

  • IPv6:iptables 只处理 IPv4 流量。对于 IPv6,你需要使用 ip6tables,其语法和 iptables 几乎完全相同。
  • nftables:nftablesiptables 的现代化继任者,旨在提供更简洁的语法、更好的性能和原子性的规则更新。新版本的 Linux 发行版(如 Debian 10+, RHEL 8+)已默认使用 nftables。学习 iptables 仍然非常有价值,因为它在存量系统中广泛使用,但对于新系统,建议开始关注 nftables
  • 安全第一:在远程服务器上修改防火墙规则时,务必小心。最好先写好一个完整的脚本,一次性执行,或者使用 at 命令在几分钟后执行一个恢复连接的脚本,以防把自己锁在外面。