linux - 内核模块中的 ip header 更改会中断连接

标签 linux kernel hook mips32 netfilter

我有一个内核模块,其中:

  • 它更改传出数据包的 saddr 字段并将其修复(daddr)在传入数据包中 ...
  • 我正在计算 ip 和 tcp header 的新校验和...

所以在客户端,我更改了 ip - 服务器端接收它(SYN 数据包)并发送(SYN-ACK)数据包 - 但客户端 - 发送(重置)数据包并再次尝试处理 tcp 握手 ...

我看过另一个内核模块示例 - dnat/snat - 我的代码是类比的吗?我的 be ebtables 使我的钩子(Hook)无法正常工作?

接口(interface): eth0 - XXX.XXX.XXX.1 eth0:0(别名)- XXX.XXX.XXX.2

 /*
 Client (original ip XX.XX.XX.1)                                                                                                                         SERVER (ip YY.YY.YY.YY)
 USER-SPACE app creates tcp-socket and connects to (YY.YY.YY.YY)

  1) 
 TCP (SYN) -----------(packet ip XX.XX.XX.1-YY.YY.YY.YY[ip.sum1, tcp.sum1] )----->
 NF_INET_POST_ROUTING ( ip XX.XX.XX.2-YY.YY.YY.YY[ip.sum2, tcp.sum2] )
 =============================================================================>
 2)
 <-------TCP (SYN ACK) ------(packet ip YY.YY.YY.YY-XX.XX.XX.2[ip.sum1, tcp.sum1])
 NF_INET_PRE_ROUTING ( ip YY.YY.YY.YY-XX.XX.XX.1[ip.sum2, tcp.sum2] )
<==============================================================================


 3)

 TCP (RST) - against TCP (ACK) - that is the question ....
 =============================================================================>

  */

/* 变量.c */

 struct in_addr orig_addr;
 struct in_addr virt_addr;
 pid_t pid_to_handle;


 void init_vars()
 {
      pid_to_handle = 0xAAAA;
      inet_pton(AF_INET, "XX.XX.XX.1", &orig_addr);
      inet_pton(AF_INET, "XX.XX.XX.2", &virt_addr);
 }

/* 初始化.c */

 void register_handlers()
 {
      ...

      int ret;
      hook_out.hooknum  = NF_INET_POST_ROUTING;
      hook_out.hook     = process_out;
      hook_out.pf       = PF_INET;
      hook_out.owner    = THIS_MODULE;
      hook_out.priority = NF_IP_PRI_LAST;
      ret = nf_register_hook(&hook_out);

      hook_in.hooknum  = NF_INET_PRE_ROUTING;
      hook_in.hook     = process_in;
      hook_in.pf       = PF_INET;
      hook_in.owner    = THIS_MODULE;
      hook_in.priority = NF_IP_PRI_FIRST;
      ret = nf_register_hook(&hook_in);
      ....

  }

/* 输出.c */

 unsigned int process_out(
           unsigned int hooknum,
           struct sk_buff *skb,
           const struct net_device *in,
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
      int i;
      struct iphdr *iph;
      struct tcphdr *tcp_header;
      ....

      {
           if ( skb->sk ) {
                if ( skb->sk ) {
                     struct socket * s = skb->sk->sk_socket;
                     if ( s ) {
                          struct file *f = s->file;

                          if ( f ) {
                               struct task_struct *task;
                               struct files_struct *files;

                               for_each_process(task) {
                                    if ( task->pid == pid_to_handle ) {
                                         task_lock(task);
                                         files = task->files;

                                         if ( files ) {
                                              read_lock(&files->file_lock);

                                              for ( i=0; i<1024; i++ ) {
                                                   if ( fcheck_files(files, i) == f ) {
                                                        iph->saddr = virt_addr.s_addr;
                                                        iph->check = 0;
                                                        ip_send_check (iph);

                                                        tcp_header->check = 0;
                                                        tcp_header->check = get_packet_checksum(
                                                                  iph, tcp_header, pseudogram_out, datagram_out);

                                                   }
                                              }

                                              read_unlock(&files->file_lock);
                                         }

                                         task_unlock(task);
                                    }
                               }
                          }

                     }
                }
           }
      }

      return NF_ACCEPT;
 }

/* in.c */

 unsigned int process_in(
           unsigned int hooknum,
           struct sk_buff *skb,
           const struct net_device *in,
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
      struct iphdr *iph;
      struct tcphdr *tcp_header;
      ...

      {
           if ( iphdr->daddr == virt_addr.s_addr ) {
                iphdr->daddr = orig_addr.s_addr;

                iph->check = 0;
                iph->check = ip_fast_csum(iph, iph->ihl);

                tcp_header->check = 0;
                tcp_header->check = get_packet_checksum(
                          iph, tcp_header, pseudogram_in, datagram_in);
           }
      }

      return NF_ACCEPT;
 }

