Warum FTP-Listen hinter einem VPN-Gateway mit NAT hängen
Anmeldung und PWD klappen, während LIST und RETR hängen bleiben, wenn NAT nur Header umschreibt. Lesen Sie, wo der FTP-Helfer sitzen muss und wie man den passiven Modus repariert.
Die Anmeldung funktioniert, PWD funktioniert, und dann hängt LIST, bis der Client aufgibt oder in einen anderen Datenmodus wechselt. Diese Trennung ist die Signatur: Die Steuerverbindung zu Port 21 ist gesund, während die Datenverbindung aus einer Adresse oder einem Port aufgebaut wird, die die Gegenseite nicht erreichen kann. Hinter einem VPN-Gateway, das auch NAT macht, ist der übliche Übeltäter ein FTP-Befehl, dessen Nutzlast eine Tunneladresse wie 10.8.0.6 nennt. Die Header-Übersetzung berührt diesen Wert nie.
Im Folgenden geht es darum, woher dieser Wert kommt und welche Box ihn ändern darf.
Es bricht die Nutzlast, nicht der Tunnel
FTP legt den Datenendpunkt in den Steuerstrom. Im aktiven Modus schickt der Client PORT mit seiner eigenen Adresse und seinem Port, und der Server wählt diesen Tupel zurück an. Im passiven Modus antwortet der Server mit 227 und einem Tupel, und der Client wählt stattdessen dieses an.
Beide Formen tragen dieselbe Art Aussage: verbinde dich mit dieser Adresse, an diesem Port. Ein Gerät, das nur IP- und TCP-Header umschreibt, lässt die Aussage unangetastet, also versucht ein Ende weiterhin, eine Adresse zu erreichen, die nur auf der anderen Seite eines Tunnels existiert. Die Datenverbindung bleibt hängen, nachdem die Steuerverbindung bereits für gut erklärt wurde.
Drei Modi, drei Nutzlasten
Die Tabelle unten zeigt, welche Seite aufgefordert wird zu wählen, und was ein NAT, das nur Header umschreibt, dagegen tun kann.
Lesen Sie die letzte Spalte als das, was zuerst ausfällt. Im aktiven Modus ist es der Server, der eine private Adresse anwählt; im passiven Modus ist es der Client; bei FTPS ist die Nutzlast Geheimtext und die Middlebox hat noch weniger, womit sie arbeiten kann.
| Mode | Value in the control stream | Who dials whom | Header-only NAT leaves |
|---|---|---|---|
| Active (PORT) | client address and port | server dials the client | a server dialing an unreachable tunnel address |
| Passive (227) | server address and port | client dials the server | a client dialing an address it cannot route to |
| FTPS | the same values, inside TLS | as above | ciphertext, so no rewrite happens at all |
Setzen Sie den Helfer dorthin, wo die Übersetzung passiert
Unter Linux erledigt der Helfer nf_conntrack_ftp das Umschreiben der Nutzlast. Er beobachtet die Steuerverbindung, lernt den ausgehandelten Port, legt eine Erwartung für den Datenfluss an und schreibt auf einer NAT-Box Adresse und Port innerhalb der Nutzlast um. Er hilft nur auf dem Gerät, das die Client-Adresse übersetzt. Ihn auf dem Client zu laden oder auf einem Router, der den Fluss bloß weiterleitet, ändert an der Sitzung nichts.
Diese drei Befehle zeigen, ob das Modul vorhanden ist, ob es angehängt ist und ob während einer offenen Sitzung eine Erwartung besteht:
modprobe nf_conntrack_ftp
lsmod | grep nf_conntrack_ftp
conntrack -L expect | grep ftp
Das Modul zu laden ist nicht dasselbe, wie es anzuhängen. Kernel ab 4.7 kommen mit net.netfilter.nf_conntrack_helper=0, also wartet der Helfer auf eine ausdrückliche Regel, zum Beispiel iptables -t raw -A PREROUTING -p tcp --dport 21 -j CT --helper ftp. Bleibt die Erwartungsliste leer, während eine Übertragung versucht wird, ist die Anhängung zu prüfen, nicht das Modul.
Passiver Modus: Sagen Sie dem Server, was er anbieten soll
Der passive Modus lässt sich leichter deterministisch machen, weil man dem Server sagen kann, was er in die 227-Antwort schreiben soll. In vsftpd ist das pasv_address, zusammen mit pasv_min_port und pasv_max_port; ProFTPD nutzt MasqueradeAddress und PassivePorts. Setzen Sie diese zuerst, denn eine korrekt angebotene Adresse erspart es, auf jener Seite irgendetwas umzuschreiben.
Lassen Sie dann genau diesen Portbereich durch das Gateway, zum Beispiel -A FORWARD -i tun0 -p tcp --dport 30000:30100 -j ACCEPT, damit die Regel zu dem passt, was der Server anbietet.
Die beiden Einstellungen müssen übereinstimmen. Ein Server, dem gesagt wird, er solle 30000-30100 anbieten, während das Gateway 40000-40100 erlaubt, scheitert auf die am wenigsten hilfreiche Weise: Das Steuergespräch sieht gesund aus, und jede Datenverbindung stirbt. Vergleichen Sie die Zahlen, bevor Sie irgendetwas anderes debuggen.
Zwei Fehlersignaturen und was FTPS beseitigt
Ein Hänger bei LIST deutet auf die erste Datenverbindung der Sitzung hin, wo sowohl Adressumschreibung als auch Erwartung funktionieren müssen. Ein Hänger bei RETR nach einem funktionierenden LIST deutet auf die Übertragung selbst hin, also auf den passiven Bereich oder die MTU des Tunnels. Diese zweite Signatur ist kein Nutzlastproblem, und Helfer-Einstellungen beheben sie nicht.
FTP über TLS entfernt die Nutzlast, die der Helfer liest. Eine Middlebox kann einen PORT- oder PASV-Wert nicht umschreiben, den sie nicht entschlüsseln kann, also bleiben ein Proxy, der TLS beendet, ein Server, der eine erreichbare Adresse in einem begrenzten Bereich anbietet, oder ein anderes Übertragungsprotokoll.
Eine kurze Reihenfolge der Prüfungen
Arbeiten Sie sich vom Symptom nach außen vor. Bestätigen Sie, dass LIST scheitert, während PWD gelingt, fangen Sie die Adresse in der PORT- oder 227-Nutzlast ab und fragen Sie, welches Gerät diese Adresse übersetzt. Hängen Sie den Helfer dort an, beobachten Sie die Erwartungsliste während einer Übertragung, reparieren Sie dann den passiven Modus auf dem Server und spiegeln Sie den Bereich in der Gateway-Regel.
Halten Sie den Datenpfad-Fehler vom Massenübertragungs-Fehler getrennt, weil sie Sie zu verschiedenen Einstellungen schicken.