Iptables 防火墙教程
概述
iptables 是 Linux 系统中一个极其强大的用户空间防火墙工具,它基于内核的 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-save 和 iptables-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方法三:使用 firewalld 或 systemd 服务 (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:
nftables是iptables的现代化继任者,旨在提供更简洁的语法、更好的性能和原子性的规则更新。新版本的 Linux 发行版(如 Debian 10+, RHEL 8+)已默认使用nftables。学习iptables仍然非常有价值,因为它在存量系统中广泛使用,但对于新系统,建议开始关注nftables。 - 安全第一:在远程服务器上修改防火墙规则时,务必小心。最好先写好一个完整的脚本,一次性执行,或者使用
at命令在几分钟后执行一个恢复连接的脚本,以防把自己锁在外面。