02.07.2013 Views

ANN/Li Yu Netfilter

ANN/Li Yu Netfilter

ANN/Li Yu Netfilter

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

<strong>ANN</strong>/<strong>Li</strong> <strong>Yu</strong>


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

<strong>Li</strong>nux 网络协议栈概况<br />

<strong>Netfilter</strong><br />

Iptable<br />

连接跟踪<br />

NAT


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

<strong>Li</strong>nux networking protocol stack overview


Inside <strong>Li</strong>nux <strong>Netfilter</strong>


<strong>Netfilter</strong><br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

什么是 netfilter ?<br />

<strong>Netfilter</strong> 如何工作?<br />

Iptable, netfilter, 连接跟踪及 NAT.<br />

Play source code.


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

什么是 netfilter?<br />

只是在 <strong>Li</strong>nux 协议栈上的各层接合点上的一个 hook 注入机制。举个<br />

例子,当内核检测到接收到的数据包是到达本机的,就会调用内核函数<br />

ip_local_deliver() ,这个函数不会直接处理相应的事务,而是主动给<br />

<strong>Netfilter</strong> 一次执行 hook 的机会。<br />

这个机制简单,但提供了足够的灵活性,我们可以利用它过滤、修<br />

改、抛弃、统计数据包,甚至凭空注入新的数据包。事实上,我们甚至几<br />

乎可以在 <strong>Netfilter</strong> 上实现另一套 <strong>Li</strong>nux 协议栈。


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

<strong>Netfilter</strong> 如何工作?<br />

<strong>Netfilter</strong> 的工作方式非常简单,它的主要功能入口是通过 NF_HOOK<br />

宏,以下是一个例子:<br />

int ip_local_deliver(struct sk_buff *skb)<br />

{<br />

/* 这里省略若干代码 */<br />

return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb,<br />

skb->dev, NULL,<br />

ip_local_deliver_finish);<br />

}


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

Iptable, netfilter ,连接跟踪以及 NAT<br />

Iptable, 连接跟踪, NAT 都在用 netfitler 框架提供的 hook 功能实现<br />

的扩展。<br />

内核中的 Iptable 的功能是根据数据包在协议栈上出现的位置,方<br />

向和所管理员指定的配置完成对数据包的匹配和目标操作。防火墙一般在<br />

filter 表内完成,网络地址转换的准备工作在 NAT 表内完成,此外,还有<br />

mangle 表和 security 表。<br />

<strong>Li</strong>nux 的防火墙功能之所以强大,就是因为它不仅仅是一个包过滤<br />

系统,而且网络连接的状态对数据包判定也有所影响,这势必需要在内核<br />

里维护网络连接的状态信息,这个功能就是由 “ 连接跟踪 ” 子系统完成的。<br />

注:这里的连接并不是局限于 TCP / SCTP 这样的有状态协议。<br />

iptable 中的 nat 表完成的只是 NAT 中的准备工作,即计算出了转<br />

换后的地址,具体转换是在 iptable 之外完成的。而且, NAT 功能不仅<br />

依赖于 iptable ,也依赖于 “ 连接跟踪 ” 。


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

It‘s time to play source code !


Iptable<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

基本术语及其数据结构<br />

数据结构的组织<br />

Play source code: (1) 初始化过程<br />

Play source code: (2) 核心处理过程


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

基本术语及其数据结构<br />

规则 → ipt_entry,” 包模式 ” 保存于 ipt_entry 的 ip 成员内;<br />

匹配 → ipt_match<br />

目标 → ipt_target<br />

表 → xt_table 和 xt_table_info<br />

其他 : ipt_replace


数据结构的组织<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

Ipt_replace 和 xt_table_info 的 entries 成员保存的是一个 ipt_entry 数组<br />

” 匹配要求 ” 和 “ 目标处理 ” 保存于 ipt_entry 的 elems 成员内,这又是一个<br />

结构数组。这个数组以 ipt_match 序列开始,之后是 ipt_target 序<br />

