OpenWrt 中的 Netfilter
本节的目的是简要描述 netfilter/iptables 子系统,然后深入研究 OpenWrt 的细节。
Netfilter 和 iptables 概述
Netfilter是Linux 内核中的数据包过滤框架。它允许进行数据包过滤、网络地址[和端口] 转换 (NA[P]T) 和其他数据包操作。它不仅仅是一个简单的防火墙,而且非常强大!
Netfilter 在内核网络堆栈中具有代码挂钩(NF_HOOK_
定义的一些函数)和一组 netfilter 内核模块(主要以nf_
,ipt_
或xt_
开头)
iptables是内核 netfilter 子系统的用户接口。iptables 应用程序使用 netfilterlibiptc
库与 netfilter 内核模块进行通信。 libiptc
与网络堆栈一样,使用 BSD 套接字接口在用户空间和内核空间之间进行通信。
有很多 netfilter/iptables 参考,所以我们不会在这里重复,主要是因为这几乎是纯粹的剪切和粘贴工作,精度水平有限。一些很好的参考是:
- Netfilter Home
- Netfilter HOWTO documents
- Wikipedia:netfilter
- Wikipedia:iptables
- LHN:Linux Firewalls
- iptables Tutorial
- Linux man pages:
iptables
andiptables-extensions
OpenWrt 中的 Netfilter 功能
本节包含 OpenWrt 提供的 netfilter 的高级视图。
网络过滤器功能
netfilter 功能存在于内核中,可以编进内核,也可以是可加载的内核模块。默认情况下,OpenWrt 使用一组有用的 netfilter 功能构建内核,用于强大的路由器。
-
NAT (网络地址转换)
-
REJECT (拒绝)
-
REDIRECT (重定向)
-
CONNTRACK (跟踪)
扫描二维码关注公众号,回复: 13554480 查看本文章 -
LOG (日志)
-
TCPMSS
-
COMMENT
-
MATCH:MAC、STATE(连接状态)、TIME、MULTIPORT(一个或多个IP端口)、LIMIT……
-
MARK
-
MASQUERADE
Netfilter 用户接口 (iptables)
主要存在iptables
和ip6tables
两个用户接口
网络过滤器表
默认情况下,OpenWrt 使用三个 netfilter 表:filter
、nat
、 mangle
。这些足以提供所需的 netfilter 功能。
另外两个 netfilter 表是:raw
, security
.
该raw
表可以通过make menuconfig
Kernel modules → Netfilter Extensions → kmod-ipt-raw添加到内核中。这将启用 netfilterIP_NF_RAW
配置:
config IP_NF_RAW
tristate 'raw table support (required for NOTRACK/TRACE)'
help
This option adds a `raw' table to iptables. This table is the very
first in the netfilter framework and hooks in at the PREROUTING
and OUTPUT chains.
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
该security
表似乎不在 OpenWrt 菜单配置中。内核ipv4/netfilter/Kconfig
中有对它的引用,但不清楚如何启用内核支持
config IP_NF_SECURITY
tristate "Security table"
depends on SECURITY
depends on NETFILTER_ADVANCED
help
This option adds a `security' table to iptables, for use
with Mandatory Access Control (MAC) policy.
If unsure, say N.
fw3 和 netfilter 详细示例
如前所述,有大量的 netfilter 参考和示例。但是,我发现跟踪特定 fw3 规则从定义到数据包处理(“ 从头到尾 ”)的每个步骤很有帮助。
此示例fw3 应用程序 配置规则允许从路由器WAN侧的任何站到LAN 侧的任何站的SSH访问 。
config rule
option src 'wan'
option dest 'lan'
option proto 'tcp'
option dest_port '22'
option target 'ACCEPT'
option name 'ACCEPT-SSH-WAN-LAN'
fw3 UCI 将规则解析为以下 iptables 规则(还有一些用于上下文,隐式创建)。规则按照它们在fw3 print
列表中的显示方式列出
...
iptables -t filter -N zone_lan_dest_ACCEPT
iptables -t filter -N zone_lan_dest_REJECT
...
iptables -t filter -N zone_wan_forward
...
# TCP/22 from WAN jumps to zone_lan_dest_ACCEPT chain
iptables -t filter -A zone_wan_forward -p tcp -m tcp --dport 22 -m comment --comment "!fw3: ACCEPT-SSH-WAN-LAN" -j zone_lan_dest_ACCEPT
...
# All TCP from WAN jumps to zone_lan_dest_REJECT
iptables -t filter -A zone_wan_forward -p tcp -m comment --comment "!fw3: REJECT-ALL-WAN-LAN" -j zone_lan_dest_REJECT
...
# zone_lan_dest_ACCEPT jumps to final ACCEPT target
iptables -t filter -A zone_lan_dest_ACCEPT -o br-lan -m comment --comment "!fw3" -j ACCEPT
...
# All traffic jumps to final reject target
iptables -t filter -A zone_lan_dest_REJECT -o br-lan -m comment --comment "!fw3" -j reject
...
# FORWARD hook, jump to chain zone_wan_forward
iptables -t filter -A FORWARD -i eth1 -m comment --comment "!fw3" -j zone_wan_forward
上面的zone_lan_dest_ACCEPT
,zone_lan_dest_REJECT
和 zone_wan_forward
链的创建,主要是出于方便,这样他们可以被添加和容易地除去。
添加到zone_wan_forward
链中的第一条规则为 tcp/22 ( SSH )执行数据包匹配,如果通过,则跳转到zone_lan_dest_ACCEPT
链。再往下走,这条链在输出接口br-lan
(lan-bridge)上匹配 并跳转到最终ACCEPT
目标。
通常,每个匹配项和目标都是唯一的内核模块。TCP /22 使用 xt_tcpudp
模块,注释使用xt_comment
模块(总是返回成功)。mangle TCPMSS 目标使用xt_TCPMSS
;该reject
目标使用ipt_REJECT
。在ACCEPT
和DROP
目标是基本无操作:ACCEPT
允许网络堆栈继续处理,DROP
立即丢弃该数据包。
如果“ TCP /22”规则不匹配,netfilter 将继续匹配所有TCP流量(非SSH)的下一个规则并跳转到zone_lan_dest_REJECT
。下一个规则链跳转到最终reject
目标,该目标将ICMP数据包发回 给发起者
最后,zone_wan_forward
链被附加到 FORWARD 链,匹配eth1
(WAN 接口) 的输入。FORWARD 这个钩子在内核 ipv4 网络堆栈中被静态调用(参见 ./net/ipv4/ip_forward.c:ip_forward
中的NF_HOOK
调用)
综上这呈现一个概念规则就是:允许从WAN 到LAN 的TCP / SSH流量。
fw3 和 netfilter 附加功能
除了 OpenWrt 版本中提供的标准 netfilter 功能之外,这些功能都很有用(但不是必需的)。
ipset
ipset是一种 netfilter 机制,用于快速管理类似实体的列表。
一种强大的用途是阻止垃圾邮件。通常会添加一条规则来拒绝/丢弃来自每个来源的流量。在标准防火墙中,以下规则阻止单一来源向邮件服务器发送大量垃圾邮件(SMTP是端口 25)。
目前,OpenWrt 中最可维护的机制是将规则添加到WAN区域中的新链中/etc/firewall.user
iptables -N spam_block
iptables -A forwarding_rule -j spam_block
iptables -t filter -A spam_block -s 103.110.144.0/22 -p tcp -m tcp --dport 25 -j DROP
iptables -t filter -A spam_block -s 114.67.64.0/18 -p tcp -m tcp --dport 25 -j DROP
...
有数千个垃圾邮件源,因此(自定义)spam_block 链中的规则数量可能非常大。
使用 ipset
这个例子展示了如何使用ipset
来阻止大量垃圾邮件发送者!
还没有测试…
config ipset
option external spam_block
option match 'dest_ip dest_port'
option family ipv4
option storage hash
将每个规则添加到 ipset 变得难以管理。因此一般将 iptable 规则放入/etc/firewall.user
.