iptables.md
iptables
基本概念
iptables 可以检测、修改、转发、重定向和丢弃 IPv4 数据包。过滤 IPv4 数据包的代码已经内置于内核中,并且按照不同的目的被组织成 表 的集合。表 由一组预先定义的 链 组成,链 包含遍历顺序规则。每一条规则包含一个谓词的潜在匹配和相应的动作(称为 目标),如果谓词为真,该动作会被执行。也就是说条件匹配。iptables 是用户工具,允许用户使用 链 和 规则。很多新手面对复杂的 linux IP 路由时总是感到气馁,但是,实际上最常用的一些应用案例(NAT 或者基本的网络防火墙)并不是很复杂。
理解 iptables 如何工作的关键是这张图。图中在上面的小写字母代表 表,在下面的大写字母代表 链。从任何网络端口 进来的每一个 IP 数据包都要从上到下的穿过这张图。一种常见的困扰是认为 iptables 对从内部端口进入的数据包和从面向互联网端口进入的数据包采取不同的处理方式,相反,iptabales 对从任何端口进入的数据包都会采取相同的处理方式。可以定义规则使 iptables 采取不同的方式对待从不同端口进入的数据包。当然一些数据包是用于本地进程的,因此在图中表现为从顶端进入,到
在大多数使用情况下都不会用到 raw,mangle 和 security 表。
表(Tables)
iptables 包含 5 张表(tables):
raw
用于配置数据包,raw
中的数据包不会被系统跟踪。filter
是用于存放所有与防火墙相关操作的默认表。nat
用于 网络地址转换(例如:端口转发)。mangle
用于对特定数据包的修改(参考 损坏数据包)。security
用于 强制访问控制 网络规则(例如: SELinux -- 详细信息参考 该文章)。
大部分情况仅需要使用 filter 和 nat。其他表用于更复杂的情况——包括多路由和路由判定——已经超出了本文介绍的范围。
链 (Chains)
表由链组成,链是一些按顺序排列的规则的列表。默认的 filter
表包含 INPUT
, OUTPUT
和 FORWARD
3条内建的链,这3条链作用于数据包过滤过程中的不同时间点,如该流程图所示。nat
表包含PREROUTING
, POSTROUTING
和 OUTPUT
链。
使用 iptables(8) 查看其他表中内建链的描述。
默认情况下,任何链中都没有规则。可以向链中添加自己想用的规则。链的默认规则通常设置为 ACCEPT
,如果想确保任何包都不能通过规则集,那么可以重置为 DROP
。默认的规则总是在一条链的最后生效,所以在默认规则生效前数据包需要通过所有存在的规则。
用户可以加入自己定义的链,从而使规则集更有效并且易于修改。如何使用自定义链请参考 Simple stateful firewall。
规则 (Rules)
数据包的过滤基于 规则。规则由一个目标(数据包包匹配所有条件后的动作)和很多匹配(导致该规则可以应用的数据包所满足的条件)指定。一个规则的典型匹配事项是数据包进入的端口(例如:eth0 或者 eth1)、数据包的类型(ICMP, TCP, 或者 UDP)和数据包的目的端口。
目标使用 -j
或者 --jump
选项指定。目标可以是用户定义的链(例如,如果条件匹配,跳转到之后的用户定义的链,继续处理)、一个内置的特定目标或者是一个目标扩展。内置目标是 ACCEPT
, DROP
, QUEUE
和 RETURN
,目标扩展是 REJECT
and LOG
。如果目标是内置目标,数据包的命运会立刻被决定并且在当前表的数据包的处理过程会停止。如果目标是用户定义的链,并且数据包成功穿过第二条链,目标将移动到原始链中的下一个规则。目标扩展可以被终止(像内置目标一样)或者不终止(像用户定义链一样)。详细信息参阅 iptables-extensions(8)。
遍历链 (Traversing Chains)
该流程图描述链了在任何接口上收到的网络数据包是按照怎样的顺序穿过表的交通管制链。第一个路由策略包括决定数据包的目的地是本地主机(这种情况下,数据包穿过 INPUT
链),还是其他主机(数据包穿过 FORWARD
链);中间的路由策略包括决定给传出的数据包使用那个源地址、分配哪个接口;最后一个路由策略存在是因为先前的 mangle 与 nat 链可能会改变数据包的路由信息。数据包通过路径上的每一条链时,链中的每一条规则按顺序匹配;无论何时匹配了一条规则,相应的 target/jump 动作将会执行。最常用的3个 target 是 ACCEPT
, DROP
,或者 jump 到用户自定义的链。内置的链有默认的策略,但是用户自定义的链没有默认的策略。在 jump 到的链中,若每一条规则都不能提供完全匹配,那么数据包像这张图片描述的一样返回到调用链。在任何时候,若 DROP
target 的规则实现完全匹配,那么被匹配的数据包会被丢弃,不会进行进一步处理。如果一个数据包在链中被 ACCEPT
,那么它也会被所有的父链 ACCEPT
,并且不再遍历其他父链。然而,要注意的是,数据包还会以正常的方式继续遍历其他表中的其他链。
模块 (Modules)
有许多模块可以用来扩展 iptables,例如 connlimit, conntrack, limit 和 recent。这些模块增添了功能,可以进行更复杂的过滤。
配置并运行 iptables
iptables 是一个 Systemd 服务,因此可以这样启动:
# systemctl start iptables
但是,除非有 /etc/iptables/iptables.rules
文件,否则服务不会启动,Arch iptables 包不包含默认的 iptables.rules
文件。因此,第一次启动服务时使用以下命令:
# touch /etc/iptables/iptables.rules
# systemctl start iptables
或者
# cp /etc/iptables/empty.rules /etc/iptables/iptables.rules
# systemctl start iptables
和其他服务一样,如果希望启动时自动加载 iptables,必须启用该服务:
# systemctl enable iptables