列。 Ipt_target 序列以字节 ipt_entry->target_offset 开始。<br />

Ipt_replace 和 xt_table_info 的成员 hook_entry[NF_INET_NUMHOOKS] 保<br />

存的是一系列 entries 的偏移。例如, hook_entry[NF_INET_LOCAL_IN] 保存着<br />

LOCAL_IN 链上需要处理的第一个 iptable 规则的偏移。 Iptables 的核心函数<br />

ipt_do_table() 会从这个偏移上找到的 iptable 规则开始处理。请注意,默认<br />

hooks 表中有许多 hook 其实只是 ipt_do_table() 的包装函数,它们使用不同的<br />

iptable table 调用它。<br />

Ipt_replace 和 xt_table_info 的成员 underflow[NF_INET_NUMHOOKS] 保<br />

存的是也一系列 entries 的偏移。有些 iptable target 可能返回 IPT_RETURN ,<br />

这表明这要求内核返回到上一个处理的规则上,这个回溯关系事实上是一条 “ 链<br />

栈 ” 。而每个 chain 都可以有这样一个链栈, underflow[] 记录的就是这个栈的栈<br />

底偏移。


数据结构的组织<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

图 1 整 “ <strong>Li</strong>nux netfilter 机制分析 ” PDF 。<br />

图 2 整补充图,现场手工绘制,不到场的<br />

看不着喽!


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

Source code is our good friend, huh? So do not let it<br />

live alone!


连接跟踪<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

抽象网络连接状态<br />

重要数据结构<br />

Play source code: tracking and confirm


抽象连接状态<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

NF_CT_ESTABLISHED :数据报属于已经完全建立的连接<br />

NF_CT_RELATED : 数据报属于一个新的连接,但此连接与一个现有连<br />

接相关(预期连接),或者是 ICMP 错误<br />

NF_CT_NEW :数据报属于一个新的连接<br />

NF_CT_IS_REPLY :数据报属于一个连接的回复,不单独使用,两种用<br />

法: ESTABLISHED+IS_REPLY , RELATED+IS_REPLY<br />

这里的状态与 TCP 无一一对应关系


• 抽象连接状态<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

发包方向 TCP 标志位 连接状态 说明<br />

A->B SYN NEW Also apply for<br />

UDP, ICMP<br />

B->A SYN/ACK ESTABLISHED<br />

+IS_REPLY<br />

Also apply for<br />

UDP, ICMP<br />

A->B ACK ESTABLISHED TCP only


重要的数据结构<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong>


重要的数据结构<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

实际上,连接跟踪中涉及到的数据结构很多,画<br />

图太累了,还是用代码说明数据结构最直接,再说我<br />

也挺 LAN 的 ~


Play source code<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

Defragment IP datagram first if need.<br />

Tracking a connection operation.<br />

Confirm a connection if need.


NAT<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

NAT 的概念过程<br />

<strong>Li</strong>nux 如何实现 NAT<br />

重要数据结构<br />

Play source code


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

NAT 的概念过程<br />

SNAT 中的 S ,和 DNAT 中的 D 是什么意思,地球人都知<br />

道。<br />

可是实现 SNAT 还需要转换 D 地址,同理, DNAT 的实<br />

现也得转换 S 地址,为什么呢?<br />

实现 NAT 功能需要完整的 IP 数据报。<br />

实现 NAT 功能需要连接跟踪功能。<br />

SNAT , DNAT 典型场景。


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

<strong>Li</strong>nux 如何实现 NAT<br />

连接跟踪即已经要求 IP 分片重组了。<br />

Iptable 的 Nat 表内保存了 NAT 规则。<br />

使用连接跟踪状态表保存地址转换关系。


重要数据结构<br />

Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

前面都已经提到过了。<br />

懒惰,是一种美德,所以,请参考之前的图片。


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

Source code is alive, they need your understanding.


Inside <strong>Li</strong>nux <strong>Netfilter</strong><br />

●GAME OVER

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!