Re: GRE-NAT broken

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I looked into this a little further: From what I've found in the source
code GRE NAT has never been properly implemented.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/net/ipv4/netfilter/nf_nat_proto_gre.c?id=HEAD

|switch (greh->flags & GRE_VERSION) { case GRE_VERSION_0: /* We do not
currently NAT any GREv0 packets. * Try to behave like
"nf_nat_proto_unknown" */ break; case GRE_VERSION_1: pr_debug("call_id
-> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); pgreh->call_id =
tuple->dst.u.gre.key; break; default: pr_debug("can't nat unknown GRE
version\n"); return false; } How did this work before? Or am I looking
at the wrong place? Regards, Matthias |



Am 24.01.2018 um 20:54 schrieb Matthias Walther:
> Hello,
>
> I used to nat GRE-tunnels into a kvm machine. That used to work
> perfectly, till it stopped working in early January.
>
> I'm not really sure, what caused this malfunction. I tried different
> kernel versions, 4.4.113, 4.10.0-35, 4.10.0-37, 4.14. All on ubuntu 16.04.3.
>
> Normal destination based nat rules, like ssh tcp 22 e. g., work
> perfectly. That gre nat rule is in place:
>
> -A PREROUTING -i eth0 -p gre -j DNAT --to-destination 192.168.10.62
>
> And the needed kernel modules are loaded:
>
> root# lsmod|grep gre
> 61:nf_conntrack_proto_gre    16384  0
> 62:nf_nat_proto_gre       16384  0
> 63:nf_nat                 24576  4
> nf_nat_proto_gre,nf_nat_ipv4,xt_nat,nf_nat_masquerade_ipv4
> 64:nf_conntrack          106496  6
> nf_conntrack_proto_gre,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4
>
> Still some packes are just not correctly natted. The configuration
> should be correct, as it used to work like this.
>
> One or two tunnels usually work. For the others, the gre packages are
> just not natted but dropped. First example, which shows the expected
> behavior:
>
> root# tcpdump -ni any host 185.66.195.1 <http://185.66.195.1> and \(
> host 176.9.38.150 or host 192.168.10.62 <http://192.168.10.62> \) and
> proto 47 and ip[33]=0x01 and \( ip[36:4]==0x644007BA or
> ip[40:4]==0x644007BA \)
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on any, link-type LINUX_SLL (Linux cooked), capture size
> 262144 bytes
> 04:06:41.322914 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.1
> <http://185.66.195.1>: GREv0, length 88: IP 185.66.194.49
> <http://185.66.194.49> > 100.64.7.186: ICMP echo request, id 26639, seq
> 1, length 64
> 04:06:41.322922 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.1
> <http://185.66.195.1>: GREv0, length 88: IP 185.66.194.49
> <http://185.66.194.49> > 100.64.7.186: ICMP echo request, id 26639, seq
> 1, length 64
> 04:06:41.322928 IP 176.9.38.150 > 185.66.195.1 <http://185.66.195.1>:
> GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> >
> 100.64.7.186: ICMP echo request, id 26639, seq 1, length 64
> 04:06:41.341906 IP 185.66.195.1 <http://185.66.195.1> > 176.9.38.150:
> GREv0, length 88: IP 100.64.7.186 > 185.66.194.49
> <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1, length 64
> 04:06:41.341915 IP 185.66.195.1 <http://185.66.195.1> > 192.168.10.62
> <http://192.168.10.62>: GREv0, length 88: IP 100.64.7.186 >
> 185.66.194.49 <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1,
> length 64
> 04:06:41.341918 IP 185.66.195.1 <http://185.66.195.1> > 192.168.10.62
> <http://192.168.10.62>: GREv0, length 88: IP 100.64.7.186 >
> 185.66.194.49 <http://185.66.194.49>: ICMP echo reply, id 26639, seq 1,
> length 64
>
> This^^ works as it should. The packet goes through the bridge interface,
> then the bridge though which all natted vms are connected, then it is
> translated and then through the eth0 interface of the hypervisor. And
> the reply packages follows in reverse direction. The nat works, the
> address is translated. Not so in the second case:
>
> root@# tcpdump -ni any host 185.66.195.0 and \( host 176.9.38.150 or
> host 192.168.10.62 <http://192.168.10.62> \) and proto 47 and
> ip[33]=0x01 and \( ip[36:4]==0x644007B4 or ip[40:4]==0x644007B4 \)
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on any, link-type LINUX_SLL (Linux cooked), capture size
> 262144 bytes
> 03:58:01.972551 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0:
> GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> >
> 100.64.7.180: ICMP echo request, id 25043, seq 1, length 64
> 03:58:01.972554 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0:
> GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> >
> 100.64.7.180: ICMP echo request, id 25043, seq 1, length 64
> 03:58:03.001013 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0:
> GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> >
> 100.64.7.180: ICMP echo request, id 25043, seq 2, length 64
> 03:58:03.001021 IP 192.168.10.62 <http://192.168.10.62> > 185.66.195.0:
> GREv0, length 88: IP 185.66.194.49 <http://185.66.194.49> >
> 100.64.7.180: ICMP echo request, id 25043, seq 2, length 64
>
> tcpdump catches the outgoing package. But instead of being translated,
> it's dropped.
>
> Any ideas, how I could analyse this? All tested kernels showed the exact
> same behavior. It's as if only one gre nat connection was possible.
>
> Regards,
> Matthias
>
> --
> To unsubscribe from this list: send the line "unsubscribe lartc" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe lartc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux