原文地址:http://blog.csdn.net/eydwyz/article/details/52456335

----------原文如下----------------------------------------

iptables中ULOG和NFLOG实现分析

转载 2016年09月07日 09:00:41
  • 342
  • 0
  • 0

目录(?)[-]

本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。

E-mail: wwwlkk@126.com

来源: http://blog.csdn.net/wwwlkk

ULOG和NFLOG特点比较

1.都是使用netlink进行通信,ULOG使用NETLINK_NFLOG通信协议,而NFLOG使用NETLINK_NETFILTER通信协议。

2. ULOG只能从内核发送消息到用户空间,而NFLOG用户空间可以发送消息到内核。

3. NFLOG用户空间有libnfnetlink库的支持,而ULOG没有

4. ULOG消息编码固定,NFLOG消息编码使用属性,相对比较灵活。

5. ULOG的消息池的个数和属性都是固定,而NFLOG消息池是动态添加和撤销,并且属性可以设置。

6. 两个都是使用netlink进行通信,从性能方面看,两者应该差不多。

7. 但是NFLOG有一个特点,就是,消息池是动态建立和撤销的,如果nflog target指定的消息池不存在,则不会去创建消息,也不会去写入消息,避免做无用功。

8. NFLOG消息池是用户空间通过发送配置消息创建,用户空间如果关闭netlink socket,对应的消息池也会随之撤销。

9.NFLOG数据包是通过单播来发送数据包,也就是,只有创建消息池的进程才可以接收到数据包,

而ULOG是通过广播来发送数据包,一个消息池对应一个广播组,所有加入到某个广播组的接收进程都可以接收到这个广播中的数据包。

 

总的来说:ULOG通信是单向的,用户空间不能发送一些配置命令到内核,而NFLOG弥补了ULOG的不足,使得通信是双向的。

 

NFLOG特点及实现机制

1.      可以使用libnfnetlink提供的接口来发送和接收数据

2.      一个分组对应一个消息池,可以建立多个消息池,并可以设置消息池的属性,比较有用的属性有3个:

       NFULA_CFG_NLBUFSIZ  可以设置消息池的大小

       NFULA_CFG_TIMEOUT     设置消息池的刷新定时器时间间隔

       NFULA_CFG_QTHRESH  设置消息池允许存储的最大消息个数

说明:内核向用户空间发送数据有3个时机

(1)   消息池已满,先发送所有旧的消息,再写入新消息。

(2)   刷新定时器到期,发送所有消息。

(3)   消息池的消息个数大于允许的最大消息个数,发送所有旧消息,再写入新消息。

3.      消息的创建和撤销是由用户空间程序控制,用户空间通过发送配置消息到netlink子系统,创建消息池,并设置消息池的属性。

4.      用户空间关闭NFLOG子系统,对应的消息池也随之撤销,内核将不再写消息。

也就是说,用户空间的读取程序控制消息池的创建,撤销以及消息池的属性。

 

iptables中的NFLOG有以下4个属性:

--nflog-group NUM          标识消息写入哪个消息池,如果消息池不存在将不会写消息

--nflog-range NUM          消息中包含网络层数据最大长度,0表示将写入所有网络层数据

--nflog-threshold NUM    消息池消息个数等于大于NUM,刷新消息池。

--nflog-prefix STRING    本条消息的前缀

说明:消息池也有一个threshold属性,target中也有一个threshold属性,每次写入消息前,取两者最小的,然后判断是否刷新消息池。

注意:这里的group是选择消息池,nflog netlink消息是发送给创建这个消息池的进程,不是用广播包来发送,而ULOG是用广播包来发送消息。

 

iptables的默认属性: -j NFLOG –nflog-group 0 –nflog-threshold 1

图 1  nflog消息编码

图1说明:nflog是使用属性的名值对应来传递消息,可以通过添加属性来传递更多的消息,下图是2.6.33.2内核中nflog已有的属性:

图2 nflog属性列表

