2013-12-18 61 views
1

我在使用iptables時遇到了一些麻煩,一組全新的眼球可能會看到問題出在哪裏。Iptables的netfilter隊列nfq_set_verdict_mark(nfq_set_verdict2)似乎沒有應用標記

我試圖使用netfilter隊列標記數據包(通過nfq_set_verdict_mark - 舊文檔說,使用nfq_set_verdict2,但該函數似乎不再是在標題或庫)在PREROUTING鏈表的mangle表。然後數據包應該移動到PRATOUTING鏈表中,我有規則來讀取標記並相應地重定向。事實上,這是在早期的測試中工作,但現在不是!

下面是我的簡單測試回調函數 - 它只是爲0xFFFFFFFF標誌和接受:

static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, 
      struct nfq_data *nfa, void *data) 
{ 
    uint32_t id = print_pkt(nfa); // from example code 
    printf("marking packet...\n"); 
    return nfq_set_verdict_mark(qh,id,NF_ACCEPT,0xFFFFFFFF,0,NULL); 
} 

下面是我使用的iptable的規則:

// Using queue -- not working 
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j QUEUE 
iptables -t nat -A PREROUTING -p tcp --dport 80 -m mark --mark 0xFFFFFFFF -j REDIRECT --to-ports 9009 

我也用conntrack --flush來重置連接狀態以確保數據包遇到nat表。我使用0xFFFFFFFF來防止可能的字節排序問題。數據包明確進入隊列並被接受(打印「標記數據包...」,瀏覽器可以訪問端口80上的內容)。然而,重定向不會發生。

如果我直接設置標記而不是在隊列中,重定向的工作。這就像標記沒有被添加到隊列中一樣。這當然是以前的標誌,我沒有改變圖書館版本或任何東西。

// Without queue -- redirection happens 
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 0xFFFFFFFF 
iptables -t nat -A PREROUTING -p tcp --dport 80 -m mark --mark 0xFFFFFFFF -j REDIRECT --to-ports 9009 

這裏的print_pkt的好辦法 - 不是我寫的,而是從netfilter_queue例如拍攝,一直沒有改變,和以前的工作:

static u_int32_t print_pkt (struct nfq_data *tb) 
{ 
     int id = 0; 
     struct nfqnl_msg_packet_hdr *ph; 
     struct nfqnl_msg_packet_hw *hwph; 
     u_int32_t mark,ifi; 
     int ret; 
     char *data; 

     ph = nfq_get_msg_packet_hdr(tb); 
     if (ph) { 
       id = ntohl(ph->packet_id); 
       printf("hw_protocol=0x%04x hook=%u id=%u ", 
         ntohs(ph->hw_protocol), ph->hook, id); 
     } 

     hwph = nfq_get_packet_hw(tb); 
     if (hwph) { 
       int i, hlen = ntohs(hwph->hw_addrlen); 

       printf("hw_src_addr="); 
       for (i = 0; i < hlen-1; i++) 
         printf("%02x:", hwph->hw_addr[i]); 
       printf("%02x ", hwph->hw_addr[hlen-1]); 
     } 

     mark = nfq_get_nfmark(tb); 
     if (mark) 
       printf("mark=%u ", mark); 

     ifi = nfq_get_indev(tb); 
     if (ifi) 
       printf("indev=%u ", ifi); 

     ifi = nfq_get_outdev(tb); 
     if (ifi) 
       printf("outdev=%u ", ifi); 
     ifi = nfq_get_physindev(tb); 
     if (ifi) 
       printf("physindev=%u ", ifi); 

     ifi = nfq_get_physoutdev(tb); 
     if (ifi) 
       printf("physoutdev=%u ", ifi); 

     ret = nfq_get_payload(tb, &data); 
     if (ret >= 0) 
       printf("payload_len=%d ", ret); 

     fputc('\n', stdout); 

     return id; 
} 

此外,主要功能(也取自示例代碼和以前的工作):

int main(int argc, char **argv) 
{ 
     struct nfq_handle *h; 
     struct nfq_q_handle *qh; 
     struct nfnl_handle *nh; 
     int fd; 
     int rv; 
     char buf[4096] __attribute__ ((aligned)); 

     printf("opening library handle\n"); 
     h = nfq_open(); 
     if (!h) { 
       fprintf(stderr, "error during nfq_open()\n"); 
       exit(1); 
     } 

     printf("unbinding existing nf_queue handler for AF_INET (if any)\n"); 
     if (nfq_unbind_pf(h, AF_INET) < 0) { 
       fprintf(stderr, "error during nfq_unbind_pf()\n"); 
       exit(1); 
     } 

     printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n"); 
     if (nfq_bind_pf(h, AF_INET) < 0) { 
       fprintf(stderr, "error during nfq_bind_pf()\n"); 
       exit(1); 
     } 

     printf("binding this socket to queue '0'\n"); 
     qh = nfq_create_queue(h, 0, &cb, NULL); 
     if (!qh) { 
       fprintf(stderr, "error during nfq_create_queue()\n"); 
       exit(1); 
     } 

     printf("setting copy_packet mode\n"); 
     if (nfq_set_mode(qh, NFQNL_COPY_META, 0xffff) < 0) { 
       fprintf(stderr, "can't set packet_copy mode\n"); 
       exit(1); 
     } 

     fd = nfq_fd(h); 

     while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { 
       printf("pkt received\n"); 
       nfq_handle_packet(h, buf, rv); 
     } 

     printf("unbinding from queue 0\n"); 
     nfq_destroy_queue(qh); 

#ifdef INSANE 
     /* normally, applications SHOULD NOT issue this command, since 
     * it detaches other programs/sockets from AF_INET, too ! */ 
     printf("unbinding from AF_INET\n"); 
     nfq_unbind_pf(h, AF_INET); 
#endif 

     printf("closing library handle\n"); 
     nfq_close(h); 

     exit(0); 
} 

重定向是我的測試代碼中的預期行爲,但它沒有發生。缺少的鏈接是什麼?我花了幾個小時解決了這個問題(之前的預期工作),但都無濟於事。幫幫我!!

回答

0

舊的文檔說,使用nfq_set_verdict2但功能似乎不再是在頁眉或庫

也許你正在使用libnetfilter_queue HDRS + LIB過時的版本? 版本1.0.2(netfilter.org)似乎是最新的版本,並且這個功能。