iptables 初探

简介

iptables 是 Linux 下一个运行在用户态的网络工具,主要用来设置、维护和检查 IP 数据包的过滤规则。不过它自己并不干活,真正干活的是内核里的 netfilter 框架。

netfilter

很多人以为过滤数据包是 iptables 干的,其实不是。真正实现过滤功能的是 netfilter——Linux 内核里的一个网络子系统。它在协议栈中预定义了若干钩子(hook),数据包流经的每个关键节点都能被拦截下来处理。iptables 更像个“传话的”:你在命令行里配好规则,它负责转达给内核中的 netfilter。

基本概念

规则一多就容易乱,所以 iptables 用表(table)把规则按功能分类。常用的表有 4 个:raw、mangle、nat、filter。如果一条链上同时挂了好几张表的规则,它们的执行顺序是:raw → mangle → nat → filter。

raw

决定数据包要不要被连接跟踪机制处理。想让某些包不被跟踪,可以在这里配合 NOTRACK 目标来豁免。对应内核模块:iptable_raw。

mangle

顾名思义,用来“改造”数据包——修改服务类型(TOS)、TTL、防火墙标记(MARK)这些内容,配合策略路由还能实现 QoS。对应内核模块:iptable_mangle。

nat

做网络地址转换(NAT)用的,也就是修改数据包的源地址/端口(SNAT)或者目的地址/端口(DNAT)。家里路由器共享上网靠的就是它。对应内核模块:iptable_nat。

filter

最常用的一张表,干的是“过滤”这个本职工作。匹配上条件之后,可以选择接受(ACCEPT)、丢弃(DROP)或者拒绝(REJECT)。对应内核模块:iptable_filter。

链(chain)对应的就是上面说的那些钩子点,可以理解成数据包路上的“检查站”。内置的链一共 5 条:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。每条链上按顺序挂着多条规则,跟检查清单一样:数据包进来后逐条比对,命中了就按规则里写的动作处理;一条都没中,就按链的默认策略(policy)来。

PREROUTING

数据包刚进门、还没做路由决策时经过这里。所有进入主机的包,第一站都是它。

INPUT

路由决策之后发现这包是发给本机的,就会走 INPUT 链,放行之后交给上层的应用程序。

FORWARD

包只是路过本机、需要转发到别处去的,走 FORWARD 链。

OUTPUT

本机自己要发出去的包,走 OUTPUT 链。

POSTROUTING

包做完路由决策、即将离开主机之前,最后经过 POSTROUTING 链。

表与链的关系

表和链是多对多的关系——一张表可以包含多条链,一条链也可以同时出现在好几张表里。说起来有点绕,看图就清楚了:

iptables 表与链的关系

处理流程

把这些链串起来,一个数据包从进来到出去的完整路径是这样的:先到 PREROUTING 链,然后做路由决策,接下来分两种情况:

  • 目的地址是本机:走 INPUT 链,放行后交给应用程序;应用程序处理完,回包再依次经过 OUTPUT、POSTROUTING 链发出去。
  • 目的地址是外部:走 FORWARD 链,然后到 POSTROUTING 链转发出去。

当然,这一切的前提是规则没有把包丢弃或拒绝——不然半路就没了。

相关命令

概念就这么多,最后看下命令长什么样:

iptables [-t 表] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]

说明:

  • 表名、链名:指定操作哪张表、哪条链。不指定 -t 的话,默认操作 filter 表;
  • 命令选项:对规则做什么操作,比如插入、追加、删除、查看等;
  • 条件匹配:什么样的包才算命中,比如按源 IP、端口、协议来过滤;
  • 目标动作或跳转:命中之后怎么办——放行(ACCEPT)、拒绝(REJECT)、丢弃(DROP),或者跳转(Jump)到其他自定义链继续处理。

篇幅有限,规则具体的增删改查就留到下次再写了。