Iptables - GRE-Verbindung zwischen genatteter und nicht-genatteter VM mit KVM als Hypervisor

Moin,

ich habe folgende Situation:

  • Ubuntu 16.04 KVM Hypervisor, darauf
    • Gateway-VM GRE genattet
    • Kartenserver mit öffentlicher IPV4 über br0 auf dem Hypervisor

Die iptables-Konfiguration sieht dementsprechend so aus:

root@unimatrixzero ~ # iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A PREROUTING -d 176.9.38.150/32 -p tcp -m tcp --dport 222 -j DNAT --to-destination 192.168.10.35:22
-A PREROUTING -d 176.9.38.150/32 -p udp -m udp --dport 20000:20100 -j DNAT --to-destination 192.168.10.35:20000-20100
-A PREROUTING -d 176.9.38.150/32 -p gre -j DNAT --to-destination 192.168.10.35
-A POSTROUTING -s 192.168.10.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.10.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.0/24 -j MASQUERADE

Die 176.9.38.150 ist die Blech-IP. Die 176.9.38.157 die IP des Kartenservers. Die beiden sind über Gretap verbunden. Leider funktioniert die Verbindung nicht.

Nun kann man auf dem Hypervisor die Batman-Pakete sichtbar machen, die vom Kartenserver kommen:

# tcpdump -ni any proto gre and src host 176.9.38.157
23:15:07.612691 IP 176.9.38.157 > 176.9.38.150: GREv0, key=0x1, length 74: de:ad:be:ef:02:12 > ff:ff:ff:ff:ff:ff, ethertype Unknown (0x4305), length 66: 
    0x0000:  000f 3202 93da 904d dead beef 0212 dead  ..2....M........
    0x0010:  beef 0212 00ff 001c 0401 000c 0101 0001  ................
    0x0020:  3865 7178 0000 0000 0601 0004 0000 0000  8eqx............
    0x0030:  0201 0000                                ....
23:15:07.612691 IP 176.9.38.157 > 176.9.38.150: GREv0, key=0x1, length 74: de:ad:be:ef:02:12 > ff:ff:ff:ff:ff:ff, ethertype Unknown (0x4305), length 66: 
    0x0000:  000f 3202 93da 904d dead beef 0212 dead  ..2....M........
    0x0010:  beef 0212 00ff 001c 0401 000c 0101 0001  ................
    0x0020:  3865 7178 0000 0000 0601 0004 0000 0000  8eqx............
    0x0030:  0201 0000

Alle Pakete sind doppelt, wie oben das Beispielpaket. Aber das ausgehende Paket wird nicht genattet und kommt daher in der genatteten Gateway-VM nicht an.

root@karte ~ # batctl -m bat01 o
[B.A.T.M.A.N. adv 2015.2, MainIF/MAC: t01-gw03/de:ad:be:ef:02:12 (bat01 BATMAN_IV)]
  Originator      last-seen (#/255)           Nexthop [outgoingIF]:   Potential nexthops ...
No batman nodes in range ...
root@karte ~ # batctl -m bat01 if
t01-gw03: active

Die Pakete von außen werden korrekt genattet, z. B. wie dieses hier vom FFRL-Backbone:

23:18:26.113956 IP 185.66.194.0 > 192.168.10.35: GREv0, length 1284: IP6 2a00:1450:401e:3a::b.443 > 2a03:2260:1010:2300:68d3:72ae:b9ca:406d.50215: Flags [.], seq 709040:710260, ack 1, win 166, length 1220

Weiß jemand, wie ich das repariert bekomme? Der iptables-Befehl müsste eigentlich alle Pakete erfassen, die zum Gateway gehen.

Grüße
Matthias

In der Tat komisch.
Vermutlich sehe ich das Problem nicht, aber wenn such nur die beiden lokal u Tierhaltung sollen, dann Klemme doch eine bridge/vswitch dazwischen. Da kannst Du dann nach Lust und Laune ein Transfernetz direkt oder meinetwegen auch Batman drauf sprechen.

Wegen Ansible müssen die Tunnel mit der öffentlichen IP der VM gebaut werden.

Für performante virtuelle Kabel (über br0 des Hypervisors lahmt es ganz schön, wenn zwei VMs auf demselben Blech miteinander sprechen) baue ich normaler Weise ein ethx mit einer /32-Route auf diesem Interface für alle VMs auf demselben Blech.

Beispiel:

auto eth1
iface eth1 inet static
    address 192.168.254.1
    netmask 31
    post-up ip route add 144.76.81.139/32 via 192.168.254.0

Da aber hier die öffentliche IP auch noch das Defaultgateway - nämlich das Blech - ist, müsste ich das nach Port aufteilen. Und das geht glaube ich nicht ohne iptables-Kette und einer zweiten Routingtabelle. Das ist mir ein wenig aufwändig.

Ich würde lieber iptables weiter verstehen. Rein praktisch baue ich es gerade über IPV6. Trotzdem würde ich gerne den Fehler oben verstehen.

Grüße
Matthias