网站首页 > 技术文章 正文
Netfilter/iptables 项目由 Rusty Russe 创建于1998年,并于 1999 年建立了 Netfilter Core team,并在此后负责维护此项目,同时也于2000年3月合并进了 linux 2.3.x 版本的 linux 内核。
Netfilter/iptables 有三部分组成,分别是Netfilter 框架/Iptables(内核空间)/Iptables 命令行工具(用户空间)。
Netfilter 是一个由Linux 内核提供的框架,可以进行多种网络相关的自定义操作。
例如:
- 无状态的报过滤(IPv4 and IPv6)
- 有状态的报过滤(IPv4 and IPv6)
- 网络地址转换(NAT/NAPT)
Netfilter 在 Linux 内核中表现为一系列的hook, 并允许Linux 内核模块注册为回调函数,Linux内核模块通过回调函数操作网络报文。
架构
Netfilterk框架是如何工作的?
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 |
Netfilter Hook的意义:
- 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 是基于Netfilter框架实现的报文选择系统,其可以用于报文的过滤、网络地址转换和报文修改等功能。Iptables 本质上是包含了5个规则表,而规则表则包含了一些列的报文的匹配规则以及操作目标。以下对每个规则表进行了简单说明:
- Filter Table: 是一个默认的规则表,用于报文的过滤。他注册了三个链: INPUT、FORWARD和OUTPUT。
- NAT Table: 主要用于NAT转换,注册了四个链:PREROUTING、INPUT、OUTPUT和POSTROUTING。
- Mangle Table: 主要用于报文的修改,一共注册了五个链: PREROUTING、OUTPUT、INPUT、FORWARD和POSTROUTING
- Raw Table: 可以对报文不进行链路跟踪,其优先级在hook中注册很高,注册了两个链: PREROUTING和OUTPUT
- Security Table: 用于强制网络接入控制,注册了三个链:INPUT、OUTPUT 和 FORWARD
操作目标指的是否允许报文通过,如果允许即为ACCEPT,拒绝则为DROP。
如何使用iptables命令行工具?
iptables命令行工具是工作在用户空间的操作工具,用于修改内核空间的规则表,下面给出了几个例子:
拒绝来自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
以下为来自man iptables的使用方法
# 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]
动手编写一个netfilter hook回调函数
以下代码实现了一个简单的linux 内核模块,并且通过netfilter hook注册了一个回调函数,以此来实现禁用ICMP报文(无法从本机ping任何主机)。
/*
* This code was compiled and tested on Ubuntu 18.04.2
* with kernel version 4.15.0
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
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
在Bash Shell环境下编译,并且加载linux内核模块。
make
insmod netfilter-LKM.ko
通过 rmmod netfilter-LKM 移除linux内核模块。
参考
1 Netfilter
2 Linux Kernel Communication Netfilter Hooks
3 Netfilter Architecture
猜你喜欢
- 2024-10-12 「观潮」4K HDR高动态范围制作技术(下)
- 2024-10-12 Linux 内核网络之 网络层发送消息:IP 分片
- 2024-10-12 如何利用eBPF程序监控Kubernetes 如何使用ebsco
- 2024-10-12 济南广播电视台4K IP HDR超高清电视转播车 应邀参加国际性体育赛事转播
- 2024-10-12 IP头情景分析 ip头部分析
- 2024-10-12 深入理解高性能网络开发路上的绊脚石 - 同步阻塞网络 IO
- 2024-10-12 Linux下AF-PACKET的V3版本 linux afs
- 2024-10-12 3000万像素与4K HDR视频?索尼A7 IV全幅微单最新消息汇总
- 2024-10-12 Linux 网络协议栈 linux网络协议栈是按照OSI网络模型实现的
- 2024-10-12 利用“socket”编程实现网络攻防 socket网络编程步骤
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)