为什么我不能在NF_INET_LOCAL_IN挂钩中修改目标IP?

时间:2019-03-28 09:23:22

标签: linux-kernel hook network-protocols netfilter

有3个主机,客户端A(10.8.8.1),代理B(10.8.8.128)和服务器C(10.8.8.133)。我需要在C上获得A的IP,而不是B的IP。因此,我在C上将NF_INET_LOCAL_IN中的源IP从10.8.8.128更改为10.8.8.1,将目标IP从10.8.8.1更改为10.8.8.128在NF_INET_LOCAL_OUT中的10.8.8.128。我该怎么办?

Mysql客户端无法通过代理B访问服务器C:

enter image description here

tcpdump输出:

[root@localhost chdip]# tcpdump -n  -i ens33 port 3306 or port 7306
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes



16:13:00.798946 IP 10.8.8.1.57632 > 10.8.8.128.7306: Flags [SEW], seq 4288644802, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 377351882 ecr 0,sackOK,eol], length 0
16:13:00.799095 IP 10.8.8.128.7306 > 10.8.8.1.57632: Flags [S.E], seq 1578140148, ack 4288644803, win 28960, options [mss 1460,sackOK,TS val 126348449 ecr 377351882,nop,wscale 6], length 0
16:13:00.799097 IP 10.8.8.1.57632 > 10.8.8.128.7306: Flags [.], ack 1, win 4117, options [nop,nop,TS val 377351882 ecr 126348449], length 0
16:13:00.799772 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126348449 ecr 0,nop,wscale 6], length 0
16:13:00.799793 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126348449 ecr 0,nop,wscale 6], length 0
16:13:01.817525 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126348704 ecr 0,nop,wscale 6], length 0
16:13:01.817574 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126348704 ecr 0,nop,wscale 6], length 0
16:13:03.833783 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126349208 ecr 0,nop,wscale 6], length 0
16:13:03.833952 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126349208 ecr 0,nop,wscale 6], length 0
16:13:08.089557 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126350272 ecr 0,nop,wscale 6], length 0
16:13:08.089618 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126350272 ecr 0,nop,wscale 6], length 0
16:13:08.089689 IP 10.8.8.128.42204 > 10.8.8.133.mysql: Flags [S], seq 2070884158, win 29200, options [mss 1460,sackOK,TS val 126350272 ecr 0,nop,wscale 6], length 0
16:13:08.089707 IP 10.8.8.1.42204 > 10.8.8.133.mysql: Flags [S], seq 2070884158, win 29200, options [mss 1460,sackOK,TS val 126350272 ecr 0,nop,wscale 6], length 0
16:13:10.800402 IP 10.8.8.1.57632 > 10.8.8.128.7306: Flags [F.], seq 1, ack 1, win 4117, options [nop,nop,TS val 377361870 ecr 126348449], length 0
16:13:10.801310 IP 10.8.8.128.7306 > 10.8.8.1.57632: Flags [.], ack 2, win 453, options [nop,nop,TS val 126350950 ecr 377361870], length 0
16:13:16.281733 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126352320 ecr 0,nop,wscale 6], length 0
16:13:16.281794 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126352320 ecr 0,nop,wscale 6], length 0
16:13:20.633910 IP 10.8.8.128.42198 > 10.8.8.133.mysql: Flags [P.], seq 2160408471:2160408483, ack 3792927187, win 773, options [nop,nop,TS val 126353408 ecr 9121698], length 12
16:13:20.633977 IP 10.8.8.1.42198 > 10.8.8.133.mysql: Flags [P.], seq 2160408471:2160408483, ack 3792927187, win 773, options [nop,nop,TS val 126353408 ecr 9121698], length 12
16:13:20.634094 IP 10.8.8.128.42200 > 10.8.8.133.mysql: Flags [P.], seq 3988153942:3988153954, ack 2162888825, win 727, options [nop,nop,TS val 126353408 ecr 9116859], length 12
16:13:20.634117 IP 10.8.8.1.42200 > 10.8.8.133.mysql: Flags [P.], seq 3988153942:3988153954, ack 2162888825, win 727, options [nop,nop,TS val 126353408 ecr 9116859], length 12
16:13:32.409535 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126356352 ecr 0,nop,wscale 6], length 0
16:13:32.409645 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126356352 ecr 0,nop,wscale 6], length 0
16:13:41.113585 IP 10.8.8.128.42204 > 10.8.8.133.mysql: Flags [S], seq 2070884158, win 29200, options [mss 1460,sackOK,TS val 126358528 ecr 0,nop,wscale 6], length 0
16:13:41.113632 IP 10.8.8.1.42204 > 10.8.8.133.mysql: Flags [S], seq 2070884158, win 29200, options [mss 1460,sackOK,TS val 126358528 ecr 0,nop,wscale 6], length 0
16:14:05.689388 IP 10.8.8.128.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126364672 ecr 0,nop,wscale 6], length 0
16:14:05.689435 IP 10.8.8.1.42206 > 10.8.8.133.mysql: Flags [S], seq 2163900222, win 29200, options [mss 1460,sackOK,TS val 126364672 ecr 0,nop,wscale 6], length 0
16:14:46.649424 IP 10.8.8.128.7306 > 10.8.8.1.57631: Flags [F.], seq 3732203951, ack 1169202828, win 453, options [nop,nop,TS val 126374912 ecr 377337705], length 0
16:14:46.649429 IP 10.8.8.1.57631 > 10.8.8.128.7306: Flags [.], ack 1, win 4117, options [nop,nop,TS val 377457577 ecr 126374912], length 0
16:15:11.225928 IP 10.8.8.128.7306 > 10.8.8.1.57632: Flags [F.], seq 1, ack 2, win 453, options [nop,nop,TS val 126381056 ecr 377361870], length 0
16:15:11.225934 IP 10.8.8.1.57632 > 10.8.8.128.7306: Flags [.], ack 2, win 4117, options [nop,nop,TS val 377482114 ecr 126381056], length 0
^C
31 packets captured
31 packets received by filter
0 packets dropped by kernel
  1. 某些源IP从10.8.8.128更改为10.8.8.1
  2. 没有目标IP 10.8.8.133。