/* 实用程序.c */

 struct pseudo_header
 {
      u_int32_t source_address;
      u_int32_t dest_address;
      u_int8_t placeholder;
      u_int8_t protocol;
      u_int16_t tcp_length;
 };

 /*
      Generic checksum calculation function
 */
 unsigned short csum(unsigned short *ptr,int nbytes) {
      register long sum;
      unsigned short oddbyte;
      register short answer;

      sum = 0;
      while (nbytes > 1) {
           sum += *ptr++;
           nbytes -= 2;
      }
      if (nbytes == 1) {
           oddbyte = 0;
           *((u_char * ) & oddbyte) = *(u_char *) ptr;
           sum += oddbyte;
      }

      sum = (sum >> 16) + (sum & 0xffff);
      sum = sum + (sum >> 16);
      answer = (short) ~sum;

      return (answer);

 }

 static char *pseudogram_out = NULL;
 static char *datagram_out = NULL;
 static char *pseudogram_in = NULL;
 static char *datagram_in = NULL;


 int get_packet_checksum(struct iphdr *ip_header, struct tcphdr *tcp_header, char *pseudogram, char *datagram)
 {
      if ( (pseudogram == NULL) || (datagram == NULL) )
           return -1;

      char source_ip[32] , *data;
      memset (datagram, 0, 4096);
      memset (pseudogram, 0, 4096);
      memcpy(datagram, ip_header, ip_header->tot_len);
      ip_header = (struct iphdr *)datagram;
      tcp_header = (struct tcphdr *)(datagram + sizeof(struct iphdr));

      struct sockaddr_in sin;
      struct pseudo_header psh;
      size_t tcp_data_len = ip_header->tot_len - sizeof(struct iphdr) - sizeof(struct tcphdr);

      psh.source_address = ip_header->saddr;
      psh.dest_address = ip_header->daddr;
      psh.placeholder = 0;
      psh.protocol = IPPROTO_TCP;
      psh.tcp_length = htons(sizeof(struct tcphdr) + tcp_data_len );

      int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + tcp_data_len;
      memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
      memcpy(pseudogram + sizeof(struct pseudo_header) , tcp_header , sizeof(struct tcphdr) + tcp_data_len);

      return csum((unsigned short*)pseudogram, psize);
 }

tcpump 登录服务器:

11:27:03.164239 IP (tos 0x0, ttl 48, id 61125, offset 0, flags [DF], proto TCP (6), length 60)
    XXX.XXX.XXX.x2.33782 > YYY.YY.YYY.YYY.8999: Flags [S], cksum 0xa1cb (correct), seq 492452010, win 5840, options [mss 1448,sackOK,TS val 251503 ecr 0,nop,wscale 1], length 0
    0x0000:  4500 003c eec5 4000 3006 a014 xxxx xxx2  E..<..@.0....5}.
    0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
    0x0020:  a002 16d0 a1cb 0000 0204 05a8 0402 080a  ................
    0x0030:  0003 d66f 0000 0000 0103 0301            ...o........
11:27:03.164394 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    YYY.YY.YYY.YYY.8999 > XXX.XXX.XXX.x2.33782: Flags [S.], cksum 0xbc10 (incorrect -> 0x597a), seq 1446351294, ack 492452011, win 28960, options [mss 1460,sackOK,TS val 842060729 ecr 251503,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 7eda yyyy yyyy  E..<..@.@.~..E..
    0x0010:  xxxx xxx2 2327 83f6 5635 91be 1d5a 38ab  .5}.#'..V5...Z8.
    0x0020:  a012 7120 bc10 0000 0204 05b4 0402 080a  ..q.............
    0x0030:  3230 d3b9 0003 d66f 0103 0307            20.....o....
11:27:04.181972 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    YYY.YY.YYY.YYY.8999 > XXX.XXX.XXX.x2.33782: Flags [S.], cksum 0xbc10 (incorrect -> 0x587b), seq 1446351294, ack 492452011, win 28960, options [mss 1460,sackOK,TS val 842060984 ecr 251503,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 7eda yyyy yyyy  E..<..@.@.~..E..
    0x0010:  xxxx xxx2 2327 83f6 5635 91be 1d5a 38ab  .5}.#'..V5...Z8.
    0x0020:  a012 7120 bc10 0000 0204 05b4 0402 080a  ..q.............
    0x0030:  3230 d4b8 0003 d66f 0103 0307            20.....o....
