小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

綠盟科技--www.nsfocus.com--綠盟月刊

 昵稱575 2005-07-29
作者:林風(fēng)<droplet@163.net>
出處:http://www.
日期:2003-07-02

本文是上一篇文章《LINUX2.4.x網(wǎng)絡(luò)安全框架》的后續(xù)文章,主要分析連接跟蹤和地址轉(zhuǎn)換在LINUX2.4.x中的實現(xiàn),本文引用代碼是LINUX2.4.20。

1.      概述

在上一篇文章中我們提到LINUX2.4.x的網(wǎng)絡(luò)安全實現(xiàn)較之LINUX2.2.x有了很大的改進,其中的兩個重要改進一是增加了連接跟蹤的功能,二是增強了地址轉(zhuǎn)換功能的實現(xiàn)。由于地址轉(zhuǎn)換功能是在連接跟蹤的基礎(chǔ)上實現(xiàn)的,所以把這兩個模塊放在一起來分析。

連接跟蹤(CONNTRACK),顧名思義,就是跟蹤并且記錄連接狀態(tài)。這里的連接并不僅僅指TCP連接,它也包括UDP、ICMP等協(xié)議的虛擬連接。連接跟蹤是實現(xiàn)地址轉(zhuǎn)換的基礎(chǔ),在使用地址轉(zhuǎn)換功能時必須加載這個模塊。

增強的地址轉(zhuǎn)換實現(xiàn)了一個全功能的地址轉(zhuǎn)換模塊。在LINUX2.2.x中只有地址偽裝和透明代理,目的轉(zhuǎn)換還是在地址偽裝基礎(chǔ)上實現(xiàn)的。在LINUX2.4.x中,源轉(zhuǎn)換(SNAT)包括了地址偽裝和源地址轉(zhuǎn)換,目的轉(zhuǎn)換(DNAT)包括了透明代理和目的地址轉(zhuǎn)換,并且這些功能是在同一個框架下實現(xiàn)的,代碼結(jié)構(gòu)比以前清晰,可擴展性更強。

2.      檢查點以及檢查點上的函數(shù)

先來看看連接跟蹤和地址轉(zhuǎn)換在檢查點上注冊了相應(yīng)的結(jié)構(gòu),如圖:



[圖1.1  IPV4的功能點在各檢查點上注冊的結(jié)構(gòu)]

在圖中,我們可以看到不同的數(shù)據(jù)包所要經(jīng)過的三條路徑:

·發(fā)往本機上層的包:經(jīng)過的檢查點是NF_IP_PRE_ROUTING,NF_IP_LOCAL_IN。
·由本機轉(zhuǎn)發(fā)的包:經(jīng)過的檢查點是NF_IP_PRE_ROUTING,NF_IP_FORWARD,NF_IP_POST_ROUTING。
·從本機發(fā)出的包:NF_IP_LOCAL_OUT,NF_IP_POST_ROUTING。

在每一條路徑上,連接跟蹤和地址轉(zhuǎn)換都注冊了相應(yīng)的函數(shù),并創(chuàng)建與之相關(guān)的數(shù)據(jù)結(jié)構(gòu),完成其功能。每條路徑上功能點的順序如圖所示:



[圖1.2 路徑上功能點的順序]

在這個圖中,CONNTRACK代表連接跟蹤,DNAT代表目的轉(zhuǎn)換,SNAT代表源轉(zhuǎn)換,F(xiàn)ILTER代表包過慮。可以看到,CONNTRACK在路徑上出現(xiàn)了兩次,其作用是:第一個點上它創(chuàng)建連接跟蹤的結(jié)構(gòu),這個結(jié)構(gòu)會在后面的地址轉(zhuǎn)換和包過濾中被使用,在第二個點上它將連接跟蹤的結(jié)構(gòu)加到系統(tǒng)的連接表中。

檢查點上注冊的函數(shù)如下圖所示:



[圖1.3 連接跟蹤和地址轉(zhuǎn)換在檢查點上調(diào)用的函數(shù)]

圖中用粗體字標(biāo)識連接跟蹤的函數(shù),用斜體字標(biāo)識地址轉(zhuǎn)換的函數(shù),括號里面的函數(shù)名是實際調(diào)用的函數(shù)的名稱。這些函數(shù)在檢查點上被調(diào)用。下面將分析這些函數(shù)的實現(xiàn)以及其中所涉及的重要數(shù)據(jù)結(jié)構(gòu)和過程。

3.      連接跟蹤的重要數(shù)據(jù)結(jié)構(gòu)和過程

