動態協議跟蹤機制的思考

來源:互聯網
上載者:User

                     動態協議跟蹤機制

例如ftp這種動態協議會通過一個控制串連來建立另一個關聯串連,而linux作業系統的本身實現上,並沒有非常靈活的實現這一點。代碼如下所示:

  1. static struct ip_conntrack_helper ftp[MAX_PORTS];
  2. static int __init init(void)
  3. {
  4.     int i, ret;
  5.     char *tmpname;
  6.     if (ports[0] == 0)
  7.         ports[0] = FTP_PORT;
  8.     //MAX_PORTS為8,也就是當載入模組時,必須要指定源端連接埠
  9.     for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
  10.         ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
  11.         ftp[i].tuple.dst.protonum = IPPROTO_TCP;
  12.         ftp[i].mask.src.u.tcp.port = 0xFFFF;
  13.         ftp[i].mask.dst.protonum = 0xFFFF;
  14.         ftp[i].max_expected = 1;
  15.         ftp[i].timeout = 0;
  16.         ftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
  17.         ftp[i].me = ip_conntrack_ftp;
  18.         ftp[i].help = help;
  19.         tmpname = &ftp_names[i][0];
  20.         if (ports[i] == FTP_PORT)
  21.             sprintf(tmpname, "ftp");
  22.         else
  23.             sprintf(tmpname, "ftp-%d", ports[i]);
  24.         ftp[i].name = tmpname;
  25.         DEBUGP("ip_ct_ftp: registering helper for port %d/n", 
  26.                 ports[i]);
  27.         //註冊ip_conntrack_helper
  28.         ret = ip_conntrack_helper_register(&ftp[i]);
  29.         if (ret) {
  30.             fini();
  31.             return ret;
  32.         }
  33.         ports_c++;
  34.     }
  35.     return 0;
  36. }

 

這種情況下,當FTP使用大量的非標準連接埠,主串連則無法正常記錄對應的相關串連。因此這裡有一個變通的做法,讓所有的ftp主串連都找不到相關串連,將一個helper_binding函數註冊到應用識別(一個根據資料包內容來判斷串連種類的模組)上,當應用識別識別出當前的串連為ftp串連時,則調用helper_binding通過名字尋找再將ftp的這個ip_conntrack_helper和這個主串連關聯起來。

 

我們設定ftp[i].mask.src.u.tcp.port = 0x0000;,因為這個賦值會導致所有的串連都不符合要求,因此應該沒有什麼應用和這個相衝突。在init_conntrack函數中會為每個主串連尋找對應的helper,代碼如下:

    /* Look up the conntrack helper for master connections only */

    if (!expected)

        conntrack->helper = ip_ct_find_helper(&repl_tuple);

最終這個函數會調用到helper_cmp,所以我們可以修改這函數,令其直接返回。

  1. static inline int
  2. helper_cmp(const struct ip_nat_helper *helper,
  3.        const struct ip_conntrack_tuple *tuple)
  4. {
  5.     //添加的判斷代碼
  6.     if (helper->mask.src.u.tcp.port == 0 &
  7.         (helper->tuple.dst.protonum == IPPROTO_TCP || helper->tuple.dst.protonum == IPPROTO_UDP))
  8.         return 0;
  9.     else
  10.         return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);
  11. }

 

在串連被應用識別識別為ftp後,在相應的後麵包的Ip_conntrack_in函數中都會相應的調用help函數,代碼如下所示:

  1. /* Netfilter hook itself. */
  2. unsigned int ip_conntrack_in(unsigned int hooknum,
  3.                  struct sk_buff **pskb,
  4.                  const struct net_device *in,
  5.                  const struct net_device *out,
  6.                  int (*okfn)(struct sk_buff *))
  7. {
  8.     struct ip_conntrack *ct;
  9.     enum ip_conntrack_info ctinfo;
  10.     struct ip_conntrack_protocol *proto;
  11.     int set_reply;
  12.     int ret;
  13.     //…
  14.     //…
  15.     if (ret != NF_DROP && ct->helper) {
  16.         //調用help函數
  17.         ret = ct->helper->help((*pskb)->nh.iph, (*pskb)->len,
  18.                        ct, ctinfo);
  19.         if (ret == -1) {
  20.             /* Invalid */
  21.             nf_conntrack_put((*pskb)->nfct);
  22.             (*pskb)->nfct = NULL;
  23.             return NF_ACCEPT;
  24.         }
  25.     }
  26.     if (set_reply)
  27.         set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
  28.     return ret;
  29. }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.