图2说明:其中nfulnl_attr_type是数据包的信息属性列表

nfulnl_attr_config是用于配置nflog消息池的属性列表

 

NFLOG消息发送流程:

当一个数据包满足了匹配条件,并开始执行NFLOG target时,需要根据nflog target的私有数据struct xt_nflog_info来构造要发送的消息,并使用xt_nflog_info中消息池编号指定的消息池发送消息,使用单播把数据包发送给创建本消息池的进程。

注意:如果消息池还未建立,将不会写入消息,也不会构造消息。

图3是消息池和xt_nflog_info结构

图3 消息池 和 NFLOG target私有数据结构

图3说明:如果指定的消息池不存在(使用分组编号定位一个消息池),将不写入消息,也不构造消息。消息池的建立和配置不是通过iptables进行,而是通过netlink传递配置消息到内核的nfnetlink子系统,nfnetlink子系统会根据消息的信息,来初始化一个消息池,图2中的nfulnl_attr_config属性列表就是用来建立和配置一个消息池。

 

这里就要涉及到nfnetlink子系统如何根据消息的类型,定位相应的处理函数,如图4《内核nfnetlink子系统结构》所示,是根据struct nlmsghdr {__u16   nlmsg_type;//前8位为子系统id号 //后8位为消息的类型};,找到相应的消息处理函数,最后根据属性列表执行相应的动作。

图4 内核nfnetlink子系统结构

 

图4说明的是内核nfnetlink子系统根据消息类型定位相应的处理函数。

内核发送消息到用户空间,用户空间可以通过libnfnetlink库函数来接收消息,和内核类似libnfnetlink库也是根据相同的字段来定位处理函数,如图5《用户空间libnfnetlink结构》所示。

图5 用户空间libnfnetlink结构

图5说明:一个回调函数对应一个消息类型。

 

这里说明的是nflog实现机制,事实上conntrack也是nfnetlink子系统的一部分,实现机制是一样的,libnetfilter_conntrack库就是在nfnetlink库的基础上进行扩展的,是否也有nflog对应的扩展库呢?如果没有也可以仿照libnetfilter_conntrack建立一个扩展库。

接下来说明ulog的实现机制,最后通过具体的例子程序来做最后的说明。

 

ULOG特点及实现机制

1.内核也是通过消息池来发送消息,但是不能接收消息,消息池是静态的,也就是说,消息池的个数和相应的属性是固定的,用户空间没法进行配置,

2.由于消息池总是存在的,只要执行ULOG目标,总会创建消息,并将消息写入消息池。

3.消息的格式是固定的,传出的是一个结构体,如图6所示。

4.用户空间没有对应的库函数支持。

 

说明:内核向用户空间发送数据有3个时机

(1)消息池已满,先发送所有旧的消息,再写入新消息。

(2)刷新定时器到期,发送所有消息。

(3)消息池的消息个数大于ipt_ulog_info中的qthreshold,发送所有旧消息,再写入新消息。

 

iptables中的ULOG有以下4个属性

--ulog-nlgroup nlgroup     选择哪个消息池发送消息,发送给编号和消息池编号相同的分组

--ulog-cprange size    截取网络层数据的最大长度

--ulog-qthreshold  当消息池中消息个数大于等于qthreshold,刷新消息池,然后再写入新消息。

--ulog-prefix prefix    消息的前缀

注意:nlgroup是消息池的编号,同样也是netlink分组编号,接收进城只有加入到这个分组才可以接收这个分组的广播包,具体的可以看ULOG例子程序中的说明。

 

iptables的默认属性: -j ULOG –ulog-group 1 –ulog-threshold 1

 

图6 ulog消息结构

 

ULOG消息发送流程:

当一个数据包满足了匹配条件,并开始执行ULOG target时,需要根据uflog target的私有数据struct ipt_uflog_info来构造要发送的消息,并使用ipt_uflog_info中消息池编号指定的消息池发送消息,使用和消息池编号相同的广播组发送广播包。

注意:消息池总是存在,也总会写入消息。

消息池的结构如图7《ulog消息池结构》所示。

图7 ulog消息池结构

 

 

NFLOG例子程序

1. 首先加载NFLOG target并建立NFLOG规则,如下:

iptables -A OUTPUT -p ICMP -d 192.168.190.2 -j NFLOG --nflog-group 112 --nflog-prefix "nflog-test."

规则说明:使用编号是112的消息池发送消息,消息的前缀是“nflog-test.”

现在消息池还未建立,内核还不会写入消息。

2. 使用libnfnetlink库函数提供的接口向内核发送配置命令,程序段如下:

cmd.command = NFULNL_CFG_CMD_BIND;

nfnl_fill_hdr(subh, &u.req.nlh, 0, AF_INET, 112, NFULNL_MSG_CONFIG, NLM_F_REQUEST);

nfnl_addattr_l(&u.req.nlh, sizeof(u), NFULA_CFG_CMD, &cmd, sizeof(cmd));

nfnl_addattr32(&u.req.nlh, sizeof(u), NFULA_CFG_QTHRESH, 10);

nfnl_addattr32(&u.req.nlh, sizeof(u), NFULA_CFG_TIMEOUT, htonl(400));

命令说明:

NFULNL_CFG_CMD_BIND:创建一个消息池

112是创建的消息池的编号

NFULA_CFG_QTHRESH:消息池最大消息个数 10。

NFULA_CFG_TIMEOUT:消息池定时器刷新时间,400*(1/100)=4秒。

 

运行截图如下:

注意:这里虽然设置消息的QTHRESH属性是10,但是NFLOG target的QTHRESH属性是1,

取其中最小的,所以QTHRESH属性是1.

 

ULOG例子程序

1. 首先加载ULOG target并建立ULOG规则,如下:

iptables -A OUTPUT -p ICMP -d 192.168.190.2 -j ULOG --ulog-nlgroup 6 --ulog-prefix "ulog-test."

说明:使用编号是6的消息池广播消息,所有属于广播6的接收进程都可以接收到消息,消息前缀是"ulog-test.",使用默认的最大消息个数1

现在只要有规则匹配,内核就会向消息池写入消息,并发送消息。

2. 其中用户空间消息接收程序,程序段如下:

group = 6;

sd = socket(AF_NETLINK, SOCK_RAW,NETLINK_NFLOG);

memset(&saddr, 0, sizeof(saddr));

memset(&daddr, 0, sizeof(daddr));

saddr.nl_family = AF_NETLINK;

saddr.nl_pid = getpid();

saddr.nl_groups = group;

bind(sd, (struct sockaddr*)&saddr, sizeof(saddr));

setsockopt(sd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));

