iptables DNAT # extrem seltsames Phänomen

Fallaxia

Lieutenant
Registriert
Okt. 2012
Beiträge
684
Hi Leute,

ich habe bei einer Box mit Ubuntu 20.04 Server folgendes Problem:

Ich möchte an der Ubuntu Box den eingehenden NTP Traffic, Port 123 UDP an den NTP Server weiterleiten.
Dieses mache ich mit:

iptables -t nat -A PREROUTING -i ppp0 -p udp --dport 123 -j DNAT --to 192.168.100.184

Auf dem Rückweg wird Masquerading benutzt.

Klappt leider nicht, da nicht einmal Pakete an Port 123 UDP am NTP Server (192.168.100.184) ankommen.

Definiere ich z.B. eine weitere Regel, nur für Port 124 also so z.B.

iptables -t nat -A PREROUTING -i ppp0 -p udp --dport 124 -j DNAT --to 192.168.100.184

In diesem Fall kommen alle an Port 124 gesendeten Pakete an, getestet mit Netcat + iptraf-ng

Egal was ich mache, alle Ports lassen sich weiterleiten mit DNAT. Nur Port 123 UDP nicht.
Die Firewall, die Port 123 UDP mittles DNAT weiterleiten soll, sendet auch keine Pakete ab, die ankommen könnten, aber eben nur bei Port 123 UDP, nicht bei 124 oder 123 TCP

Was mache ich falsch?



