Linux iptables 防火墙配置与使用指南
11 minute read

在 Linux 系统中,iptables 是一个强大且灵活的命令行工具,用于配置和管理 Linux 内核的 netfilter 包过滤框架。它允许管理员定义规则来控制进出服务器的网络流量,是实现网络安全策略的关键组件。本文将详细介绍 iptables 的基本概念、常用命令以及一些实际的配置示例。

Netfilter 与 iptables

Netfilter 是 Linux 内核中实现网络数据包过滤、NAT(网络地址转换)和连接跟踪的框架。它提供了多个“钩子”(hooks),允许你在数据包经过网络堆栈的特定点时执行自定义操作。

iptables 是一个用户空间的工具,它通过与 Netfilter 框架交互,来设置、维护和查看这些规则。你可以将 iptables 理解为 Netfilter 的“前端”。

iptables 的基本概念

  1. 表 (Table): iptables 有几个内置的表,每个表处理特定类型的网络数据包。

    • filter (默认表): 用于包过滤,即决定是否允许或拒绝数据包通过。这是最常用的表。
    • nat: 用于网络地址转换(Source NAT, Destination NAT)。
    • mangle: 用于修改数据包的头部信息,例如 TTL。
    • raw: 用于绕过连接跟踪机制,主要用于配置 exempt 规则。
    • security: 用于强制访问控制(MAC),在 SELinux 等安全模块中使用。
  2. 链 (Chain): 每个表都包含多个链。链是数据包在经过表中时需要遵循的规则序列。

    • filter 表的链:
      • INPUT: 处理发往本机(服务器本身)的数据包。
      • OUTPUT: 处理本机发出的数据包。
      • FORWARD: 处理(转发)经过本机但不发往本机的数据包。
    • nat 表的链:
      • PREROUTING: 在路由判断之前,修改目标地址(DNAT)。
      • POSTROUTING: 在路由判断之后,修改源地址(SNAT)。
      • OUTPUT: 处理本机发出的数据包,用于修改源地址(SNAT)。
    • mangle 表的链: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
  3. 规则 (Rule): 链由一系列规则组成。数据包会按顺序匹配链中的规则。

    • 匹配 (Match): 规则可以定义各种条件来匹配数据包,例如源 IP 地址、目标 IP 地址、协议(TCP, UDP, ICMP)、端口号、接口等。
    • 目标 (Target): 如果数据包匹配了某条规则,就会执行该规则指定的操作,称为“目标”。
      • ACCEPT: 允许数据包通过。
      • DROP: 静默地丢弃数据包(不返回任何信息给发送方)。
      • REJECT: 丢弃数据包,并返回一个错误信息(如 ICMP port unreachable)给发送方。
      • SNAT: 修改源 IP 地址。
      • DNAT: 修改目标 IP 地址。
      • MASQUERADE: 一种特殊的 SNAT,当源 IP 地址是动态分配的时使用。
      • LOG: 记录匹配的数据包信息(用于调试)。
      • RETURN: 停止在当前链中继续匹配,并返回到调用它的链。
      • JUMP: 将数据包跳转到另一个链进行处理。
  4. 策略 (Policy): 每个链都有一个默认策略,当数据包不匹配链中的任何规则时,就会应用这个策略。常见的策略是 ACCEPTDROP

常用 iptables 命令

  • 查看规则:

    1sudo iptables -L  # 列出 filter 表的所有链的规则
    2sudo iptables -t nat -L # 列出 nat 表的所有链的规则
    3sudo iptables -L -v -n # -v 显示详细信息(包括接口、包/字节计数),-n 显示 IP 和端口号,不进行 DNS 查找
    
  • 添加规则:

    1sudo iptables -A <chain> <rule specification> -j <target>
    2# -A: Append (添加到链的末尾)
    3# -I <chain> [rule_num]: Insert (插入到链的指定位置,默认插入到首位)
    
  • 删除规则:

    1sudo iptables -D <chain> <rule specification> # 根据规则描述删除
    2sudo iptables -D <chain> <rule_num> # 根据规则编号删除
    
  • 替换规则:

    1sudo iptables -R <chain> <rule_num> <new rule specification> -j <target>
    
  • 清空规则:

    1sudo iptables -F [<chain>] # 清空指定链的所有规则,不指定则清空所有链
    
  • 设置默认策略:

    1sudo iptables -P <chain> <policy> # 例如: sudo iptables -P INPUT DROP
    

