使用 tc 和 xdp 程序在 docker 容器中代理服务

问题描述 投票:0回答:0

我的 ubuntu 容器中有一个 Web 服务绑定到地址 172.17.0.2:8080。我主机的网络地址是172.16.0.240,另一台设备的ip地址是172.16.0.198.

访问172.16.0.240:9999,通过xdp程序将数据包的目的ip和mac路由到ubuntu容器中。容器中的web服务响应后,使用tc exit程序更改源ip、端口、mac,但是在建立tcp连接时,连接被客户端重置。我不知道数据包是如何生成的。 enter image description here
docker0 是网桥
docker0:enter image description here
eth0是docker中的网卡
eth0:enter image description here
wlp0s20f3 是我主机的物理网卡
wlp0s20f3:enter image description here
第一:
我用xdp程序把客户端访问的数据包的目的ip和目的mac改成了容器中eth网卡的ip和mac,然后将数据包转发给docker0网卡,其iface.指数是5.

        if (tcp->dest == bpf_htons(9999) && iph->daddr == bpf_htonl(0xac1000f0)) {
            tcp->dest = bpf_htons(8080);
            iph->daddr = bpf_htonl(0xAC110002);
            eth->h_dest[0] = 2;
            eth->h_dest[1] = 66;
            eth->h_dest[2] = -84;
            eth->h_dest[3] = 17;
            eth->h_dest[4] = 0;
            eth->h_dest[5] = 2;
            iph->check = ipv4_csum(iph);
            return bpf_redirect(5, 0);
        }

第二个:
容器中服务的响应包通过tc程序变成wlp0s20f3网卡的相关数据,然后发送给客户端,但是在tcp连接阶段,连接被服务端重置了

因为一个数据包的出现不是tc程序修改对的,可以看到我在/sys/kernel/debug/tracing/trace_pipe中做了debug信息。我判断所有端口为8080,ip为172.17.0.2的包都会被修改。但是,有一个 IP 为 172.16.0.240 的数据包。我不知道它是如何产生的。
调试信息在 /sys/kernel/debug/tracing/trace_pipe:

 irq/147-iwlwifi-588     [003] D.s3.  3224.289402: bpf_trace_printk: source: 8080, target: 47018, src: ac110002
 irq/147-iwlwifi-588     [003] D.s3.  3224.289415: bpf_trace_printk: 1
 irq/147-iwlwifi-588     [003] D.s3.  3224.289416: bpf_trace_printk: 2
 irq/147-iwlwifi-588     [003] D.s3.  3224.315978: bpf_trace_printk: source: 8080, target: 47018, src: ac1000f0
 irq/147-iwlwifi-588     [003] D.s3.  3224.315991: bpf_trace_printk: 1
            main-12886   [007] D.s3.  3224.316547: bpf_trace_printk: source: 8080, target: 47018, src: ac1000f0
            main-12886   [007] D.s3.  3224.316557: bpf_trace_printk: 1
 irq/147-iwlwifi-588     [003] D.s3.  3224.637523: bpf_trace_printk: source: 8080, target: 47018, src: ac110002
 irq/147-iwlwifi-588     [003] D.s3.  3224.637535: bpf_trace_printk: 1
 irq/147-iwlwifi-588     [003] D.s3.  3224.637537: bpf_trace_printk: 2
 irq/147-iwlwifi-588     [003] D.s3.  3224.916243: bpf_trace_printk: source: 8080, target: 47018, src: ac110002
 irq/147-iwlwifi-588     [003] D.s3.  3224.916255: bpf_trace_printk: 1
 irq/147-iwlwifi-588     [003] D.s3.  3224.916257: bpf_trace_printk: 2

我如何调试:

        bpf_printk("source: %d, target: %d, src: %2x", bpf_ntohs(tcp->source), bpf_ntohs(tcp->dest), bpf_ntohl(iph->saddr));
        bpf_printk("1");
        if (tcp->source == bpf_htons(8080) || iph->saddr == bpf_htonl(0xAC110002)) {
            tcp->source = bpf_htons(9999);
            iph->saddr = bpf_htonl(0xac1000f0);
            eth->h_source[0] = xx;
            eth->h_source[1] = xx;
            eth->h_source[2] = xx;
            eth->h_source[3] = 70;
            eth->h_source[4] = 58;
            eth->h_source[5] = 57;
            iph->check = ipv4_csum(iph);
            bpf_printk("2");
        }
docker tcp ip ebpf xdp-bpf
© www.soinside.com 2019 - 2024. All rights reserved.