Product SiteDocumentation Site

14.2. 防火墙或者包过滤

防火墙是一个过滤网关,并且只对要通过它的数据包有作用。因此,只有在防火墙是这些数据包的唯一路由器的时候才有效。
缺乏标准配置(之前“过程,而非产品”的格言)就缺少交钥匙解决方案。然而,有些工具使配置 netfilter 防火墙更加简单,使用图形显示过滤规则。fwbuilder 无疑是其中的佼佼者。
The Linux kernel embeds the netfilter firewall. It can be controlled from user space with the iptables and ip6tables commands. The difference between these two commands is that the former acts on the IPv4 network, whereas the latter acts on IPv6. Since both network protocol stacks will probably be around for many years, both tools will need to be used in parallel.

14.2.1. Netfilter 行为

netfilter 使用四个截然不同的表存储规则,来规定对数据包的三种操作:
  • filter 关注过滤规则(接受,拒绝或者忽略数据包);
  • nat 关注转化源地址或者目的地址和数据包端口;
  • mangle 关注对 IP 数据包的其他变化(包含 ToS - 服务类型 -区段和选项);
  • raw 允许在到达追踪系统之前手动更改数据包。
每个表都包含称为链(chains)的规则列表。防火墙使用标准链处理预定义环境下的数据包。管理员可以创建其他链,该链只有在被标准链引用(直接或间接)时才会起作用。
过滤 表有三个标准链:
  • 输入:关注目的地是防火墙自身的数据包;
  • 输出:关注防火墙发出的数据包;
  • 转发:关注通过防火墙的数据包(既不是源头也不是目的地)。
nat 表也有三个标准链:
  • 预先路由:一旦数据包到达就修改;
  • 后路由:在准备继续上路时修改数据包;
  • 输出:修改防火墙自身产生的数据包。
netfilter 中的链是如何被调用的

图 14.1. netfilter 中的链是如何被调用的

每个链是一个规则列表;每个规则是条件集合以及符合条件时要采取的行动。当处理数据包时,防火墙逐一扫描链;当碰到规则条件时,“跳(jumps)”到(因此在命令中使用 -j 选项)规定的行为并继续处理。大多数常用的行为都已经标准化,并有专门操作。使用标准操作会中断对链的处理过程,此时数据包的去向未知(除了下面提到的例外):
  • 接受(ACCEPT):允许数据包继续往下走;
  • 拒绝(REJECT):通过 ICMP 错误数据包拒绝(命令 iptables--reject-with type 选项可以设定错误类型);
  • 丢弃(DROP):删除(忽略)数据包;
  • 记录(LOG):记录(通过 syslogd)描述数据包的信息;注意该行为不会中断处理,并且会继续执行链中断的下一条规则,这就为什么记录拒绝数据包既需要记录规则,也需要拒绝/丢弃规则;
  • ULOG:通过 ulogd 记录信息,在处理大量信息时,它比 syslogd 更合适有效;注意该规则,类似 LOG,也会返回到调用链的下一条规则;
  • 链名(chain_name):跳转到指定链并处理其规则;
  • 返回:中断当前链的处理过程,并返回调用链;如果当前链是一个标准链,并且没有调用链,默认(有iptables-P 定义)就会执行该链;
  • SNAT (only in the nat table): apply Source NAT (extra options describe the exact changes to apply);
  • DNAT (only in the nat table): apply Destination NAT (extra options describe the exact changes to apply);
  • MASQUERADE (only in the nat table): apply masquerading (a special case of Source NAT);
  • REDIRECT (only in the nat table): redirect a packet to a given port of the firewall itself; this can be used to set up a transparent web proxy that works with no configuration on the client side, since the client thinks it connects to the recipient whereas the communications actually go through the proxy.
其他规则,特别是和 mangle 表相关的,不在本章的范围。 iptables(8)ip6tables(8) 有全面的清单介绍。

14.2.2. iptablesip6tables语法

iptablesip6tables 命令允许操作表格,链和规则。-t table 选项指明要操作哪个表(默认,filter)。

14.2.2.1. 命令