更改源IP代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/socket.h>/*PF_INET*/
#include <linux/netfilter_ipv4.h>/*NF_IP_PRE_FIRST*/
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/inet.h> /*in_aton()*/
#include <net/ip.h>
#include <net/tcp.h>

#define ETHALEN 14

MODULE_LICENSE("GPL");
MODULE_AUTHOR("bbo");

static struct nf_hook_ops nfho;

unsigned int checksum(unsigned int hooknum,
        struct sk_buff *__skb,
        const struct net_device *in,
        const struct net_device *out,
        int (*okfn)(struct sk_buff *))
{
    struct sk_buff *skb;
    struct net_device *dev;
    struct iphdr *iph;
    struct tcphdr *tcph;
    int tot_len;
    int iph_len;
    int tcph_len;
    int ret;

    skb = __skb;
    if (skb == NULL)
        return NF_ACCEPT;

    iph = ip_hdr(skb);
    if (iph == NULL)
        return NF_ACCEPT;

    tot_len = ntohs(iph->tot_len);

    if (iph->saddr == in_aton("10.8.8.128"))
    {
        printk("LINE: %d,   FUNCTION: %s:  \n", __LINE__, __FUNCTION__);
        iph_len = ip_hdrlen(skb);/*in ip.h*/
        skb_pull(skb, iph_len);

        skb_reset_transport_header(skb);
        if (iph->protocol == IPPROTO_TCP)
        {
            tcph = tcp_hdr(skb);
            tcph_len = tcp_hdrlen(skb);
            if (tcph->dest == htons(3306))
            {
                iph->saddr = in_aton("10.8.8.1");
                dev = dev_get_by_name(&init_net, "ens33");

                tcph->check = 0;
                skb->csum = csum_partial((unsigned char *)tcph, tot_len - iph_len, 0);
                tcph->check = csum_tcpudp_magic(iph->saddr,
                        iph->daddr,
                        ntohs(iph->tot_len) - iph_len, iph->protocol,
                        skb->csum);
                iph->check = 0;
                iph->check = ip_fast_csum(iph, iph->ihl);

                skb->ip_summed = CHECKSUM_NONE;
                skb->pkt_type = PACKET_OTHERHOST;
                skb->dev = dev;
                skb_push(skb, iph_len);
                //skb_reset_transport_header(skb);

                skb_push(skb, ETHALEN);

                ret = dev_queue_xmit(skb);
                if (ret < 0)
                {
                    printk("dev_queue_xmit() error\n");
                    goto out;
                }
                printk("LINE: %d,   FUNCTION: %s\n", __LINE__, __FUNCTION__);
                return NF_STOLEN;
            }
        }
        skb_push(skb, iph_len);
        skb_reset_transport_header(skb);
    }


    return NF_ACCEPT;
out:
    dev_put(dev);

    return NF_DROP;
}