Firewall ist hier ein Ubuntu 20.04 Server, Timeserver ein Meinberg Lantime 350 (zum Testen hab ich auch andere Linux-Boxen genutzt + Wireshark etc.

//Mir ist bewusst, das Ubuntu 20.04 nicht das perfekte Firewall OS ist. In diesem Fall aber aufgrund der DSL Hardware (Vigornic 132 PCI-E Modem) nicht wirklich mit PFsense etc. lösbar.
 
Grundsätzlich wird der NTP Server als Option 42 im DHCP angegeben.
Jeder DHCP Client bekommt dann automatisch den richtigen NTP im Netzwerk.

Deine iptables Regel sind eigentlich gut aus. Mir ist jedoch deine Konstellation nicht ganz klar.
Dein Gateway ist auch Zeitserver? Wozu dann iptables? Der Zeitserver kann doch auch im Netzwerk einen Broadcast senden oder auf eintreffende Pakete warten / ("Listen to port 123 on interface ... ")
 
Zuletzt bearbeitet:
Der Zeitserver bedient externe Clients. Er ist hinter dem Gateway/Firewall. Somit müssen die externen Anfragen vom Gateway an den internen Zeitserver mittels DNAT weiter geleitet werden.

Im lokalen Netz bedient der Zeitserver nix.
 
Fallaxia schrieb:
In diesem Fall kommen alle an Port 124 gesendeten Pakete an, getestet mit Netcat + iptraf-ng
[..]
Die Firewall, die Port 123 UDP mittles DNAT weiterleiten soll, sendet auch keine Pakete ab, die ankommen könnten,
Das hat du wo/wie genau getestet? Hast du auf der Ubuntu-Kiste geprüft ob die Pakete rausgehen oder auf dem NTP-Server (192.168.100.184) mittels WireShark bzw. tcpdump geprüft ob die Pakete ankommen? Letzteres ist zu bevorzugen.


Was mich etwas stutzig macht ist, dass das nur bei UDP 123 so sein soll. Eigentlich findet DNAT vor dem Routing, inkl. der möglichen lokalen Verabeitung statt -daher ja auch die PREROUTING-Chain - aber wenn das explizit nur bei UDP 123 passiert, stellt sich mir die Frage ob Ubuntu den eingehenden Traffic womöglich dennoch selbst bearbeitet. Prüfe mal ob dort ein Dienst auf UDP 123 läuft (netstat -tulpen). Wenn dem so ist, schalte ihn testweise mal ab.
Ergänzung ()

Prüfe zudem bitte auch die FORWARD Chain in der filter table. In dieser muss UDP 123 per ACCEPT erlaubt sein. Wichtig ist hierbei, dass Pakete, die dort ankommen, bereits durch die nat table verändert wurden. Das heißt, dass in filter.FORWARD auf Basis der geänderten Destination-IP gematched werden muss und nicht auf die lokale IP von Ubuntu. Das ist natürlich nur dann relevant, wenn in filter.FORWARD überhaupt mittels Destination-IP gefiltert wird.

Beispiel:

iptables -t nat
---> PREROUTING : dst-port udp 123 --> DNAT to 192.168.100.184

iptables -t filter
---> FORWARD : Policy ACCEPT und kein weiterer match mit drop/deny
oder
---> FORWARD : ACCEPT dst-port udp 123
oder
---> FORWARD : ACCEPT dst-port udp 123 & dst-ip 192.168.100.184


Die Destination-IP ist in der FORWARD Chain der filter table rein optional, aber WENN man darauf matched, dann muss es die geDNATtete IP sein.


In vereinfachter Form sieht der Ablauf so aus:

nat.PREROUTING (aka DNAT) ---> filter.FORWARD ---> nat.POSTROUTING (aka SNAT)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: snaxilian
Der netstat output zeigt keinen Dienst auf Port 123 UDP, aber selbst wenn, so würde er durch das Prerouting übergangen.
Ich habe eben in einer VM, frisch installiert, ausprobiert was passiert wenn z.B. ein NTP Server am Laufen ist.
Das NAT Prerouting funktioniert auch dann einwandfrei und leitet die eingehenden Pakete zur internen Ziel IP.

Es muss also etwas vor iptables / dem Routing sein, wass die auf Port 123 UDP eingehenden Pakete bereits erfasst.
Lokal kommen sie übrigens an, also wenn ich auf dem Gateway/Firewall einen NTP Server Dienst laufen lasse, so erhält dieser alle ankommenden Pakete auf Port 123 UDP und beantwortet diese.

Trage ich dann aber die Regel

iptables -t nat -A PREROUTING -i ppp0 -p udp --dport 123 -j DNAT --to 192.168.100.184

ein, so ändert das rein gar nichts. Alle Pakete für Port 123 UDP werden lokal zugestellt.

Was die FORWARD Cahin angeht -- irrelevant, denn wie gesagt, auf allen anderen Ports funktioniert das Prerouting wie erwartet, nur auf Port 123 UDP nicht, da wird es einfach ignoriert. Die Pakete werden lokal zugestellt, am externen Interface, hier ppp0

Irgendeine Idee dazu?
 
Fallaxia schrieb:
Was die FORWARD Cahin angeht -- irrelevant, denn wie gesagt, auf allen anderen Ports funktioniert das Prerouting wie erwartet, nur auf Port 123 UDP nicht,
Aha. Und du weißt schon was die FORWARD Chain in der filter table tut, oder? Scheint mir irgendwie nicht so, sonst hättest du einfach mal nachgeschaut bevor du das so wegwischst. Zur Frage wie du testest auch keine Antwort.

Naja, wenn du genau weißt was wieso und wieso nicht, brauchst du uns ja nicht. Wer nicht will, der hat schon.. :freak:
 
@Raijin

Sollte nicht bös oder arogant gemeint sein, sondern nur, dass die FORWARD Chain auf ACCEPT steht.

Hier die Übersicht der schnell zusammen gebauten iptables Regeln:
Ist kein fertiges Werk, nur ganz grob, aber es funktioniert jetzt.

Der Grund, warum es vorher nicht funktioniert hat waren zwei Zeilen:

-A PREROUTING -p udp -m udp --dport 123 -j NOTRACK -A OUTPUT -p udp -m udp --sport 123 -j NOTRACK

Ich hatte das Regelwerk mit Webmin auf die Schnelle erstellt und es hat beim Erstellen die beiden Regeln übernommen, die gerade zu dem Zeitpunkt der Erstellung aktiv waren. Diese beiden Regeln finden sich aber in der grafischen Webmin Konfiguration nicht visuell wieder, so dass ich davon ausging, alle Regeln wären richtig und vorhanden.
Aber die beiden führten natürlich dazu, dass alle anderen DNAT Regeln für Port 123 UDP einfach nicht zur Anwendung kamen, da vorher ein Match gefunden wurde.

Die aktuell krude, aber funktionale iptables config:

# Generated by iptables-save v1.8.4 on Thu May 14 00:28:42 2020 *mangle :PREROUTING ACCEPT [134828:10590997] :INPUT ACCEPT [132166:10071674] :FORWARD ACCEPT [2614:515131] :OUTPUT ACCEPT [124777:9636366] :POSTROUTING ACCEPT [127392:10151575] -A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu -A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu COMMIT # Completed on Thu May 14 00:28:42 2020 # Generated by iptables-save v1.8.4 on Thu May 14 00:28:42 2020 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT -A INPUT -m conntrack --ctstate RELATED -j ACCEPT -A INPUT -p udp -m udp -i ppp0 --dport 123 -j ACCEPT -A INPUT -i br0 -j ACCEPT -A INPUT -i enp3s0 -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -p tcp -m tcp -m multiport -i ppp0 -j REJECT --reject-with icmp-port-unreachable --dports 135,137,138,139,445 -A INPUT -p udp -m udp -m multiport -i ppp0 -j REJECT --reject-with icmp-port-unreachable --dports 135,137,138,139,445 -A INPUT -p tcp -m tcp -m multiport -i ppp0 -j DROP --dports 22,23,3389 -A INPUT -p udp -m udp ! -s 192.168.100.0/24 -i ppp0 --dport 2 -j ACCEPT -A INPUT -m limit -i ppp0 --limit 20/sec --limit-burst 100 -j LOG -A INPUT -j DROP -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu COMMIT # Completed on Thu May 14 00:28:42 2020 # Generated by iptables-save v1.8.4 on Thu May 14 00:28:42 2020 *raw :PREROUTING ACCEPT [1585400128:162101625084] :OUTPUT ACCEPT [1207010183:112478323827] COMMIT # Completed on Thu May 14 00:28:42 2020 # Generated by iptables-save v1.8.4 on Thu May 14 00:28:42 2020 *nat :OUTPUT ACCEPT [0:0] :PREROUTING ACCEPT [0:0] :INPUT DROP [0:0] :POSTROUTING ACCEPT [0:0] -A PREROUTING -p udp -m udp ! -s 192.168.100.0/24 -i ppp0 --dport 123:123 -j DNAT --to-destination 192.168.100.17-192.168.100.17:123-123 -A PREROUTING -p tcp -m tcp ! -s 192.168.100.0/24 -i ppp0 --dport 80 -j DNAT --to-destination 192.168.100.8:80 -A PREROUTING -p tcp -m tcp ! -s 192.168.100.0/24 -i ppp0 --dport 25 -j DNAT --to-destination 192.168.100.8:25 -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT -A INPUT -m conntrack --ctstate RELATED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -i br0 -j ACCEPT -A INPUT -i enp3s0 -j ACCEPT -A INPUT -p udp -m udp ! -s 192.168.100.0/24 -i ppp0 --dport 37 -j ACCEPT -A INPUT -p tcp -m tcp ! -s 192.168.100.0/24 -i ppp0 --dport 37 -j ACCEPT -A INPUT -p udp -m udp --dport 1024:65535 --sport 53 -j ACCEPT -A INPUT -p udp -m udp ! -s 192.168.100.0/24 -i ppp0 --dport 2 -j ACCEPT -A INPUT -p icmp -j ACCEPT -A POSTROUTING -o ppp0 -j MASQUERADE -A PREROUTING -p tcp -m tcp ! -s 192.168.100.0/24 -i ppp0 --dport 993 -j DNAT --to-destination 192.168.100.8:993 COMMIT # Completed on Thu May 14 00:28:42 2020

Ist natürlich wie gesagt keinesfalls fertig und nur das Gröbste.

Ich danke Allen, die mir mit Tipps und Ideen weitergeholfen haben, insbesondere Raijin der mich durch den Hinweis auf die FORWARD Chain die Konfiguration auch mal in plain text anschauen lies.
 
  • Gefällt mir
Reaktionen: Raijin
Fallaxia schrieb:
Der Grund, warum es vorher nicht funktioniert hat waren zwei Zeilen:

-A PREROUTING -p udp -m udp --dport 123 -j NOTRACK -A OUTPUT -p udp -m udp --sport 123 -j NOTRACK
Und als du diese Regeln entfernt hast, hat es funktioniert? Das kann ich nicht wirklich nachvollziehen. Die OUTPUT chain ist bei geroutetem Traffic in keinster Weise involviert, weil sich INPUT und OUTPUT ausschließlich auf Traffic beziehen, der an einen lokalen Dienst gerichtet ist oder von diesem generiert wird. Die zweite Regel bezieht sich also lediglich auf einen lokalen NTP-Dienst des Systems, der via OUTPUT auf eine Anfrage antwortet.

Bei der ersten Regel wiederum wird lediglich das connection tracking abgeschaltet. D.h. conntrack prüft nicht mehr auf den connection state NEW, ESTABLISHED, RELATED bzw. INVALID. Da ich aber keine Regel entdecken kann, die explizit bei udp 123 bezüglich conntrack blocken würde, erschließt sich mir auch hier nicht warum das Entfernen der Regel helfen sollte?! Alle Regeln, die den conntrack matchen, befinden sich in den INPUT chains, die ja wie gesagt gar nicht beteiligt sind. Die FORWARD chain steht auf ACCEPT, das heißt jeglicher weitergeleiteter Traffic hätte ungeachtet des connection states weitergeleitet werden sollen.

Nachvollziehbar oder nicht, ich sag's mal so: Hauptsache es funktioniert jetzt!

:schluck:
 
Zurück
Oben