有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:
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
更改源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);