連接跟蹤記錄連接的狀態(tài),并且實現(xiàn)狀態(tài)間的轉(zhuǎn)換。連接并不只是指TCP協(xié)議連接,它也包括UDP協(xié)議和ICMP協(xié)議。當(dāng)然這只是內(nèi)核的標(biāo)準(zhǔn)實現(xiàn)中包含的協(xié)議,其他協(xié)議的連接跟蹤可以自己添加到內(nèi)核中。連接的數(shù)據(jù)結(jié)構(gòu)如下:

struct ip_conntrack
{
            struct nf_conntrack ct_general;  /* 結(jié)構(gòu)的引用計數(shù) */
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; /* 不同方向上的計算哈希值的參數(shù)*/
            volatile unsigned long status;                  /* 結(jié)構(gòu)的狀態(tài) */
            struct timer_list timeout;
            struct list_head sibling_list;                    /* 與此結(jié)構(gòu)關(guān)聯(lián)的expect鏈表*/
            unsigned int expecting;              /* 與此結(jié)構(gòu)關(guān)聯(lián)的expect的數(shù)量*/
            struct ip_conntrack_expect *master;     /* 指向創(chuàng)建此結(jié)構(gòu)的expect */
            struct ip_conntrack_helper *helper;       /* 與此結(jié)構(gòu)關(guān)聯(lián)的helper */
            struct nf_ct_info infos[IP_CT_NUMBER];       /* 不同狀態(tài)下由skb引用 */
            union ip_conntrack_proto proto;
            union ip_conntrack_help help;
            struct {
                        struct ip_nat_info info;  
                        union ip_conntrack_nat_help help;
                        int masq_index;
            } nat;                                                    /* 與地址轉(zhuǎn)換相關(guān)的結(jié)構(gòu) */
};

在這個結(jié)構(gòu)中tuplehash[]記錄了此連接的正反兩個方向包的參數(shù),這些參數(shù)包括協(xié)議、源地址/源端口、目的地址/目的端口等,如果沒有端口,比如ICMP協(xié)議,就用它的id,type,code等代替。每個連接都根據(jù)這些參數(shù)計算哈希值并連接到一個全局的哈希表中。連接是雙向的,所以每個連接在哈希表中出現(xiàn)兩次,匹配連接和應(yīng)答兩個方向上的包。

前面說到,對不同協(xié)議,連接跟蹤記錄的參數(shù)不同,所以不同的協(xié)議定義了不同的 ip_conntrack_protocol結(jié)構(gòu)來處理與協(xié)議相關(guān)的內(nèi)容。這些結(jié)構(gòu)被注冊到一個全局的鏈表中,在使用時根據(jù)協(xié)議去查找,并調(diào)用相應(yīng)的處理函數(shù)來完成相應(yīng)的動作。下面將要講到的ip_nat_protocol的作用與此類似,它處理的是與協(xié)議相關(guān)的地址轉(zhuǎn)換方面的內(nèi)容。

不同協(xié)議連接跟蹤的過程不同。

TCP的連接跟蹤可以用下面的表來說明:(假設(shè)是A到B的TCP連接)

發(fā)包的方向    標(biāo)志位   連接狀態(tài)           說明
A--> B        SYN      IP_CT_NEW          A發(fā)起連接
B-->A         SYN/ACK  IP_CT_ESTABLISHED  B響應(yīng)A的連接請求
                       + IP_CT_IS_REPLY
A-->B         ACK      IP_CT_ESTABLISHED  A確認(rèn)B的響應(yīng)

[表2.1 TCP建立連接的狀態(tài)變遷]

這個表說明的是創(chuàng)建TCP連接所經(jīng)歷的狀態(tài)變遷。表中沒有顯示刪除TCP連接所經(jīng)歷的狀態(tài),這是因為刪除TCP連接是通過超時執(zhí)行的,任何狀態(tài)下都可以刪除連接,所以并不需要額外的狀態(tài)變遷。

對TCP連接,還有一個TCP的狀態(tài)變遷。它和連接的狀態(tài)不同,它記錄了TCP協(xié)議的狀態(tài)轉(zhuǎn)換,其中涉及更多與TCP連接相關(guān)的狀態(tài)。并且超時也是在這個狀態(tài)基礎(chǔ)上賦值的。具體的實現(xiàn)可以參考源代碼。

除了上面列出的狀態(tài)外,還有一個重要的狀態(tài)IP_CT_RELATED。這個狀態(tài)用于創(chuàng)建動態(tài)連接時使用。動態(tài)連接有兩類,一是處理使用了動態(tài)地址或端口的應(yīng)用協(xié)議;二是針對TCP、UDP、ICMP等協(xié)議的ICMP差錯報文。動態(tài)連接與原連接相關(guān),所以用了一個特殊的狀態(tài)來標(biāo)識它們。

UDP的連接跟蹤可以用下面的表來說明:

發(fā)包的方向  連接狀態(tài)            說明
A-->B       IP_CT_NEW           A到B的UPD包
B-->A       IP_CT_ESTABLISHED   B到A的UDP包(端口與A到B的包相反)
            + IP_CT_IS_REPLY

[表2.2 UDP的狀態(tài)變遷]

UDP本來是一個無狀態(tài)的協(xié)議,連接跟蹤記錄的的是兩個方向上的UDP包,并且不同狀態(tài)下,連接的超時值不同。

ICMP的連接跟蹤可以用下面的表來說明:

發(fā)包的方向    連接狀態(tài)           說明
A-->B         IP_CT_NEW          A到B的ICMP查詢包
B-->A         IP_CT_ESTABLISHED  B到A的對ICMP查詢包的應(yīng)答包
              + IP_CT_IS_REPLY

[表2.3 ICMP的狀態(tài)變遷]

ICMP協(xié)議也是一個無狀態(tài)的協(xié)議,連接跟蹤記錄的是ICMP的查詢包和查詢應(yīng)答包,只有在記錄了查詢包的情況下才允許相應(yīng)的應(yīng)答包通過。

為了處理應(yīng)用協(xié)議里面的動態(tài)地址和端口,每個使用動態(tài)地址和端口的協(xié)議一般都定義了數(shù)據(jù)結(jié)構(gòu)ip_conntrack_helper,并把它放到一個全局的鏈表中。這類協(xié)議一般都會有控制連接和數(shù)據(jù)連接兩個不同的連接,如FTP協(xié)議。而在這個結(jié)構(gòu)中定義了匹配其協(xié)議控制連接的參數(shù),當(dāng)創(chuàng)建或更新結(jié)構(gòu)ip_conntrack時都會查找鏈表中有沒有相應(yīng)的ip_connctrack_helper結(jié)構(gòu),如果存在,就把它的指針賦給ip_conntrack里面的helper。ip_conntrack_helper里面的函數(shù)會根據(jù)協(xié)議里的地址和端口創(chuàng)建與控制連接相關(guān)的結(jié)構(gòu)ip_conntrack_expect,并且在有應(yīng)答時根據(jù)ip_conntrack_expect得到相應(yīng)數(shù)據(jù)連接的參數(shù)。ip_conntrack與ip_conntrack_expect的關(guān)系可以用下圖來表示:



[2.1 ip_conntrack和ip_conntrack_expect的關(guān)系]

在helper里并沒有直接創(chuàng)建ip_conntrack結(jié)構(gòu),而是創(chuàng)建了一個過渡的結(jié)構(gòu)ip_conntrack_expect,并把它放到了一個全局的鏈表中。接著,當(dāng)建立數(shù)據(jù)連接時,再找到這個ip_conntrack_expect結(jié)構(gòu),并把它與新建的ip_conntrack結(jié)構(gòu)連接起來。

連接跟蹤主要在ip_conntrack_in和ip_confirm這兩個函數(shù)里實現(xiàn)。在ip_conntrack_in里面創(chuàng)建ip_conntrack結(jié)構(gòu)。接下來,地址轉(zhuǎn)換改動數(shù)據(jù)包里的地址,包過濾會禁止包通過。如果這個包能夠到達ip_confirm,由它把相應(yīng)的ip_conntrack結(jié)構(gòu)加到系統(tǒng)的哈希表中。ip_conntrack_in函數(shù)在文件ip_conntrack_core.c中,下面是它的一個修改后的版本,每行前的行號與原文件里的行號相同。