说明:

AF_NETLINK和NETLINK_NFLOG是说接收netlink协议族中协议类型是NETLINK_NFLOG

的数据包。

saddr.nl_pid = getpid()是说,接收发给本进程的数据包。

saddr.nl_groups = 6是说,也接收广播组6的广播包。

Setsockopt是由于内核 2.6.14 对 netlink 套接字有新的实现,它缺省情况下不允许用户态应用发送给组号非 1 的netlink 组,因此用户态应用要想使用非1的组,必须先加入到该组,使用Setsockopt实现。

程序运行截图:

iptables中ULOG和NFLOG实现分析【转】的更多相关文章

  1. 详解Linux下iptables中的DNAT与SNAT设置(转)

    详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下   原文连 ...

  2. iptables中实现内外网互访,SNAT和DNAT

    目录 一.SNAT原理与应用 二.DNAT原理与应用 DNAT转换:发布内网web服务 DNAT转换:发布时修改目标端口 三.防火墙规则的备份和还原 四.linux抓包 一.SNAT原理与应用 ① S ...

  3. 电商系统中的商品模型的分析与设计—续

    前言     在<电商系统中的商品模型的分析与设计>中,对电商系统商品模型有一个粗浅的描述,后来有博友对货品和商品的区别以及属性有一些疑问.我也对此做一些研究,再次简单的对商品模型做一个介 ...

  4. [转]IPTABLES中SNAT和MASQUERADE的区别

    IPtables中可以灵活的做各种网络地址转换(NAT)网络地址转换主要有两种:SNAT和DNAT SNAT是source network address translation的缩写即源地址目标转换 ...

  5. AX中四种库存ABC分析法原理研究

    库存ABC分类,简单的说就是抓大放小,是为了让我们抓住重点,用最大精力来管理最重要的物料,而对于不太重要的物料则可以用较少的精力进行管理.它和我们平常说的八二法则有异曲同工之妙. 既然要应用库存ABC ...

  6. SQL中的Null深入研究分析

    SQL中的Null深入研究分析 虽然熟练掌握SQL的人对于Null不会有什么疑问,但总结得很全的文章还是很难找,看到一篇英文版的, 感觉还不错. Tony Hoare 在1965年发明了 null 引 ...

  7. try-catch-finally中return的执行情况分析

    try-catch-finally中return的执行情况分析: 1.在try中没有异常的情况下try.catch.finally的执行顺序 try --- finally 2.如果try中有异常,执 ...

  8. iptables中DNAT、SNAT和MASQUERADE的理解

    转:http://blog.csdn.net/yu_xiang/article/details/9212543 DNAT(Destination Network Address Translation ...

  9. Java EE中的容器和注入分析,历史与未来

    Java EE中的容器和注入分析,历史与未来 java中的容器 java中的注入 容器和注入的历史和展望 一.java中的容器 java EE中的注入,使我们定义的对象能够获取对资源和其他依赖项的引用 ...

