netfilter/iptables 学习
netfilter概述
netfilter 组件位于内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。
iptables 组件是一种用户空间(userspace)的工具,用来插入、修改和除去信息包过滤表中的规则。
Netfilter 提供了整个防火墙的框架,各个协议基于 Netfilter 框架来实现自己的功能。每个协议都有独立的表来存储自己的配置信息,他们之间完全独立的进行配置和运行。
下图是netfilter的主要组成(来源wikipedia):
其中各模块说明:
- 链路层的防火墙模块,在链路层中对数据帧进行处理。对应用户空间的配置工具是ebtables。
- 对ARP处理的防火墙模块,有独立的表来存放自己的配置,对应用户空间的配置工具是arptables。
- 网络层中ipv6的防火墙模块,在Ipv6协议栈中对报文进行处理,对应用户空间的配置工具是ip6tables
- 网络层中ipv4的防火墙模块,在Ipv4协议栈中对报文进行处理,对应用户空间的配置工具是iptables/nftables。
nftables是iptables的后继者,nftables在用户态把网络规则编译成字节码,然后由内核的虚拟机执行。
一个数据包在netfilter中的处理流程如下图(来源wikipedia):
网络层中的hook
Netfilter 提供了5个网络层的hook,分别位于linux 网络栈中的各个处理节点,如下图:
--->[NF_IP_PRE_ROUTING]--->[ROUTE]--->[NF_IP_FORWARD]--->[NF_IP_POST_ROUTING]--->
| ^
| |
| [ROUTE]
v |
[NF_IP_LOCAL_IN] [NF_IP_LOCAL_OUT]
| ^
| |
v |
--------Local Process-------
Netfilter Hook的意义(参考:www.netfilter.org):
- NF_IP_PRE_ROUTING: 位于路由之前,报文一致性检查之后(报文一致性检查包括: 报文版本、报文长度和checksum)。
- NF_IP_LOCAL_IN: 位于报文经过路由之后,并且目的是本机的。
- NF_IP_FORWARD:位于在报文路由之后,目的地非本机的。
- NF_IP_LOCAL_OUT: 由本机发出去的报文,并且在路由之前。
- NF_IP_POST_ROUTING: 所有即将离开本机的报文。
Linux 内核模块可以注册到任何的hook,注册的回调函数也必需指定优先级。当一个报文通过hook的时候,hook将会依据优先级调用回调函数。注册的回调函数,可以有五种返回,每种返回代表对报文不同的操作:
- NF_ACCEPT: 继续正常处理此报文,即允许报文通过。
- NF_DROP: 丢弃此报文,不再进行继续处理,即拒绝此报文。
- NF_STOLEN: 取走这个报文,不再继续处理。
- NF_QUEUE: 报文进行重新排队,可以将报文发到用户空间的程序,进行修改或者决定是拒绝或者允许。
- NF_REPEAT: 报文重新调用hook。
iptables的介绍
关于iptables的原理已经有很多博客都介绍过了,这里把我做的一个图放上来供大家参考:
iptables常用的就是如上图所示的四表五链(实际上还有个Security Table,应该是五个表,但这个表很少用):
- 四表:
- raw:可以对报文在链路跟踪之前进行处理
- mangle:主要用于对报文的修改
- nat:主要用于NAT转换
- filter:默认的规则表,用于报文的过滤
- 五链:PREROUTING, INPUT, OUTPUT, POSTROUTING, FORWARD,分别对应的是netfilter的五个hook。
iptables 工具使用
iptables命令基本格式:
iptables [-t table] [option] chain [rulenum] rule-specification
iptables 的操作是针对表中的链进行的,如果不指定,默认表为filter。
常用的Option如下
规则级别的修改:
-A | 添加规则到指定链最后一行 |
-D | 删除指定链指定行 |
-I | 插入规则到指定链的指定行,默认插入第一行 |
-R | 替换规则到指定链指定行 |
针对规则查询的:
-L | 列出指定链中所有规则,若未指定链,则列出所有规则。-n 以数字方式显示,-v 显示具体信息 |
-S | 类似于-L,按照iptables-save的格式打印规则 |
链级别的修改:
-N | 新增自定义链 |
-X | 删除指定链,如未指定,则默认删除所有链 |
-P | 修改内置链的默认策略,值为ACCEPT或DROP |
-F | 删除指定链中的所有规则,默认删除所有规则(所有链都还在,只不过规则被清空) |
规则语法(rule-specification)
规则由包匹配和目标动作组成。目标动作由-j
选项指定。
常用的包匹配:
-p | 指定协议。常见的有:tcp, udp, icmp |
-s | 指定源地址,格式类似于192.168.1.0/24 ,多个地址使用逗号分隔,并且会自动形成多条规则 |
-d | 指定目的地址,格式与-s一样 |
-i | 指定某网卡的流入规则 |
-o | 指定某网卡的流出规则 |
-m | 指定扩展匹配,可以匹配到特定性质的包。最常用的是tcp, udp, conntrack。当使用tcp和udp时,可以使用--dport指定目标地址端口,--sport指定源地址端口 |
大部分都支持使用!
进行反向匹配。如:
iptables -A INPUT -s 192.168.2.0/24 -p tcp ! -i enth0 -j ACCEPT
# 接受所有非enth0的网卡流入的源地址为192.168.2.0/24网段的包。
-j
中包含很多操作,比如对包的标记,ip地址的修改,ttl的修改等操作。某些操作只能在特定表和链中进行。
常用的动作:
-j user-chain |
跳转到指定的自定义链。注意,自定义链匹配到最后一行以后会返回跳转之前的地方继续向后匹配 |
`-j ACCEPT | DROP |
-j LOG [options] |
记录日志 |
-j MASQUERADE |
仅在nat表的POSTROUTING链中使用。用于snat自动转换IP功能 |
-j SNAT |
仅在nat表的POSTROUTING链中使用 |
-j DNAT |
仅在nat表的PRETROUTING和OUTPUT链中使用 |
最后补充一个刚刚犯的错误:
在配置FORWARD的时候,要保证正常通信,一定要配置双向的规则。任何网卡流入的包首先经过的链都是PREROUTING。总结如下图:
enth-a和enth-b都是主机的网卡。在FORWARD链上配置:
iptables -A FORWARD -i enth-a -j ACCEPT
iptables -A FORWARD -o enth-a -j ACCEPT
即可简单实现双网卡之间的互相转发。