unsigned int ip_conntrack_in
{
804      (*pskb)->nfcache |= NFC_UNKNOWN;
823      if ((*pskb)->nfct)
824                  return NF_ACCEPT;
指針pskb指向傳入函數(shù)的數(shù)據(jù)包,第804行設(shè)置這個數(shù)據(jù)包的標(biāo)記為NFC_UNKNOWN,說明它沒有被修改過。同類的標(biāo)記還有NFC_ALTERED,用于說明這個數(shù)據(jù)包已被修改過。在連接跟蹤里不會修改數(shù)據(jù)包的任何參數(shù),所以把它的標(biāo)記置為NFC_UNKNOWN。第823行檢查這個數(shù)據(jù)包是否已被檢查過了,因為已檢查過的數(shù)據(jù)包它的nfct成員指向它所屬的ip_conntrack結(jié)構(gòu)里的infos[]中的某一成員,以說明這個數(shù)據(jù)包是此連接的哪個狀態(tài)下收到的包。
827      if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
828                  *pskb = ip_ct_gather_frags(*pskb);
829                  if (!*pskb)
830                              return NF_STOLEN;
831      }
第827-831行進行分片重組。在LINUX2.4.x網(wǎng)絡(luò)安全的實現(xiàn)中,分片重組是自動進行的,并不需要打開像LINUX2.2.x中ip_always_defrag那樣的開關(guān)。
833      proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
836      if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP
837          && icmp_error_track(*pskb, &ctinfo, hooknum))
838                  return NF_ACCEPT;
第833-838行找到與數(shù)據(jù)包協(xié)議相同的ip_conntrack_protocol結(jié)構(gòu),并且如果協(xié)議是ICMP則調(diào)用icmp_error_track做特殊處理。
840      if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo)))
841                  return NF_ACCEPT;
850      ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo);
851      if (ret == -1) {
853                  nf_conntrack_put((*pskb)->nfct);
854                  (*pskb)->nfct = NULL;
855                  return NF_ACCEPT;
856      }
第840-856行根據(jù)數(shù)據(jù)包中的參數(shù)在全局的連接表中查找與此包匹配的連接結(jié)構(gòu)。前面說過,連接結(jié)構(gòu)在連接表中出現(xiàn)兩次,代表連接的兩個方向。如果沒有找到相應(yīng)的連接,則創(chuàng)建新的連接。新的連接創(chuàng)建之后,需要查找ip_conntrack_expect_list看看是否這個連接是與控制連接相關(guān)的數(shù)據(jù)連接。同時還要查找ip_conntrack_helper的鏈表,看看此連接是否有與之關(guān)聯(lián)的ip_conntrack_helper結(jié)構(gòu)。
858      if (ret != NF_DROP && ct->helper) {
859                  ret = ct->helper->help((*pskb)->nh.iph, (*pskb)->len, ct, ctinfo);
861                  if (ret == -1) {
863                              nf_conntrack_put((*pskb)->nfct);
864                              (*pskb)->nfct = NULL;
865                              return NF_ACCEPT;
866                  }
867      }
第858-867行調(diào)用與連接關(guān)聯(lián)的ip_conntrack_helper中的函數(shù)處理協(xié)議中的動態(tài)地址和端口。
ip_confirm函數(shù)實際調(diào)用的是函數(shù)__ip_conntrack_confirm,在調(diào)用之前它會先確認(rèn)相關(guān)連接是否已經(jīng)在全局的哈希表中,如果已經(jīng)在了,就返回。__ip_conntrack_confirm函數(shù)在文件ip_conntrack_core.c中,下面是它的一個修改過的版本,每行前的行號是原文件中的行號。
int__ip_conntrack_confirm(struct nf_ct_info *nfct)
{
426      ct = __ip_conntrack_get(nfct, &ctinfo);
432      if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
433                  return NF_ACCEPT;
第426行從數(shù)據(jù)包的nfct變量中得到它所屬的ip_conntrack結(jié)構(gòu),第432行檢查此時的連接狀態(tài)是否是IP_CT_DIR_ORIGINAL方向,也就是創(chuàng)建此連接包的方向上的狀態(tài),如果不是,返回。
435      hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
436      repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
第435-436行計算兩個方向上的哈希值。
448      WRITE_LOCK(&ip_conntrack_lock);
452      if (!LIST_FIND(&ip_conntrack_hash[hash],
                               conntrack_tuple_cmp,
                               struct ip_conntrack_tuple_hash *,
                               &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL)
456          && !LIST_FIND(&ip_conntrack_hash[repl_hash],
                                      conntrack_tuple_cmp,
                                      struct ip_conntrack_tuple_hash *,
                                      &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
460                  list_prepend(&ip_conntrack_hash[hash],
                                         &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
462                  list_prepend(&ip_conntrack_hash[repl_hash],
                                         &ct->tuplehash[IP_CT_DIR_REPLY]);
470                  WRITE_UNLOCK(&ip_conntrack_lock);
471                  return NF_ACCEPT;
472      }
474      WRITE_UNLOCK(&ip_conntrack_lock);
475      return NF_DROP;
}

第448-475行將連接加到全局的哈希表中。在加入之前,先要確認(rèn)它不在哈希表中,而且要把表鎖住,禁止其他內(nèi)核路徑讀或?qū)懝1?。如果加入成功,則返回NF_ACCEPT,如果不成功,則返回NF_DROP。

4.      地址轉(zhuǎn)換的重要數(shù)據(jù)結(jié)構(gòu)和過程

地址轉(zhuǎn)換與連接跟蹤緊密相關(guān)。事實上,與地址轉(zhuǎn)換相關(guān)的數(shù)據(jù)也就放在ip_conntrack結(jié)構(gòu)里面,它的內(nèi)容如下:

struct ip_nat_info
{
            int initialized;
            unsigned int num_manips;                      /* 需要改動的tuple的個數(shù) */
struct ip_nat_info_manip manips[IP_NAT_MAX_MANIPS];   /* 在不同檢查點上修改后的地址和端口*/
            const struct ip_nat_mapping_type *mtype;        /* 地址轉(zhuǎn)換的類型 */
            struct ip_nat_hash bysource, byipsproto;           /* 鏈接到哈希表 */
            struct ip_nat_helper *helper;                 /* 與此相關(guān)的helper */
            struct ip_nat_seq seq[IP_CT_DIR_MAX];
};

結(jié)構(gòu)中manips[]保存的是修改后的地址和端口(這與協(xié)議有關(guān),比如說ICMP協(xié)議里面修改可能是id,type,code等。前面提到的ip_nat_protocol結(jié)構(gòu)就是處理與協(xié)議相關(guān)的參數(shù)的),這些地址用來替代原包中的地址或端口。

bysource,byipsproto兩個成員把它所在ip_conntrack鏈接到兩個哈希表中。這兩個哈希表,一個用于源地址轉(zhuǎn)換,一個用于目的地址轉(zhuǎn)換。

如前所述,ip_nat_helper處理應(yīng)用協(xié)議里的動態(tài)地址和端口,這個helper與前面提到的ip_conntrack_helper是配合起來使用的。ip_conntrack_helper創(chuàng)建與ip_conntrack相關(guān)的ip_conntrack_expect結(jié)構(gòu),然后再由ip_conntrack_helper修改其中的地址和端口。

完成地址轉(zhuǎn)換的主要函數(shù)是ip_nat_fn。在這個函數(shù)里,根據(jù)manips[]的信息修改包的地址或端口。manips[]里面的參數(shù)的填充主要來自兩個方面:一是匹配相應(yīng)的地址轉(zhuǎn)換規(guī)則(由ip_nat_rule_find查找),匹配到相應(yīng)的規(guī)則后,規(guī)則里的TARGET會將相應(yīng)的信息填充到manips[]中;還有一個就是由ip_conntrack_helper創(chuàng)建ip_conntrack結(jié)構(gòu),它的完整信息由ip_nat_helper里的expect函數(shù)填充。填充ip_nat_info里參數(shù)的函數(shù)是ip_nat_setup_info,在這個函數(shù)里為ip_nat_info選擇唯一的地址和端口,如果有多個可選地址,還可以做簡單的負(fù)載均衡。

ip_nat_fn函數(shù)在文件ip_nat_standalone.c中,下面是它的一個修改過的版本。

ip_nat_fn
{
79        (*pskb)->nfcache |= NFC_UNKNOWN;
85        ct = ip_conntrack_get(*pskb, &ctinfo);
第79行設(shè)置skb的標(biāo)志,這個標(biāo)志是暫時的,因為地址轉(zhuǎn)換要修改數(shù)據(jù)包里的參數(shù),所以在改動之后,這個標(biāo)志會設(shè)置為NFC_ALTERED。第85行是得到與此包關(guān)聯(lián)的ip_contrack結(jié)構(gòu)。
103      switch (ctinfo) {
111      case IP_CT_NEW:
118                  info = &ct->nat.info;
120                  WRITE_LOCK(&ip_nat_lock);
123                  if (!(info->initialized & (1 << maniptype))) {
127                              if (ct->master
                                        && master_ct(ct)->nat.info.helper
                                        && master_ct(ct)->nat.info.helper->expect) {
130                                          ret = call_expect(master_ct(ct), pskb,
                                                                          hooknum, ct, info);
132                              } else {
133                                          ret = ip_nat_rule_find(pskb, hooknum, in, out,
                                                                               ct, info);
135                              }
第103-135行填充ip_nat_info結(jié)構(gòu),這里有兩種情況。對創(chuàng)建ip_conntrack結(jié)構(gòu)的包,因為是它的ip_nat_info結(jié)構(gòu)還沒有初始化,所以調(diào)用ip_nat_rule_find去查找相應(yīng)的地址轉(zhuǎn)換規(guī)則,這個函數(shù)又會調(diào)用ipt_do_table函數(shù)。如果這個ip_conntrack結(jié)構(gòu)是由ip_conntrack_helper創(chuàng)建的,則調(diào)用它的控制連接的ip_nat_helper中的expect函數(shù)填充數(shù)據(jù)連接中ip_nat_info中的參數(shù)。如果相應(yīng)的ip_nat_info結(jié)構(gòu)已經(jīng)填充過了,則跳過這部分處理。
142                              if (in_hashes) {
144                                          replace_in_hashes(ct, info);
145                              } else {
146                                          place_in_hashes(ct, info);
147                              }
148                  }
152                  WRITE_UNLOCK(&ip_nat_lock);
第142-152行根據(jù)新的地址和端口將ip_conntrack放到全局的哈希表中,或者從哈希表中將使用舊參數(shù)的ip_conntrack取下來,并使用新的參數(shù)把它重新放到哈希表中。
163      return do_bindings(ct, ctinfo, info, hooknum, pskb);
第163行的do_bindings函數(shù)完成數(shù)據(jù)包的修改,并且如果ip_conntrack上有與之相關(guān)的ip_nat_helper,則調(diào)用的help函數(shù)處理應(yīng)用協(xié)議里的數(shù)據(jù)。

5.      連接跟蹤、地址轉(zhuǎn)換與包過濾的關(guān)系

LINUX2.4.x中的連接跟蹤和包過濾是兩個獨立的功能。連接跟蹤創(chuàng)建的連接結(jié)構(gòu)并不作為允許或禁止包通過的依據(jù),只是在包過濾中可以匹配連接跟蹤里面的狀態(tài),進而決定允許或禁止包通過。這一點與一般意義上的狀態(tài)檢測不同。在狀態(tài)檢測里面,如果有相應(yīng)的連接存在,就不檢查過濾規(guī)則,只進行相應(yīng)的狀態(tài)變遷。在LINUX2.4.x中,不管連接跟蹤的狀態(tài)如何,都要去檢查過濾規(guī)則才能決定是否允許包通過。其檢查效率要差一些。

從前面的檢查點的順序圖可以看出,包過濾是在目的轉(zhuǎn)換之后,源轉(zhuǎn)換之前進行的,所以在添加過濾規(guī)則時,規(guī)則中的目的地址要用轉(zhuǎn)換后的地址,也就是數(shù)據(jù)包真正的目的地,而不是包中原來地目的地址。

6.      小結(jié)

以上是對LINUX2.4.x中連接跟蹤和地址轉(zhuǎn)換實現(xiàn)的簡單分析。在分析中我們可以看到,在這個實現(xiàn)里面,有許多可以擴展的東西:如ip_conntrack_protocol,ip_nat_protocol,ip_conntrack_helper,ip_nat_helper等。加上上一篇介紹的ipt_table,ipt_match,ipt_target,nf_hook_ops等。LINUX2.4.x網(wǎng)絡(luò)安全的實現(xiàn)就是建立在這些可擴展結(jié)構(gòu)的基礎(chǔ)之上,所以它有很好的可擴展性。并且,針對不同的協(xié)議定義的不同的結(jié)構(gòu)處理與協(xié)議相關(guān)的信息,使得信息隱蔽性好,模塊化增強。這正是一個出色的框架所具備的特點。不過它并沒有實現(xiàn)真正意義上的狀態(tài)檢測,而且它的包過濾的效率也有待改進。


參考資料:

1:LINUX2.4.20內(nèi)核源代碼

2:Netfilter Hacking HOWTO

2: iptables tutorial by Oskar Andreasson

3:Iptables connection tracking by James C. Stephens.



作者簡介:

      林風(fēng),獨立撰稿人。熟悉LINUX網(wǎng)絡(luò)安全技術(shù)。比較感興趣的方向是網(wǎng)絡(luò)協(xié)議棧的實現(xiàn)。寫文章,是為整理思路,發(fā)現(xiàn)問題,與更多人分享經(jīng)驗,知識,或者教訓(xùn)。郵件地址是droplet@163.net,歡迎批評,鼓勵或指正。



    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多