The -N chain option creates a new chain. The -X chain deletes an empty and unused chain. The -A chain rule adds a rule at the end of the given chain. The -I chain rule_num rule option inserts a rule before the rule number rule_num. The -D chain rule_num (or -D chain rule) option deletes a rule in a chain; the first syntax identifies the rule to be deleted by its number, while the latter identifies it by its contents. The -F chain option flushes a chain (deletes all its rules); if no chain is mentioned, all the rules in the table are deleted. The -L chain option lists the rules in the chain. Finally, the -P chain action option defines the default action, or “policy”, for a given chain; note that only standard chains can have such a policy.

14.2.2.2. 规则

Each rule is expressed as conditions -j action action_options. If several conditions are described in the same rule, then the criterion is the conjunction (logical and) of the conditions, which is at least as restrictive as each individual condition.
-p protocol 条件匹配 IP 数据包的协议区段。最常见的是 tcpudpicmp,和 icmpv6。条件之前加上感叹号表示求反,就变成了“除了指定协议之外的任何数据包”。这种求反机制不仅仅适用于 -p 选项,也可用于其它所有条件。
-s address-s network/mask 条件匹配数据包的源地址。相应地,-d address-d network/mask 匹配目的地地址。
-i interface 条件选择源自指定网络接口的数据包。-o interface 条件选择从指定接口出去的数据包。
根据上述的通用条件,可以定义更具体的条件。例如,-p tcp 条件可以和 TCP 端口条件互为补充,就形成例如--source-port port--destination-port port
--state state 条件匹配连接中某个状态的数据包(这需要 ipt_conntrack 内核模块,用于连接追踪)。新(NEW) 状态指明开启新连接的数据包;建立(ESTABLISHED) 匹配属于已存在连接的数据包;相关(RELATED) 匹配发起与已存在连接相关的数据包(这对处于“活动”模式的 ftp-data 连接是很有用的)。
前面的段落列出了可用的操作,但是没有相应的选项。例如:记录 LOG 操作,有如下的选项:
  • --log-level, with default value warning, indicates the syslog severity level;
  • --log-prefix 可用来指定不同文字前缀来区分消息;
  • --log-tcp-sequence--log-tcp-options--log-ip-options 指定需附加的消息数据:相对应的 TCP 序列号码,TCP 选项,和 IP 选项。
The DNAT action provides the --to-destination address:port option to indicate the new destination IP address and/or port. Similarly, SNAT provides --to-source address:port to indicate the new source IP address and/or port.
The REDIRECT action (only available if NAT is available) provides the --to-ports port(s) option to indicate the port, or port range, where the packets should be redirected.

14.2.3. 创建规则

每次创建规则需要使用 iptables/ip6tables命令。手工输入这些命令是繁琐的,可以将调用存储在脚本中,这样机器每次启动后就可以进行同样的自动配置。脚本可以手工输入,但是也可以使用很有趣的高级工具(例如,fwbuilder)来准备。
# apt install fwbuilder
规则很简单。第一步,列出所有要调用的规则元素:
  • 防火墙自身以及网络接口;
  • 网络,及其相应的 IP 范围;
  • 服务器;
  • 宿主服务器上服务所使用的端口号。
然后可以使用对象拖拽(drag-and-drop)来创建规则。一些上下文菜单可以改变条件(例如,求反)。然后选择操作和配置。
至于 IPv6,可以为 IPv4 和 IPv6 分别创建规则集,或者只创建一个并使用 fwbuilder 来根据赋给对象的地址来转化规则。
Fwbuilder 主窗口

图 14.2. Fwbuilder 主窗口

fwbuilder can then generate a script configuring the firewall according to the rules that have been defined. Its modular architecture gives it the ability to generate scripts targeting different systems (iptables for Linux, ipf for FreeBSD and pf for OpenBSD).

14.2.4. 每次启动时加载规则

其他情况下,推荐的方法是将配置脚本在 up 目录下作为 /etc/network/interfaces 文件。在后面的例子中,脚本存储在 /usr/local/etc/arrakis.fw

例 14.1. 接口(interfaces) 文件调用防火墙脚本

auto eth0
iface eth0 inet static
    address 192.168.0.1
    network 192.168.0.0
    netmask 255.255.255.0
    broadcast 192.168.0.255
    up /usr/local/etc/arrakis.fw
This obviously assumes that you are using ifupdown to configure the network interfaces. If you are using something else (like NetworkManager or systemd-networkd), then refer to their respective documentation to find out ways to execute a script after the interface has been brought up.