跳转至

iptable

iptables 是 Linux 系统中的一个强大的工具,用于设置防火墙规则以控制网络流量。它通过修改 Linux 内核的网络流量过滤表实现网络包的过滤和转发。以下是 iptables 规则的基本结构和主要概念:


1. 表(Table)

iptables 规则分为几张表,每张表负责处理不同类型的网络数据流。

  • filter 表(默认表):主要用于过滤数据包,决定是否允许或拒绝数据包。
  • nat 表:用于网络地址转换(如端口映射和地址转换)。
  • mangle 表:用于修改数据包(如更改 QoS 标志)。
  • raw 表:用于处理数据包的原始状态,可以控制连接跟踪。
  • security 表:用于加强 SELinux 的安全设置。

2. 链(Chain)

每张表由多个链(Chain)组成,链表示处理数据包的一系列规则的集合。

  • INPUT 链:处理进入本地机器的数据包。
  • OUTPUT 链:处理从本地机器发送出去的数据包。
  • FORWARD 链:处理经过本地机器但不属于本地的数据包(转发包)。
  • PREROUTING 链:在路由决定之前处理数据包(通常用于 NAT)。
  • POSTROUTING 链:在路由决定之后处理数据包(通常用于 NAT)。

3. 规则(Rule)

每个链中可以定义多个规则。每条规则由以下部分组成:

  • 匹配条件:指定规则生效的条件,例如数据包的来源、目的地、协议、端口等。
  • 目标动作:指定匹配到规则时的处理方式,如接受(ACCEPT)、拒绝(DROP)、跳转(JUMP)到自定义链等。

4. 命令

iptables 提供了管理规则的命令,用于添加、删除和查看规则。

常用命令:

  • 添加规则

    iptables -A 链名 -p 协议 --dport 端口 -j 目标
    例如:
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    (允许 SSH 连接)

  • 插入规则

    iptables -I 链名 规则序号 -p 协议 --dport 端口 -j 目标

  • 删除规则

    iptables -D 链名 规则序号

  • 列出规则

    iptables -L

  • 清空规则

    iptables -F

  • 保存规则

    service iptables save


5. 匹配条件

iptables 提供了丰富的条件匹配选项,用于定义规则。

常见匹配参数:

  • 协议

    -p tcp|udp|icmp

  • 来源地址

    -s 地址
    例如:
    iptables -A INPUT -s 192.168.1.1 -j DROP

  • 目标地址

    -d 地址

  • 接口

    -i 接口名   # 入站接口
    -o 接口名   # 出站接口

  • 端口

    --dport 端口   # 目标端口
    --sport 端口   # 源端口


6. 动作(Target)

动作定义了数据包匹配规则后的处理方式。

  • ACCEPT:允许数据包通过。
  • DROP:丢弃数据包,不发送响应。
  • REJECT:拒绝数据包并发送响应。
  • SNAT:修改源地址(用于 NAT)。
  • DNAT:修改目标地址(用于 NAT)。
  • MASQUERADE:伪装(动态 NAT)。
  • LOG:记录日志但不处理数据包。

示例配置

假设我们想配置一组规则: 1. 允许本地回环接口通信。 2. 允许 SSH(22 端口)。 3. 禁止来自某 IP(192.168.1.100)的访问。 4. 拒绝所有其他入站流量。

规则如下:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 192.168.1.100 -j DROP
iptables -A INPUT -j REJECT

高级 iptables 配置实例,涵盖了实际工作中常见的需求和场景。


1. 配置基本防火墙

以下规则可以作为基本防火墙规则的模板:

规则目标:

  • 允许本地通信和已建立连接。
  • 允许特定端口访问(如 HTTP、HTTPS、SSH)。
  • 禁止其他所有入站流量。
  • 默认允许出站流量。

配置命令:

# 清空现有规则
iptables -F
iptables -X

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

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

# 允许已建立和相关连接通过
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许 SSH(22端口)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许 HTTP 和 HTTPS(80 和 443 端口)
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# 默认拒绝其他流量
iptables -A INPUT -j DROP

2. 配置 NAT 转发

用于路由器或网关设备,设置 NAT 转发以实现内网设备的上网。

规则目标:

  • 内网网段:192.168.1.0/24
  • 外网接口:eth0

配置命令:

# 启用内核的 IP 转发功能
echo 1 > /proc/sys/net/ipv4/ip_forward

# 配置 NAT 转发
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# 允许内网转发
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

3. 阻止特定 IP 地址

规则目标:

  • 阻止来自 192.168.1.100 的所有访问。
  • 阻止某 IP 地址段(如 10.0.0.0/8)的访问。

配置命令:

# 阻止单个 IP 地址
iptables -A INPUT -s 192.168.1.100 -j DROP

# 阻止 IP 地址段
iptables -A INPUT -s 10.0.0.0/8 -j DROP

4. 限制端口的连接速率

规则目标:

  • 限制 SSH 登录尝试为每分钟最多 5 次,防止暴力破解。

配置命令:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 -j DROP

5. 配置端口转发

用于将外部流量转发到内网服务器。

规则目标:

  • 外部接口:eth0
  • 内网服务器:192.168.1.10
  • 端口:80(HTTP)

配置命令:

# 配置 DNAT 转发
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80

# 允许转发到内网服务器
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT

6. 记录特定流量

记录来自指定 IP 的访问,用于分析流量或故障排查。

规则目标:

  • 记录来自 192.168.1.100 的所有流量。

配置命令:

iptables -A INPUT -s 192.168.1.100 -j LOG --log-prefix "Blocked IP: " --log-level 4

7. 配置时间段访问

允许某些服务在特定时间段内开放,例如只允许白天访问。