随机推荐

  1. Spark的动态资源分配

    跑spark程序的时候,公司服务器需要排队等资源,参考一些设置,之前不知道,跑的很慢,懂得设置之后简直直接起飞. 简单粗暴上设置代码: def conf(self): conf = super(Tbt ...

  2. unity3d内存管理坑爹之处

    Resources.UnloadUnusedAssets();会卸载没有引用的资源,切场景也会自动清理 但是注意,如果不调,是不会自动清理的,比如不断的用www加载图片资源,即使没有引用,也一样在内存 ...

  3. (转)[Unity3D]BuildPipeline.PushAssetDependencies 打包依赖包,优化UI Prefab的资源引用加载(坑爹之处)

    转自:http://blog.csdn.net/chiuan/article/details/39040421#reply 1:长话短说,UI Prefab中一般会交叉引用Atlas,那么打包时候我们 ...

  4. (转)Unity3D研究院之Assetbundle的原理(六十一)

    Assetbundle 是Unity Pro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利. 1.预设          A ...

  5. Docker for windows可用性检查

    Docker for windows不太稳定,每次启动机器后, 等待Docker启动起来后,要进行如下的检查: Docker启动看,看看图标是否正常,如果是红色,或者报错就是有问题. 打开Hyper- ...

  6. Eclipse使用hibernate插件

    首先安装好hibernate插件,进入安装界面,输入下载地址http://download.jboss.org/jbosside/updates/stable,点击下载javaee web 以下的hi ...

  7. Android 开源项目 eoe 社区 Android 客户端

    本文内容 环境 开源项目 eoe 社区 Android 客户端 本文介绍 eoe 社区 Android 客户端.它是一个开源项目,功能相对简单,采用侧边菜单栏.可以学习一下.点击此处查看 GitHub ...

  8. MySQL 存储过程/游标/事务

    将会用到的几个表 mysql> DESC products; +------------+--------------+------+-----+---------+-------------- ...

  9. JERSEY中文翻译(第三章、模块和依赖)

    Chapter 2 Modules and Dependencencies 2.1 Java SE 兼容 所有的Jersey组建都是基于Java6开发的,所以你的Java必须是Java6以上的版本才能 ...

  10. tornado输出json

    只需要输出一个dict就自动会变成json http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.write