FTP: Passive Mode e restrizioni di Firewall

ATTENZIONE: Questo post e' stato scritto piu' di 3 mesi fa. Potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a scrivere un commento per chiedere delucidazioni! :)

Problematica apparentemente stupida capitata giusto stamane. Sulla stessa macchina sarà necessario attivare un doppio server FTP di cui solo uno esposto all’esterno con IP pubblico raggiungibile dalla rete. Il secondo server dovrà essere “riservato ad alcune reti LAN” e in ascolto su una porta differente da quella standard.

Riepilogo estremamente semplice: il primo sfrutterà la classica porta 21, il secondo la 2121 e sarà bloccato tramite regole di firewall, rendendolo disponibile -come richiesto- solo ad alcune sottoreti. Per gli addetti il funzionamento di modalità attiva e passiva è cosa banale, un po’ meno per chi non è abituato a mangiare di questo quotidianamente:

FTP, a differenza di altri protocolli come ad esempio HTTP, utilizza due connessioni separate per gestire comandi e dati. Un server FTP rimane tipicamente in ascolto sulla porta 21 TCP a cui si connette il client. La connessione da parte del client determinerà l’inizializzazione del canale comandi attraverso il quale client e server si scambieranno comandi e risposte. Lo scambio effettivo di dati (come ad esempio file) richiederà l’apertura del canale dati il quale può essere di due tipi.

In un canale dati di tipo attivo il client apre una porta tipicamente random, tramite il canale comandi rende noto il numero di tale porta al server e attende che esso si connetta. Una volta che il server ha attivato la connessione dati al client FTP, quest’ultimo effettua il binding della porta sorgente alla porta 20 del server FTP. A tale scopo possono venire impiegati i comandi PORT o EPRT, a seconda del protocollo di rete utilizzato (tipicamente IPv4 o IPv6).

In un canale dati di tipo passivo il server apre una porta tipicamente random (> 1023), tramite il canale comandi rende noto il numero di tale porta al client e attende che esso si connetta. A tale scopo possono venire impiegati i comandi PASV o EPSV, a seconda del protocollo di rete utilizzato (tipicamente IPv4 o IPv6).

Ergo: contrariamente al servizio FTP esposto in modalità attiva (per richiesta), quello interno configurato in modalità passiva avrebbe potuto utilizzare una qualsiasi porta casuale (oltre la 2121 stabilita in IIS) in un range che va dalla 1025 alla 5000, come dichiarato nel documento Microsoft pubblicato in Technet:

technet.microsoft.com/en-us/library/cc734964%28WS.10%29.aspx

A questo punto è stato necessario fare in modo che il range diminuisse notevolmente per poter aprire meno porte possibili e concedere lo stretto indispensabile ai PC che potranno far accesso alla 2121 in Passive Mode per scambiare dati via FTP. Lo stesso documento propone l’utilizzo di uno script già presente in una qualsiasi installazione di Microsoft IIS:

Configure PassivePortRange by using an ADSUTIL script

To configure PassivePortRange by using an ADSUTIL script:

  1. Open an elevated Command Prompt window. Click Start, point to All Programs, click Accessories, right-click Command Prompt, and then click Run as administrator.
  2. Type cd %SystemDrive%\Inetpub\AdminScripts and press ENTER.
  3. Type the following from the command prompt (this example uses a port range of 6000-7000):adsutil.vbs set /MSFTPSVC/PassivePortRange “6000-7000″

Restart the FTP Service

To restart the FTP Service:

  1. Open an elevated Command Prompt window. Click Start, point to All Programs, click Accessories, right-click Command Prompt, and then click Run as administrator.
  2. Type net stop msftpsvc.
  3. Type net start msftpsvc.

Si ottiene quindi questo risultato:

IIS: restringere il range di porte per il Passive Mode

L’ultima modifica riguarderà il firewall e si potrà ora facilmente controllare avendo limitato il range di porte a 20 comprese tra la 6000 e la 6020 (oltre la 2121 precedentemente stabilita e inserita nella configurazione di IIS). Tradotto in iptables (ho offuscato lo stretto necessario):


iptables -t filter -A FORWARD -s 192.168.1.0/24 -d IPSERVERFTP -p tcp --dport 2121 -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.2.0/24 -d IPSERVERFTP -p tcp --dport 2121 -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.3.0/24 -d IPSERVERFTP -p tcp --dport 2121 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.1.0/24 -p tcp --sport 2121 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.2.0/24 -p tcp --sport 2121 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.3.0/24 -p tcp --sport 2121 -j ACCEPT

iptables -t filter -A FORWARD -s 192.168.1.0/24 -d IPSERVERFTP -p tcp --dport 6000:6020 -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.2.0/24 -d IPSERVERFTP -p tcp --dport 6000:6020 -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.3.0/24 -d IPSERVERFTP -p tcp --dport 6000:6020 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.1.0/24 -p tcp --sport 6000:6020 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.2.0/24 -p tcp --sport 6000:6020 -j ACCEPT
iptables -t filter -A FORWARD -s IPSERVERFTP -d 192.168.3.0/24 -p tcp --sport 6000:6020 -j ACCEPT

Dato che per chi lavora costantemente su ambiente Microsoft ricordare la sintassi di iptables potrebbe essere un problema, ho fatto spudorato uso di questo post: cyberciti.biz/tips/linux-iptables-how-to-specify-a-range-of-ip-addresses-or-ports.html, il classico “articolo al posto giusto nel momento giusto” :-)

Fatto ciò basterà riapplicare le regole per poter poi effettuare un test sul primo client che vi capita a tiro, tutto dovrebbe andare liscio come l’olio.

Buon lavoro.

  • http://gionn.net/ gionn

    Così a occhio mi paion superflui la seconda parte di ogni blocco di regole, basta che metti prima un ACCEPT globale sui pacchetti con flag di stato ESTABLISHED,RELATED.
    Se invece ho interpretato male, lascia perde, sono comunque le 19.35 :D

  • http://gioxx.org gioxx

    @ gionn:
    l’osservazione in realtà è ottima, è giusto un modo (evidentemente ripetitivo ma tant’è) di inserire regole in un file già creato e messo in piedi da $altruipersona dove io ho non ho fatto altro che rispettare “i canoni trovati” :mrgreen: (altrimenti sarebbe stato sensatissimo il tuo suggerimento)

  • Timothy Redaelli

    Ciao,
    perché non usi ip_conntrack_ftp?

  • http://gioxx.org Gioxx

    @ Timothy Redaelli:
    me l’ha suggerito anche un altro mio conoscente via Facebook, non conoscevo il modulo! (tornerà sicuramente utile)

    Per la casistica analizzata e “messa a posto” va comunque bene quanto fatto sopra dato che il server FTP interno sarà utilizzato da un solo utente, limitargli il range di porte (anche se utilizzerà più connessioni simultanee) non dovrebbe creare un problema ;)