Het inloggen werkt, PWD werkt, en dan blijft LIST hangen tot de client opgeeft of naar een andere datamodus overstapt. Die splitsing is de signatuur: de controleverbinding naar poort 21 is gezond, terwijl de dataverbinding wordt opgebouwd vanuit een adres of poort die de andere kant niet kan bereiken. Achter een VPN-gateway die ook NAT doet, is de gebruikelijke boosdoener een FTP-commando waarvan de payload een tunneladres zoals 10.8.0.6 noemt. Headervertaling raakt die waarde nooit.

Wat volgt is waar die waarde vandaan komt, en welke doos die mag wijzigen.

Wat breekt is de payload, niet de tunnel

FTP zet het data-eindpunt in de controlestroom. In actieve modus stuurt de client PORT met zijn eigen adres en poort, en de server belt terug naar dat tupel. In passieve modus antwoordt de server met 227 en een tupel, en de client belt in plaats daarvan dat aan.

Beide vormen dragen dezelfde soort uitspraak: verbind met dit adres, op deze poort. Een apparaat dat alleen IP- en TCP-headers herschrijft laat de uitspraak met rust, dus één kant blijft proberen een adres te bereiken dat alleen aan de andere kant van een tunnel bestaat. De dataverbinding loopt vast nadat de controleverbinding al gezond is verklaard.

Drie modi, drie payloads

De tabel hieronder laat zien welke kant wordt opgedragen te bellen, en wat een NAT die alleen headers herschrijft daaraan kan doen.

Lees de laatste kolom als dat wat het eerst faalt. In actieve modus is de server degene die een privéadres belt; in passieve modus is dat de client; bij FTPS is de payload versleutelde tekst en heeft de tussenbox nog minder om mee te werken.

ModeValue in the control streamWho dials whomHeader-only NAT leaves
Active (PORT)client address and portserver dials the clienta server dialing an unreachable tunnel address
Passive (227)server address and portclient dials the servera client dialing an address it cannot route to
FTPSthe same values, inside TLSas aboveciphertext, so no rewrite happens at all

Zet de helper waar de vertaling gebeurt

Op Linux doet de helper nf_conntrack_ftp het herschrijven van de payload. Hij houdt de controleverbinding in de gaten, leert de poort die is onderhandeld, maakt een verwachting voor de datastroom en herschrijft op een NAT-doos het adres en de poort binnen de payload. Hij helpt alleen op het apparaat dat het clientadres vertaalt. Hem op de client laden, of op een router die de stroom alleen doorstuurt, verandert niets aan de sessie.

Deze drie commando's laten zien of de module aanwezig is, of hij is aangekoppeld en of er een verwachting bestaat terwijl een sessie open is:

modprobe nf_conntrack_ftp
lsmod | grep nf_conntrack_ftp
conntrack -L expect | grep ftp

De module laden is niet hetzelfde als hem aankoppelen. Kernels vanaf 4.7 komen met net.netfilter.nf_conntrack_helper=0, dus de helper wacht op een uitdrukkelijke regel, bijvoorbeeld iptables -t raw -A PREROUTING -p tcp --dport 21 -j CT --helper ftp. Als de verwachtingslijst leeg blijft terwijl een overdracht wordt geprobeerd, is de aankoppeling wat gecontroleerd moet worden, niet de module.

Passieve modus: vertel de server wat hij moet adverteren

Passieve modus is makkelijker deterministisch te maken omdat de server kan worden verteld wat hij in het 227-antwoord moet zetten. In vsftpd is dat pasv_address, samen met pasv_min_port en pasv_max_port; ProFTPD gebruikt MasqueradeAddress en PassivePorts. Stel die eerst in, want een correct geadverteerd adres haalt de noodzaak weg om aan die kant iets te herschrijven.

Laat dan precies die poortenreeks door de gateway, bijvoorbeeld -A FORWARD -i tun0 -p tcp --dport 30000:30100 -j ACCEPT, zodat de regel overeenkomt met wat de server adverteert.

De twee instellingen moeten overeenkomen. Een server die wordt opgedragen 30000-30100 te adverteren terwijl de gateway 40000-40100 toestaat, faalt op de minst behulpzame manier: het controlegesprek ziet er gezond uit en elke dataverbinding sterft. Vergelijk de getallen voordat u iets anders debugt.

Twee faalsignaturen, en wat FTPS wegneemt

Een hang op LIST wijst op de eerste dataverbinding van de sessie, waar zowel het herschrijven van het adres als de verwachting moeten werken. Een hang op RETR na een werkende LIST wijst op de overdracht zelf, dat wil zeggen de passieve reeks of de MTU van de tunnel. Die tweede signatuur is geen payloadprobleem, en helperinstellingen lossen hem niet op.

FTP over TLS neemt de payload weg die de helper leest. Een tussenbox kan een PORT- of PASV-waarde niet herschrijven die hij niet kan ontsleutelen, dus blijven over een proxy die TLS beëindigt, een server die een bereikbaar adres binnen een begrensd bereik adverteert, of een ander overdrachtsprotocol.

Een korte volgorde van controles

Werk van het symptoom naar buiten. Bevestig dat LIST faalt terwijl PWD slaagt, vang het adres in de PORT- of 227-payload, en vraag welk apparaat dat adres vertaalt. Koppel de helper daar aan, houd de verwachtingslijst in de gaten tijdens één overdracht, repareer daarna de passieve modus op de server en spiegel de reeks in de gatewayregel.

Houd de fout in het datapad gescheiden van de fout bij bulkoverdracht, omdat ze u naar verschillende instellingen sturen.

Gerelateerde artikelen