ip6tables中nflog的使用

一、前言
    iptables中有個非常有用的功能:log。通過log我們可以在內核特定位置抓取我們想要的數據包,之後由用戶層的程序接收數據包的log並做相應處理。iptables中的log target主要有以下三種:
    1、log
    log target會把匹配到的數據包的部分信息輸出到dmesg和syslogd中,之後用戶可以直接用dmesg或者到log文件中查看,屬於比較簡單的log方式。這種方式至多記錄數據包的頭部信息。
    2、ulog
    ulog target會把匹配的數據包以netlink廣播的形式廣播到制定netlink組。用戶可以自己編寫neilink接收程序或者使用ulogd軟件接收數據包。ulog功能要比log強大的多,可以獲取數據包任意範圍的數據。具體的ulog使用可以參見我寫的另一篇文章:http://blog.csdn.net/l1902090/article/details/25911877
    3、nflog
    其實對於抓取數據包來講,ulog已經夠用了,但是可惜的是ip6tables(iptables的ipv6版本)不支持ulog,而僅僅支持nflog,所以要抓取ipv6數據包就只能用nflog了。nflog比ulog功能要更加強大,ulog有的功能nflog全都有。下面就詳細介紹下如何利用nflog抓取ipv6數據包。
二、ip6tables中nflog target的使用
    要想抓取數據包,最先要做的就是添加iptables規則。例如:
        ip6tables -A INPUT -p TCP --dport 22 -j NFLOG --nflog-group 2 --nflog-prefix "test" --nflog-range 100
    上面的規則實現在INPUT鏈中將所有tcp協議端口號爲22的數據包的前100字節發送到組號爲2的netlink組中,prefix "test" 則是指爲log添加“test”前綴,以幫助我們分析。
三、nflog用戶層接收程序的編寫
    添加完規則後,iptables就會不停地將符合規則的數據包發送到netlink組了。但是我們還需要一個用戶層程序來接收數據包。
    編寫nflog接收程序最簡單的方式就是使用libnetfilter_log庫,這個庫中封裝了很多簡單易用的函數供我們使用。如果你還沒有這個庫,可以直接使用yum install安裝。下面通過一個簡單的例子介紹nflog程序的編寫:
//這個頭文件包含了libnetfilter_log需要的宏和函數定義
#include <libnetfilter_log/libnetfilter_log.h>
//首先是三個非常重要的數據結構
static int lb_nflog_fd;
static struct nflog_handle *handle;
static struct nflog_g_handle *group_handle;
//然後是nflog的初始化
handle = nflog_open();//打開一個nflog
nflog_bind_pf(handle,AF_INET6);//綁定地址族
group_handle = nflog_bind_group(handle, group);//綁定netlink組
nflog_set_mode(group_handle, NFULNL_COPY_PACKET, LOG_CP_RANGE) ;//設置拷貝的數據包範圍
nflog_set_qthresh(group_handle,1); //設置數據包緩存數量,即內核會湊齊這個數量的數據包後再講數據包發送到用戶層程序
nflog_callback_register(group_handle, &handle_packet, NULL); //設置回調函數,當收到數據包後會直接調用handle_packet函數對數據包進行處理,如果一次接收了多條數據包log,那麼回調函數會被調用多次
lb_nflog_fd = nflog_fd(handle);//獲取接收nflog的文件描述符
//然後是nflog的接收
 char buf[MAX_MSG_SIZE];//設置接收緩衝區
 res = recv(lb_nflog_fd, buf, sizeof(buf), 0);//接收一組數據包,數據存儲在buf中,返回接收到的數據長度
 nflog_handle_packet(handle, buf, res);// 由回調函數處理這組數據包
//回調函數的編寫
static int
handle_packet(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg,struct nflog_data *nfa, void *data)
//注意上邊的函數定義是定死的
{
nflog_get_nfmark(nfa);//獲取數據包的元數據,這裏是mark值,還能獲取時間戳、接口等信息,在此不再敖述,感興趣的可以自己去看頭文件
char *payload;
nflog_get_payload(nfa, &payload);//獲取數據包的載荷,也就是真正的IP數據包了
//獲取的載荷指針存儲在payload,在這之後我們就可以通過payload指針對數據包進行分析了。例如:struct //ip6_hdr *ip6h=(struct ip6_hdr *)payload;獲取ipv6頭
……
}
四、總結
    可以看到,iptables中nflog使用的難點在於接收程序的編寫,但是通過libnetfilter_log庫編寫這個接收程序也不難。

發佈了47 篇原創文章 · 獲贊 20 · 訪問量 108萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章