[OpenBSD]

[Vorige: Prestatie] [Inhoud] [Volgende: Authpf: Gebruiker-Shell voor Authentiserende Gateways]

PF: Problemen met FTP


Inhoudsopgave


FTP Modi

FTP is een protocol dat dateert van toen het Internet een kleine, vriendelijke verzameling computers was en iedereen iedereen kende. In die tijd was er geen nood aan filtering of aan strikte beveiliging. FTP werd niet ontworpen om te filteren, om doorheen firewalls te passeren, of om te werken met NAT.

U kan FTP op één van twee manieren gebruiken: passief of actief. In het algemeen wordt de keuze tussen actief of passief gemaakt om te bepalen wie het probleem met firewalling heeft. Realistisch gezien zal u beide moeten ondersteunen om gelukkige gebruikers te hebben.

Bij actieve FTP maakt de FTP server een nieuwe verbinding terug naar de client om de opgevraagde gegevens over te dragen, wanneer een gebruiker verbindt naar een remote FTP server en informatie of een bestand opvraagt. Dit wordt de data connection genoemd. Om te beginnen kiest de FTP client een willekeurige (random) poort om de "data connection" op te ontvangen. De client stuurt het poortnummer dat hij koos naar de FTP server en luistert dan naar een binnenkomende verbinding op die poort. De FTP server initieert vervolgens een verbinding naar het adres van de client op de gekozen poort en transfereert de gegevens. Dit is een probleem voor gebruikers die proberen toegang te verkrijgen tot FTP servers van achter een NAT gateway. Omwille van hoe NAT werkt, initieert de FTP server de "data connection" door te verbinden naar het externe adres van de NAT gateway op de gekozen poort. De NAT machine zal dit ontvangen, maar omdat hij geen afbeelding heeft voor het pakket in zijn toestandstabel, zal hij het pakket laten vallen en zal het niet aan de client bezorgen.

Bij passieve FTP modus (de standaard modus voor OpenBSD's ftp(1) client), vraagt de client aan de server een willekeurige poort te kiezen om op te luisteren voor de "data connection". De server informeert de client over de poort die hij gekozen heeft, en de client verbindt naar deze poort om de gegevens te transfereren. Jammer genoeg is dit niet altijd mogelijk of wenselijk omwille van de mogelijke aanwezigheid van een firewall vóór de FTP server die de binnenkomende "data connection" blokkeert. OpenBSD's ftp(1) gebruikt standaard de passieve modus; om actieve FTP te forceren, gebruikt u de -A vlag voor ftp, of stelt u passive mode in op "off" door het commando "passive off" uit te voeren op de "ftp>" prompt.

FTP Client achter de Firewall

Zoals eerder aangegeven, gaat FTP niet erg goed doorheen NAT en firewalls.

Packet Filter voorziet een oplossing voor deze situatie door FTP verkeer om te leiden doorheen een FTP proxy server. Dit proces grijpt in om uw FTP verkeer doorheen de NAT gateway/firewall te "gidsen". De FTP proxy die gebruikt wordt door OpenBSD en PF, is ftp-proxy(8). Om het te activeren, zet u iets als dit in de NAT sectie van pf.conf:

rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
   port 8021

De verklaring van deze lijn is: "Verkeer op de interne interface wordt omgeleid naar de proxy server die op deze machine draait en luistert op poort 8021".

Hopelijk is het duidelijk dat de proxy server gestart moet worden en moet draaien op de OpenBSD machine. Dit wordt gedaan door de volgende lijn in te voegen in /etc/inetd.conf:

127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \
   ftp-proxy -n

Merk op dat de -n vlag alleen nodig is als de OpenBSD machine NAT uitvoert. Stuur nu een 'HUP' signaal naar inetd(8) om het zijn configuratiebestand opnieuw te laten lezen. Eén manier om het 'HUP' signaal te sturen is met het commando:

kill -HUP `cat /var/run/inetd.pid`

U zal opmerken dat de ftp-proxy luistert op poort 8021, dezelfde poort waar de bovenstaande rdr opdracht FTP verkeer naartoe stuurt. De keuzen van poort 8021 is willekeurig, hoewel 8021 een goede keuze is aangezien deze voor geen enkele andere toepassing gedefinieerd is.

Op dit ogenblik zullen alleen passieve FTP verbindingen functioneren. Om actieve verbindingen mogelijk te maken, moet de "ftp-data connection" die de FTP server initieert, binnen gelaten worden op de firewall. Jammer genoeg kan de poort waarop deze verbinding binnenkomt, niet op voorhand gekend zijn, alleen het bereik waarin ze valt. Wat echter wel gekend is, is dat de verbinding zal geïnitieerd worden vanaf poort 20 (ftp-data poort) en dat ftp-proxy de verbinding zal aannemen (en vervolgens data naar de client omleiden). Aangezien ftp-proxy draait als de gebruiker proxy, kan het user sleutelwoord gebruikt worden in de filterregel.

pass in on $ext_if inet proto tcp from port 20 to ($ext_if) \
    user proxy flags S/SA keep state

Merk alstublieft op dat ftp-proxy(8) dient om FTP clients achter een PF filter te helpen; het wordt niet gebruikt om een FTP server achter een PF filter aan te pakken.

Een FTP Server die "zichzelf beschermt" met PF

In dit geval draait PF op de FTP server zelf, veeleer dan op een toegewijde firewall computer. Bij het bedienen van een passieve FTP verbinding zal FTP een willekeurig gekozen, hoge TCP poort gebruiken voor binnenkomende gegevens. Standaard gebruikt OpenBSD's aangeboren FTP server ftpd(8) het bereik 49152 tot 65535. Vanzelfsprekend moeten deze doorgelaten worden door de filterregels, samen met poort 21 (de FTP controlepoort):
pass in on $ext_if proto tcp from any to any port 21 keep state
pass in on $ext_if proto tcp from any to any port > 49151 \
   keep state

Merk op dat indien u dat wenst, u dat bereik van poorten aanzienlijk kan vernauwen. In het geval van het OpenBSD ftpd(8) programma, gebeurt dat met de sysctl(8) variabelen net.inet.ip.porthifirst en net.inet.ip.porthilast.

FTP Server Beschermd door een Externe PF Firewall die NAT draait

In dit geval moet de firewall verkeer omleiden naar de FTP server bovenop het niet blokkeren van de vereiste poorten. Om een concreet voorbeeld te geven, zullen we aannemen dat de FTP server in kwestie opnieuw de standaard OpenBSD ftpd(8) is, met gebruik van het standaard poortbereik.

Hier is een voorbeeld van een subset van regels die dit zouden verwezenlijken:

ftp_server = "10.0.3.21"

rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \
   port 21
rdr on $ext_if proto tcp from any to any port 49152:65535 -> \
   $ftp_server port 49152:65535

# in on $ext_if
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port 21 keep state
pass in quick on $ext_if proto tcp from any to $ftp_server \
   port > 49151 keep state

# out on $int_if
pass out quick on $int_if proto tcp from any to $ftp_server \
   port 21 keep state
pass out quick on $int_if proto tcp from any to $ftp_server \
   port > 49151 keep state

Meer Informatie over FTP

Meer informatie over het filteren van FTP en hoe FTP werkt in het algemeen, kan u terugvinden in dit artikel:

[Vorige: Prestatie] [Inhoud] [Volgende: Authpf: Gebruiker-Shell voor Authentiserende Gateways]


[terug] www@openbsd.org
$OpenBSD: ftp.html,v 1.5 2005/11/01 19:05:41 jufi Exp $