Изменение заголовка ip в модуле ядра разрывает соединение
У меня есть модуль ядра, в котором:
- Это изменяет поле saddr исходящих пакетов и исправляет его (daddr) в поступающих пакетах...
- Я вычисляю новую контрольную сумму для заголовков ip и tcp...
Таким образом, на стороне клиента я изменяю ip - сторона сервера получает его (пакет SYN) и отправляет (SYN-ACK) пакет - но сторона клиента - отправляет (сбрасывает) пакеты и пытается снова обработать рукопожатие tcp...
Я видел другие примеры модулей ядра - dnat / snat - мой код аналогичен? Мои be ebtables заставляют мои крюки работать неправильно?
Интерфейсы: 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 ....
=============================================================================>
*/
/ * vars.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);
}
/ * init.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);
....
}
/ * out.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;
}
/ * utils.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
1 ответ
Из того, что вы говорите, похоже, проблема в том, что вы модифицируете аспекты пакета вне стека TCP/IP. Это создает ситуацию, когда возвращаемый SYN/ACK, например, не будет связан с каким-либо соединением, о котором осведомлен стек TCP/IP, поэтому он будет реагировать путем сброса соединения.
Быстрый и грязный способ обойти это - использовать брандмауэр IPTables, чтобы система не могла отправлять исходящие RST-пакеты. Конечно, это означает, что вашему пакетному мастеру также будет запрещено отправлять исходящие RST-пакеты.
iptables -I INPUT -p tcp --tcp-flags RST RST -j DROP