Netfilter/iptables项目由RustyRusse创建于1998年,并于1999年完善了NetfilterCoreteamlinux就该这么学,并在随后负责维护此项目linux回调函数,同时也于2000年3月合并进了linux2.3.x版本的linux内核。
Netfilter/iptables有三部份组成,分别是Netfilter框架/Iptables(内核空间)/Iptables命令行工具(用户空间)。
Netfilter是一个由Linux内核提供的框架,可以进行多种网路相关的自定义操作。
比如:
Netfilter在Linux内核中表现为一系列的hook,并容许Linux内核模块注册为反弹函数,Linux内核模块通过反弹函数操作网路报文。
构架
图片作者JanEngelhardtNetfilterk框架是怎样工作的?
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 |
NetfilterHook的意义:
Linux内核模块可以注册到任何的hook,注册的反弹函数也必需指定优先级。当一个报文通过hook的时侯,hook将会根据优先级调用反弹函数。注册的反弹函数,可以有五种返回,每种返回代表对报文不同的操作:
哪些是内核空间的iptables?
Iptables是基于Netfilter框架实现的报文选择系统,其可以用于报文的过滤、网络地址转换和报文更改等功能。Iptables本质上是包含了5个规则表,而规则表则包含了一些列的报文的匹配规则以及操作目标。以下对每位规则表进行了简单说明:
操作目标指的是否容许报文通过,假如容许即为ACCEPT,拒绝则为DROP。
怎样使用iptables命令行工具?
iptables命令行工具是工作在用户空间的操作工具,用于更改内核空间的规则表linux回调函数linux文本编辑器,下边给出了几个反例:
拒绝来自192.168.12.4的报文
# Drop all incoming packets from address 192.168.12.4
iptables -I INPUT -s 192.168.12.4 -j DROP
拒绝ping任何主机
iptables -A OUTPUT -p icmp -j DROP
以下为来自maniptables的使用方式
# Append rule-specification in selected chain
iptables [-t table] -[A] chain rule-specification [options]
# Insert one or more rules in the selected chain as the given rule number.
iptables [-t table] -I chain [rulenum] rule-specification [options]
# Replace a rule in the selected chain
iptables [-t table] -R chain rulenum rule-specification [options]
# Delete one or more rules from the selected chain.
iptables [-t table] -D chain rulenum [options]
# List all rules in the selected chain.
iptables [-t table] -[L] [chain] [options]
# Flush the selected chain.
iptables [-t table] -[F] [chain] [options]
# Set the policy for the chain to the given target.
iptables [-t table] -P chain target [options]
动手编撰一个netfilterhook反弹函数
以下代码实现了一个简单的linux内核模块,但是通过netfilterhook注册了一个反弹函数,借此来实现禁用ICMP报文(未能从本机ping任何主机)。
/*
* This code was compiled and tested on Ubuntu 18.04.2
* with kernel version 4.15.0
*/
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Rui");
MODULE_DESCRIPTION("A simple example netfilter module.");
MODULE_VERSION("0.0.1");
static struct nf_hook_ops *nfho = NULL;
static unsigned int hfunc(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
struct iphdr *iph;
if (!skb)
return NF_ACCEPT;
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_ICMP) {
return NF_DROP;
}
return NF_ACCEPT;
}
static int __init LKM_init(void)
{
nfho = (struct nf_hook_ops*)kcalloc(1, sizeof(struct nf_hook_ops), GFP_KERNEL);
/* Initialize netfilter hook */
nfho->hook = (nf_hookfn*)hfunc; /* hook function */
nfho->hooknum = NF_INET_PRE_ROUTING; /* received packets */
nfho->pf = PF_INET; /* IPv4 */
nfho->priority = NF_IP_PRI_FIRST; /* max hook priority */
nf_register_net_hook(&init_net, nfho);
}
static void __exit LKM_exit(void)
{
nf_unregister_net_hook(&init_net, nfho);
kfree(nfho);
}
module_init(LKM_init);
module_exit(LKM_exit);
Makefile
obj-m += netfilter-LKM.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
在BashShell环境下编译,而且加载linux内核模块。
make
insmod netfilter-LKM.ko
通过rmmodnetfilter-LKM移除linux内核模块。
参考
1Netfilter
2LinuxKernelCommunicationNetfilterHooks
3NetfilterArchitecture