11:27:05.525221 IP (tos 0x0, ttl 48, id 61126, offset 0, flags [DF], proto TCP (6), length 60)
    XXX.XXX.XXX.x2.33782 > YYY.YY.YYY.YYY.8999: Flags [S], cksum 0x9612 (correct), seq 492452010, win 5840, options [mss 1448,sackOK,TS val 254504 ecr 0,nop,wscale 1], length 0
    0x0000:  4500 003c eec6 4000 3006 a013 xxxx xxx2  E..<..@.0....5}.
    0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
    0x0020:  a002 16d0 9612 0000 0204 05a8 0402 080a  ................
    0x0030:  0003 e228 0000 0000 0103 0301            ...(........
11:27:05.525319 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    YYY.YY.YYY.YYY.8999 > XXX.XXX.XXX.x2.33782: Flags [S.], cksum 0xbc10 (incorrect -> 0x572c), seq 1446351294, ack 492452011, win 28960, options [mss 1460,sackOK,TS val 842061319 ecr 251503,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 7eda yyyy yyyy  E..<..@.@.~..E..
    0x0010:  xxxx xxx2 2327 83f6 5635 91be 1d5a 38ab  .5}.#'..V5...Z8.
    0x0020:  a012 7120 bc10 0000 0204 05b4 0402 080a  ..q.............
    0x0030:  3230 d607 0003 d66f 0103 0307            20.....o....
11:27:07.541981 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    YYY.YY.YYY.YYY.8999 > XXX.XXX.XXX.x2.33782: Flags [S.], cksum 0xbc10 (incorrect -> 0x5533), seq 1446351294, ack 492452011, win 28960, options [mss 1460,sackOK,TS val 842061824 ecr 251503,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 7eda yyyy yyyy  E..<..@.@.~..E..
    0x0010:  xxxx xxx2 2327 83f6 5635 91be 1d5a 38ab  .5}.#'..V5...Z8.
    0x0020:  a012 7120 bc10 0000 0204 05b4 0402 080a  ..q.............
    0x0030:  3230 d800 0003 d66f 0103 0307            20.....o....
11:27:11.524252 IP (tos 0x0, ttl 48, id 61127, offset 0, flags [DF], proto TCP (6), length 60)
    XXX.XXX.XXX.x2.33782 > YYY.YY.YYY.YYY.8999: Flags [S], cksum 0x7ea2 (correct), seq 492452010, win 5840, options [mss 1448,sackOK,TS val 260504 ecr 0,nop,wscale 1], length 0
    0x0000:  4500 003c eec7 4000 3006 a012 xxxx xxx2  E..<..@.0....5}.
    0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
    0x0020:  a002 16d0 7ea2 0000 0204 05a8 0402 080a  ....~...........
    0x0030:  0003 f998 0000 0000 0103 0301            ............
11:27:11.524331 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    YYY.YY.YYY.YYY.8999 > XXX.XXX.XXX.x2.33782: Flags [S.], cksum 0xbc10 (incorrect -> 0x5150), seq 1446351294, ack 492452011, win 28960, options [mss 1460,sackOK,TS val 842062819 ecr 251503,nop,wscale 7], length 0
    0x0000:  4500 003c 0000 4000 4006 7eda yyyy yyyy  E..<..@.@.~..E..
    0x0010:  xxxx xxx2 2327 83f6 5635 91be 1d5a 38ab  .5}.#'..V5...Z8.
    0x0020:  a012 7120 bc10 0000 0204 05b4 0402 080a  ..q.............
    0x0030:  3230 dbe3 0003 d66f 0103 0307            20.....o....

客户端上的 tcpdump:

     06:27:02.370828 IP (tos 0x0, ttl 64, id 61125, offset 0, flags [DF], proto TCP (6), length 60) xxx.xxx.xxx.X2.33782 > YYY.YY.YYY.YYY.8999: S, cksum 0xa1bf (correct), 492452010:492452010(0) win 5840 <mss 1460,sackOK,timestamp 251503 0,nop,wscale 1>
      0x0000:  4500 003c eec5 4000 4006 9014 xxxx xxx2  E..<..@.@....5}.
      0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
      0x0020:  a002 16d0 a1bf 0000 0204 05b4 0402 080a  ................
      0x0030:  0003 d66f 0000 0000 0103 0301            ...o........
 06:27:03.301644 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x5986 (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842060729 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 5986 0000 0204 05a8 0402 080a  ..q.Y...........
      0x0030:  3230 d3b9 0003 d66f 0103 0307            20.....o....
 06:27:04.318359 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x5887 (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842060984 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 5887 0000 0204 05a8 0402 080a  ..q.X...........
      0x0030:  3230 d4b8 0003 d66f 0103 0307            20.....o....
 06:27:05.371079 IP (tos 0x0, ttl 64, id 61126, offset 0, flags [DF], proto TCP (6), length 60) xxx.xxx.xxx.X2.33782 > YYY.YY.YYY.YYY.8999: S, cksum 0x9606 (correct), 492452010:492452010(0) win 5840 <mss 1460,sackOK,timestamp 254504 0,nop,wscale 1>
      0x0000:  4500 003c eec6 4000 4006 9013 xxxx xxx2  E..<..@.@....5}.
      0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
      0x0020:  a002 16d0 9606 0000 0204 05b4 0402 080a  ................
      0x0030:  0003 e228 0000 0000 0103 0301            ...(........
 06:27:05.661863 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x5738 (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842061319 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 5738 0000 0204 05a8 0402 080a  ..q.W8..........
      0x0030:  3230 d607 0003 d66f 0103 0307            20.....o....
 06:27:07.677895 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x553f (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842061824 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 553f 0000 0204 05a8 0402 080a  ..q.U?..........
      0x0030:  3230 d800 0003 d66f 0103 0307            20.....o....
 06:27:11.371065 IP (tos 0x0, ttl 64, id 61127, offset 0, flags [DF], proto TCP (6), length 60) xxx.xxx.xxx.X2.33782 > YYY.YY.YYY.YYY.8999: S, cksum 0x7e96 (correct), 492452010:492452010(0) win 5840 <mss 1460,sackOK,timestamp 260504 0,nop,wscale 1>
      0x0000:  4500 003c eec7 4000 4006 9012 xxxx xxx2  E..<..@.@....5}.
      0x0010:  yyyy yyyy 83f6 2327 1d5a 38aa 0000 0000  .E....#'.Z8.....
      0x0020:  a002 16d0 7e96 0000 0204 05b4 0402 080a  ....~...........
      0x0030:  0003 f998 0000 0000 0103 0301            ............
 06:27:11.660592 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x515c (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842062819 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 515c 0000 0204 05a8 0402 080a  ..q.Q\..........
      0x0030:  3230 dbe3 0003 d66f 0103 0307            20.....o....
 06:27:15.870063 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x4d3f (correct), 1446351294:1446351294(0) ack 492452011 win 28960 <mss 1448,sackOK,timestamp 842063872 251503,nop,wscale 7>
      0x0000:  4500 003c 0000 4000 3506 89d9 yyyy yyyy  E..<..@.5....E..
      0x0010:  xxxx xxx1 2327 83f6 5635 91be 1d5a 38ab  .4}.#'..V5...Z8.
      0x0020:  a012 7120 4d3f 0000 0204 05a8 0402 080a  ..q.M?..........
      0x0030:  3230 e000 0003 d66f 0103 0307            20.....o....
 06:27:24.062254 IP (tos 0x0, ttl 53, id 0, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 89d9 (->89da)!) YYY.YY.YYY.YYY.8999 > xxx.xxx.xxx.x1.33782: S, cksum 0x453f (correct), 1446351294:1446351294(0) ack 492452011

最佳答案

从您所说的看来,问题似乎在于您正在修改 TCP/IP 堆栈之外的数据包的各个方面。这会造成一种情况,例如,返回的 SYN/ACK 不会与 TCP/IP 堆栈知道的任何连接相关联,因此它将通过重置连接来使用react。

解决此问题的一种快速而肮脏的方法是使用 IPTables 防火墙来防止系统能够向外发送 RST 数据包。当然,这意味着您的数据包修补也将无法发送出站 RST 数据包。

iptables -I INPUT -p tcp --tcp-flags RST RST -j DROP

关于linux - 内核模块中的 ip header 更改会中断连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48299308/

相关文章:

linux - 将系统调用编写为内核模块

excel - 在VBA中,如何在不使用Application.Run()的情况下从未知模块调用特定方法?

linux - 我的 shell 脚本中的 URL 中断

linux - 内核 API 返回当前运行的 CPU 号

从源代码编译内核。错误解释。

c++ - 如何将 vector 的 C++ vector 传递给 OpenCL 内核?

erlang - ejabberd 钩子(Hook)的文档?

git - 实现自定义 gitlab 钩子(Hook)时出现问题

linux - GAWK 脚本 - 在 BEGIN 部​​分打印文件名

linux - 如何在 Ubuntu 上找到多个工作进程的父进程(其 ppid=1)?