iptables命令

iptables命令 #

iptables是Linux系统中用于配置IPv4网络包过滤规则的命令行工具。它允许系统管理员配置内核防火墙(由Netfilter模块实现)的规则,用于过滤网络流量、网络地址转换(NAT)和数据包修改。

语法 #

iptables [选项] 命令 [] [条件] [动作]

常用选项 #

选项 描述
-t, --table 表 指定要操作的表(filter、nat、mangle、raw、security)
-A, --append 链 规则 在链的末尾添加规则
-D, --delete 链 规则 删除链中的规则
-I, --insert 链 [序号] 规则 在链中插入规则
-R, --replace 链 序号 规则 替换链中的规则
-L, --list [链] 列出链中的规则
-S, --list-rules [链] 以iptables命令格式列出规则
-F, --flush [链] 删除链中的所有规则
-Z, --zero [链 [序号]] 将链中的数据包和字节计数器归零
-N, --new-chain 链 创建新的用户自定义链
-X, --delete-chain [链] 删除用户自定义链
-P, --policy 链 目标 设置链的默认策略
-E, --rename-chain 旧链 新链 重命名用户自定义链
-h, --help 显示帮助信息
-V, --version 显示版本信息
-v, --verbose 详细输出
-n, --numeric 以数字形式显示IP地址和端口
-x, --exact 显示精确的数据包和字节计数
--line-numbers 显示规则的行号
-c, --set-counters 数据包计数 字节计数 设置规则的计数器
-m, --match 匹配扩展 指定使用的匹配扩展

表和链 #

iptables有五个表,每个表包含不同的链:

  1. filter表(默认):用于过滤数据包

    • INPUT:处理发往本机的数据包
    • OUTPUT:处理本机发出的数据包
    • FORWARD:处理通过本机转发的数据包
  2. nat表:用于网络地址转换

    • PREROUTING:在路由决策前修改数据包
    • OUTPUT:修改本机生成的数据包
    • POSTROUTING:在路由决策后修改数据包
  3. mangle表:用于特殊的数据包修改

    • PREROUTING:在路由决策前修改数据包
    • INPUT:处理发往本机的数据包
    • FORWARD:处理通过本机转发的数据包
    • OUTPUT:修改本机生成的数据包
    • POSTROUTING:在路由决策后修改数据包
  4. raw表:用于配置豁免连接跟踪

    • PREROUTING:处理到达的数据包
    • OUTPUT:处理本机生成的数据包
  5. security表:用于强制访问控制网络规则

    • INPUT:处理发往本机的数据包
    • OUTPUT:处理本机发出的数据包
    • FORWARD:处理通过本机转发的数据包

常用匹配条件 #

条件 描述
-p, --protocol 协议 匹配协议(tcp、udp、icmp等)
-s, --source 地址[/掩码] 匹配源IP地址
-d, --destination 地址[/掩码] 匹配目标IP地址
-i, --in-interface 接口 匹配输入接口
-o, --out-interface 接口 匹配输出接口
--sport, --source-port 端口[:端口] 匹配源端口
--dport, --destination-port 端口[:端口] 匹配目标端口
-m state --state 状态 匹配连接状态(NEW、ESTABLISHED、RELATED、INVALID)
-m multiport --sports 端口列表 匹配多个源端口
-m multiport --dports 端口列表 匹配多个目标端口
-m tcp --tcp-flags 掩码 比较 匹配TCP标志
-m limit --limit 速率 匹配速率限制
-m connlimit --connlimit-above 数量 匹配连接数限制
-m mac --mac-source MAC地址 匹配源MAC地址
-m iprange --src-range IP范围 匹配源IP范围
-m iprange --dst-range IP范围 匹配目标IP范围
-m time --timestart 时间 --timestop 时间 匹配时间范围
-m string --string 字符串 匹配数据包中的字符串

常用动作 #

动作 描述
-j, --jump 目标 指定匹配规则后要执行的动作
ACCEPT 接受数据包
DROP 丢弃数据包
REJECT 拒绝数据包并发送错误消息
LOG 记录数据包信息到系统日志
SNAT 源地址转换
DNAT 目标地址转换
MASQUERADE 动态源地址转换(用于动态IP)
REDIRECT 重定向数据包到另一个端口
MARK 标记数据包
RETURN 返回到调用链

安装 #

在大多数Linux发行版中,iptables命令通常已经预装。如果没有,可以使用以下命令安装:

# Debian/Ubuntu
sudo apt install iptables

# CentOS/RHEL
sudo yum install iptables

# Fedora
sudo dnf install iptables

# Arch Linux
sudo pacman -S iptables

常见用法 #

1. 查看当前规则 #

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

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

# 显示详细信息
sudo iptables -L -v

# 显示规则的行号
sudo iptables -L --line-numbers

# 以数字形式显示
sudo iptables -L -n

2. 添加规则 #

# 允许SSH连接
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许HTTP和HTTPS连接
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

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

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

3. 设置默认策略 #

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

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

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

4. 删除规则 #

# 删除INPUT链中的第1条规则
sudo iptables -D INPUT 1

# 删除特定规则
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT

5. 清空规则 #

# 清空所有规则
sudo iptables -F

# 清空特定链的规则
sudo iptables -F INPUT

6. 保存和恢复规则 #

# 保存规则
sudo iptables-save > /etc/iptables/rules.v4

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

7. 网络地址转换(NAT) #

# 启用IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 设置SNAT(源地址转换)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# 设置DNAT(目标地址转换)
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

8. 端口转发 #

# 将发往80端口的流量转发到8080端口
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

9. 限制连接速率 #

# 限制SSH连接尝试
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j DROP

10. 记录被丢弃的数据包 #

sudo iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
sudo iptables -A INPUT -j DROP

实用示例 #

1. 基本防火墙配置 #

# 清空所有规则
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X

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

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

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

# 允许SSH连接
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许HTTP和HTTPS连接
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许ICMP(ping)
sudo iptables -A INPUT -p icmp -j ACCEPT

# 保存规则
sudo iptables-save > /etc/iptables/rules.v4

2. 配置NAT路由器 #

# 启用IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 清空规则
sudo iptables -F
sudo iptables -t nat -F

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

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

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

# 允许内网访问外网
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

# 设置NAT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# 允许SSH连接
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 保存规则
sudo iptables-save > /etc/iptables/rules.v4

3. 端口转发 #

# 将外部80端口的流量转发到内部服务器
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT

4. 阻止特定IP地址 #

# 阻止特定IP地址
sudo iptables -A INPUT -s 192.168.1.10 -j DROP

# 阻止IP范围
sudo iptables -A INPUT -s 192.168.1.0/24 -j DROP

5. 限制连接数 #

# 限制每个IP到80端口的最大连接数为10
sudo iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

6. 根据时间限制访问 #

# 只允许在工作时间访问
sudo iptables -A INPUT -p tcp --dport 80 -m time --timestart 08:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j DROP

7. 防止DoS攻击 #

# 限制SYN数据包
sudo iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn -j DROP

# 限制ICMP数据包
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

8. 记录并丢弃无效数据包 #

sudo iptables -A INPUT -m state --state INVALID -j LOG --log-prefix "INVALID_PACKET: "
sudo iptables -A INPUT -m state --state INVALID -j DROP

注意事项 #

  1. 错误的iptables规则可能会导致系统无法访问,特别是当你通过SSH远程管理服务器时。

  2. 在应用新规则之前,确保有一条规则允许SSH连接,或者有其他方式访问服务器。

  3. 某些Linux发行版可能使用不同的工具来管理防火墙规则,如ufw(Ubuntu)或firewalld(CentOS/RHEL)。

  4. iptables规则在系统重启后不会自动保存,需要使用iptables-save保存规则,并配置系统在启动时自动加载。

  5. 在容器化环境中,iptables规则可能会与容器网络产生冲突。

提示 #

  • 在应用新规则之前,先使用iptables -L -v查看当前规则
  • 使用--line-numbers选项可以更容易地识别要删除或修改的规则
  • 创建规则时,从最具体的规则开始,到最一般的规则结束
  • 使用-m state --state ESTABLISHED,RELATED允许已建立的连接,这对于大多数防火墙配置都是必要的
  • 使用-m limit可以防止日志文件被大量日志消息填满
  • 对于复杂的防火墙配置,考虑使用脚本或配置管理工具
  • 使用iptables-saveiptables-restore可以更容易地备份和恢复规则
  • 在生产环境中应用规则之前,先在测试环境中测试
  • 对于更复杂的需求,考虑使用更高级的防火墙工具,如nftablesfirewalld
  • 使用-m comment --comment "注释"可以为规则添加注释,使其更易于理解