规则目标:

  • 允许 HTTP 服务(端口 80)在每天 8:00 至 18:00 开放。

配置命令:

iptables -A INPUT -p tcp --dport 80 -m time --timestart 08:00 --timestop 18:00 --days Mon,Tue,Wed,Thu,Fri -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j REJECT

8. 防止 SYN 洪泛攻击

SYN 洪泛攻击是常见的 DoS 攻击之一。

配置命令:

iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

9. 配置流量限速

限制单个 IP 每秒最多发送多少数据包,以防止滥用。

规则目标:

  • 限制每秒最多 10 个数据包。

配置命令:

iptables -A INPUT -m limit --limit 10/sec --limit-burst 20 -j ACCEPT
iptables -A INPUT -j DROP

10. 保存并恢复规则

防止重启后规则丢失。

保存规则:

iptables-save > /etc/iptables/rules.v4

恢复规则:

iptables-restore < /etc/iptables/rules.v4

在使用 iptables 配置规则时,如果没有显式指定表(如 -t nat),默认情况下,规则会被添加到 filter 表 中。

filter 表iptables 的默认表,主要负责数据包的过滤(例如允许或拒绝数据包)。

如果没有通过 -t 参数指定表,iptables 会假定操作针对 filter 表

例子

iptables -A INPUT -s 192.168.1.100 -j DROP
解释

-A INPUT:将规则追加到 filter 表 的 INPUT 链。

-s 192.168.1.100:匹配源地址为 192.168.1.100 的数据包。

-j DROP:丢弃匹配的数据包。

因此,这条规则会被添加到 filter 表 的 INPUT 链,用于过滤从 192.168.1.100 发来的流量。


为什么是 filter 表?

iptables 有多张表,每张表的功能不同: 1. filter 表(默认):用于管理数据包的过滤(例如 ACCEPTDROP)。 2. nat 表:用于网络地址转换(SNAT、DNAT)。 3. mangle 表:用于修改数据包的头部。 4. raw 表:用于调整连接跟踪。 5. security 表:用于安全策略相关规则。

没有指定表时,iptables 默认操作的是最常用的 filter 表,因为大多数情况下,我们是在配置防火墙规则(例如允许或拒绝流量)。


如何验证规则在哪张表?

使用以下命令可以列出 filter 表 的规则,并确认规则是否已添加:

sudo iptables -L INPUT -n -v


如何避免混淆?

如果需要明确规则所在的表,可以始终指定表名。例如:

sudo iptables -t filter -A INPUT -s 192.168.1.100 -j DROP
这与默认行为一致,但显式指定表有助于提高规则的可读性和维护性。

如果没有指定表,iptables 默认操作的是 filter 表,所以你的规则会添加到 filter 表 的 INPUT 链中,用于过滤不想要的数据流量。显式指定表(如 -t filter)有助于避免歧义,是一种推荐的做法。

并不是所有规则都可以添加到 filter 表 中。filter 表iptables 的默认表,用于管理数据包的 过滤(即 ACCEPTDROP 等操作),但有些功能只能在特定的表(如 natmangle 表)中实现。如果你尝试将不适合的规则添加到 filter 表 中,iptables 会报错。


适合添加到 filter 表 的规则

filter 表 的功能主要是控制数据包的流向,可以使用以下目标(-j 参数):

ACCEPT:允许数据包通过。

DROP:丢弃数据包。

REJECT:拒绝数据包并发送错误响应。

LOG:记录数据包信息到日志。

RETURN:返回上一链表。

常用的链:

INPUT:管理进入本机的数据包(如SSH流量)。

FORWARD:管理经过本机转发的数据包(如网关转发)。

OUTPUT:管理从本机发出的数据包。

示例(这些规则可以添加到 filter 表):

# 禁止某个IP访问本机
sudo iptables -A INPUT -s 192.168.1.100 -j DROP

# 允许本机访问外网
sudo iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT

# 转发流量的过滤
sudo iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT


无法添加到 filter 表 的规则

有些操作必须添加到其他表中,无法通过 filter 表 实现。如果强行添加会报错,例如:

1.NAT相关规则

NAT功能(如 SNAT、DNAT)必须添加到 nat 表

示例:

# 映射内网到外网地址(SNAT规则) -> 必须用nat表
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

2修改数据包头部

修改TTL或其他数据包字段必须使用 mangle 表

示例:

# 修改数据包的TTL值 -> 必须用mangle表
sudo iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64

3.关闭连接跟踪

必须使用 raw 表

示例:

# 不使用连接跟踪 -> 必须用raw表
sudo iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK


为什么不能将所有规则都添加到 filter 表

这是因为 iptables 的设计中,每个表有其特定的用途: 1. filter 表:专注于数据包过滤。 2. nat 表:处理地址转换(NAT)。 3. mangle 表:用于修改数据包的头部。 4. raw 表:用于连接跟踪的调整。

将所有规则放到 filter 表 中,会破坏这种分工,也会导致某些操作无法实现或出现报错。


建议

1.默认表操作

如果你只是过滤数据包(例如防火墙规则),可以省略表名,直接使用 filter 表

示例:

sudo iptables -A INPUT -s 192.168.1.100 -j DROP

2涉及特殊功能时显式指定表

如需NAT、修改数据包头部等操作,必须显式指定表:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64

3遵循规则分工

不同表的规则分工明确,建议根据功能将规则添加到正确的表中,便于维护和排查。

你可以省略表名添加规则到 filter 表,但只能用于过滤(ACCEPTDROP 等)。

涉及NAT、修改数据包头部或关闭连接跟踪等特殊操作时,必须显式指定正确的表(如 natmangleraw 表)。

遵循iptables表的分工原则,有助于规则的管理和功能实现。