static int __init filter_init(void)
{
    int ret;
    nfho.hook = checksum;
    nfho.pf = AF_INET;
    nfho.hooknum =  NF_INET_LOCAL_IN;
    nfho.priority = NF_IP_PRI_FIRST;

    ret = nf_register_hook(&nfho);
    if (ret < 0)
    {
        printk("%s\n", "can't modify skb hook!");
        return ret;
    }

    return 0;
}

static void filter_fini(void)
{
    nf_unregister_hook(&nfho);
}

module_init(filter_init);
module_exit(filter_fini);

更改目标IP地址:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/socket.h>/*PF_INET*/
#include <linux/netfilter_ipv4.h>/*NF_IP_PRE_FIRST*/
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/inet.h> /*in_aton()*/
#include <net/ip.h>
#include <net/tcp.h>

#define ETHALEN 14

MODULE_LICENSE("GPL");
MODULE_AUTHOR("xu");

static struct nf_hook_ops nfho;

unsigned int checksum(unsigned int hooknum,
        struct sk_buff *__skb,
        const struct net_device *in,
        const struct net_device *out,
        int (*okfn)(struct sk_buff *))
{
    struct sk_buff *skb;
    struct net_device *dev;
    struct iphdr *iph;
    struct tcphdr *tcph;
    int tot_len;
    int iph_len;
    int tcph_len;
    int ret;

    skb = __skb;
    if (skb == NULL)
        return NF_ACCEPT;

    iph = ip_hdr(skb);
    if (iph == NULL)
        return NF_ACCEPT;

    tot_len = ntohs(iph->tot_len);

    if (iph->daddr == in_aton("10.8.8.1"))
    {
        printk("FILE: %s, LINE: %d, FUNCTION: %s:  \n", __FILE__,  __LINE__, __FUNCTION__);
        iph_len = ip_hdrlen(skb);/*in ip.h*/
        skb_pull(skb, iph_len);

        skb_reset_transport_header(skb);
        if (iph->protocol == IPPROTO_TCP)
        {
            tcph = tcp_hdr(skb);
            tcph_len = tcp_hdrlen(skb);
            if (tcph->source == htons(3306))
            {
                printk("FILE: %s, LINE: %d, FUNCTION: %s:  \n", __FILE__,  __LINE__, __FUNCTION__);

                iph->daddr = in_aton("10.8.8.128");
                dev = dev_get_by_name(&init_net, "ens33");

                tcph->check = 0;
                skb->csum = csum_partial((unsigned char *)tcph, tot_len - iph_len, 0);
                tcph->check = csum_tcpudp_magic(iph->saddr,
                        iph->daddr,
                        ntohs(iph->tot_len) - iph_len, iph->protocol,
                        skb->csum);
                iph->check = 0;
                iph->check = ip_fast_csum(iph, iph->ihl);

                skb->ip_summed = CHECKSUM_NONE;
                skb->pkt_type = PACKET_OTHERHOST;
                skb->dev = dev;
                skb_push(skb, iph_len);
                //skb_reset_transport_header(skb);

                skb_push(skb, ETHALEN);

                ret = dev_queue_xmit(skb);
                if (ret < 0)
                {
                    printk("dev_queue_xmit() error\n");
                    goto out;
                }
                printk("LINE: %d,   FUNCTION: %s\n", __LINE__, __FUNCTION__);
                return NF_STOLEN;
            }
        }
        skb_push(skb, iph_len);
        skb_reset_transport_header(skb);
    }


    return NF_ACCEPT;
out:
    dev_put(dev);

    return NF_DROP;
}

static int __init filter_init(void)
{
    int ret;
    nfho.hook = checksum;
    nfho.pf = AF_INET;
    nfho.hooknum = NF_INET_LOCAL_OUT;
    nfho.priority = NF_IP_PRI_FIRST;

    ret = nf_register_hook(&nfho);
    if (ret < 0)
    {
        printk("%s\n", "can't modify skb hook!");
        return ret;
    }

    return 0;
}

static void filter_fini(void)
{
    nf_unregister_hook(&nfho);
}

module_init(filter_init);
module_exit(filter_fini);

0 个答案:

没有答案