一、概述
网络技术分享第一篇网络虚拟化之内核能力NetFilter
关键点:
1.网络层,也就是IP层
2.有5个拦截点
3.NAT、IPTable
二、核心原理
Netfilter框架由著名的Linux开发人员Rusty Russell于1998年开发,旨在改进以前实现ipchains(Linux2.2.x)和ipfwadm(Linux2.0.x)。
这套名为
Netfilter
的框架是
Linux 防火墙和网络的主要维护者
Rusty Russell
提出并主导设计的,它围绕网络层(
IP 协议)的周围,埋下了五个
钩子
Hooks,每当有数据包流到网络层,经过这些钩子时,就会自动触发由内核模块注册在这里的回调函数,程序代码就能够通过回调来干预
Linux 的网络通信。
这五个钩子的名字与含义:
PREROUTING
:来自设备的数据包进入协议栈后立即触发此钩子。
PREROUTING 钩子在进入
IP 路由之前触发,这意味着只要接收到的数据包,无论是否真的发往本机,都会触发此钩子。一般用于目标网络地址转换(
Destination NAT
,
DNAT
)。
INPUT
:报文经过
IP 路由后,如果确定是发往本机的,将会触发此钩子,一般用于加工发往本地进程的数据包。
FORWARD
:报文经过
IP
路由后,如果确定
不是发往本机的,将会触发此钩子,一般用于处理转发到其他机器的数据包。
OUTPUT
:从本机程序发出的数据包,在经过
IP 路由前,将会触发此钩子,一般用于加工本地进程的输出数据包。
POSTROUTING:从本机网卡出去的数据包,无论是本机的程序所发出的,还是由本机转发给其他机器的,都会触发此钩子,一般用于源网络地址转换(
Source NAT
,SNAT
)。
不同类型数据包流向需要经过的钩子节点不完全相同:
- 发往本地:NF_INET_PRE_ROUTING-->NF_INET_LOCAL_IN
- 转发:NF_INET_PRE_ROUTING-->NF_INET_FORWARD-->NF_INET_POST_ROUTING
- 本地发出:NF_INET_LOCAL_OUT-->NF_INET_POST_ROUTING
三、使用示例
Netfilter挂载点定义:
// include/linux/netfilter.h
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
NF_INET_LOCAL_IN,
NF_INET_FORWARD,
NF_INET_LOCAL_OUT,
NF_INET_POST_ROUTING,
NF_INET_NUMHOOKS
};
原文解释:
NF_INET_PRE_ROUTING
: incoming packets pass this hook in the () function before they are processed by the routing code.ip_rcv()``linux/net/ipv4/ip_input.c
NF_INET_LOCAL_IN
: all incoming packets addressed to the local computer pass this hook in the function .ip_local_deliver()
NF_INET_FORWARD
: incoming packets are passed this hook in the function .ip_forwared()
NF_INET_LOCAL_OUT
: all outgoing packets created in the local computer pass this hook in the function .ip_build_and_send_pkt()
NF_INET_POST_ROUTING
: this hook in the ipfinishoutput() function before they leave the computer.
kernel提供如下函数来注册和解除hook函数。
// include/linux/netfilter.h
/* Function to register/unregister hook points. */
int nf_register_hook(struct nf_hook_ops *reg);
void nf_unregister_hook(struct nf_hook_ops *reg);
int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
Netfilter 的钩子回调虽然很强大,但毕竟要通过程序编码才能够使用,并不适合系统管理员用来日常运维,日常用得最多的自然是iptables。