常用匹配条件

  • -s <ip>--source <ip>: 指定源 IP 地址或网段。
  • -d <ip> or --destination <ip>: 指定目标 IP 地址或网段。
  • -p <protocol>: 指定协议(tcp, udp, icmp, all)。
  • -i <interface>: 指定入站接口(如 eth0)。
  • -o <interface>: 指定出站接口(如 eth1)。
  • --sport <port>: 指定源端口。
  • --dport <port>: 指定目标端口。
  • -m state --state <state>: 使用 state 模块匹配连接状态(NEW, ESTABLISHED, RELATED, INVALID)。
  • -m tcp --tcp-flags <mask> <comp>: 匹配 TCP 标志位。

实际配置示例

  1. 允许所有入站和出站流量,并丢弃所有转发流量 (基本配置)

     1# 清空所有规则
     2sudo iptables -F
     3sudo iptables -t nat -F
     4sudo iptables -t mangle -F
     5
     6# 设置默认策略为 ACCEPT
     7sudo iptables -P INPUT ACCEPT
     8sudo iptables -P OUTPUT ACCEPT
     9sudo iptables -P FORWARD DROP # 禁用转发
    10
    11# 允许已建立和相关的连接
    12sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    13sudo iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    

    注意:在生产环境中,通常会将默认策略设置为 DROP,然后逐个允许需要的流量。

  2. 只允许 SSH (22 端口) 和 HTTP (80 端口) 入站

     1# 先设置默认策略为 DROP
     2sudo iptables -P INPUT DROP
     3sudo iptables -P OUTPUT ACCEPT # 允许出站
     4sudo iptables -P FORWARD DROP
     5
     6# 允许已建立和相关的连接
     7sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
     8
     9# 允许 SSH (TCP 22 端口)
    10sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    11
    12# 允许 HTTP (TCP 80 端口)
    13sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    14
    15# 允许 ICMP (ping) - 可选
    16sudo iptables -A INPUT -p icmp -j ACCEPT
    17
    18# 记录被拒绝的流量 (可选,用于调试)
    19# sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DENIED: "
    20# sudo iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
    
  3. 配置 NAT (端口转发) 假设服务器 IP 是 1.1.1.1,内网有一台 Web 服务器 IP 是 192.168.1.100,我们想将服务器的 80 端口流量转发到内网 Web 服务器的 80 端口。

     1# 允许 IP 转发 (在 /etc/sysctl.conf 中设置 net.ipv4.ip_forward = 1 并执行 sysctl -p)
     2echo 1 > /proc/sys/net/ipv4/ip_forward
     3
     4# 配置 DNAT
     5sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
     6
     7# 配置 SNAT (因为内网服务器需要响应到公网 IP)
     8# 如果内网服务器直接访问公网,则需要 SNAT,这里用 MASQUERADE 更灵活
     9sudo iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 80 -j MASQUERADE
    10
    11# 确保 filter 表允许流量通过
    12sudo iptables -A FORWARD -d 192.168.1.100 -p tcp --dport 80 -j ACCEPT
    
  4. 限制单个 IP 的访问频率 (使用 limit 模块) 例如,限制 SSH 登录尝试的频率。

    1sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 5/min --limit-burst 10 -j ACCEPT
    2sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j REJECT --reject-with tcp-reset
    

    这表示每分钟最多允许 5 次新的 SSH 连接,并且在触发限制前允许最多 10 次连接(burst)。超过限制的连接会被拒绝。

保存 iptables 规则

iptables 规则在系统重启后会丢失。需要将它们保存下来。具体方法因 Linux 发行版而异:

  • Debian/Ubuntu:

    1sudo apt-get install iptables-persistent
    2sudo netfilter-persistent save
    

    或者手动保存:

    1sudo iptables-save > /etc/iptables/rules.v4
    2sudo ip6tables-save > /etc/iptables/rules.v6
    

    然后在 /etc/network/interfaces 或 systemd 服务中配置在启动时加载。

  • CentOS/RHEL:

    1sudo yum install iptables-services
    2sudo systemctl enable iptables
    3sudo iptables-save > /etc/sysconfig/iptables
    4sudo systemctl start iptables
    

安全建议

  • 最小权限原则: 默认拒绝所有流量,然后只允许必需的流量。
  • 使用 state 模块: 始终允许 ESTABLISHED, RELATED 的连接,这能显著减少不必要的规则,并提高安全性。
  • 限制不必要的端口: 关闭所有未使用的端口。
  • 使用 DROP 而非 REJECT: 对于外部不应访问的流量,使用 DROP 更安全,因为它不会暴露服务器内部结构。
  • 定期审查: 定期审查 iptables 规则,确保其符合当前的安全策略。
  • 日志记录: 合理配置日志记录,以便在出现问题时进行分析。

总结

iptables 是 Linux 系统上一款功能强大的网络防火墙工具。掌握其基本概念、命令和配置方法,是保障服务器网络安全的基础。通过精心设计的规则,我们可以有效地控制网络流量,抵御潜在的攻击。

世界杯投注 平台为您提供最新的服务器安全技术动态。