Avanti Indietro Indice

23. FTP

23.1 Descrizione

Il protocollo FTP (File Trasfert Protocol) è un protocollo molto noto e utilizzato che consente di trasferire file da una macchina ad un'altra.

Per effettuare operazioni FTP sono disponibili due modalità: attiva e passiva.

La modalità attiva in particolare è nota per i problemi che crea a chi deve impostare un firewall a protezione ad esempio di una rete locale.

Il protocollo FTP richiede che inizialmente sia comunque stabilita una connessione FTP, indipendentemente dal tipo (passiva o attiva), tra il client e il server. Questo avviene attraverso una richiesta inviata dal client alla porta 21 (FTP) del server, il quale se disponibile accetterà la connessione. Quindi nel nostro caso il firewall dovrà accettare le richieste inviate da un computer della rete locale (client) ad un server presente nella rete esterna.

          +---+ ......
          |PC1|----+ .                   
          +---+    | .                   
                   | .                          
          +---+    | ....> +---+ .......................> +---+        
          |MAC|----+-------|PC0|---------- INTERNET ----- |   |
          +---+    |       +---+                          +---+ 
                   .
             LAN         Linux Box       Internet      Server FTP
        [rete locale]  

In questo caso non ci sono grossi problemi, se usiamo iptables possiamo utilizzare:


# --------------------------------------------------------------------------------
# Appendiamo una regola che accetti tutti i pacchetti provenienti dalla rete locale 
# (LAN) e destinati alla porta ftp
# --------------------------------------------------------------------------------
iptables -A FORWARD -s $LAN -p tcp --dport ftp -j ACCEPT

# Appendiamo una regola che accetti tutti i pacchetti provenienti da un computer presente nella rete internet
# con porta sorgente ftp e che non siano di richiesta connessione
iptables -A FORWARD -s $INTERNET -p tcp  ! --syn --sport ftp -j ACCEPT

NOTA: è importante impedire che dall'esterno qualcuno cerchi di effettuare connessioni con le macchine della LAN. In genere le macchine della rete locale non dovrebbero offrire alcun servizio (FTP, telnet, mail, ...) all'esterno. Ciò si può realizzare utilizzando l'opzione ! --syn, ossia non accettando pacchetti con il flag SYN (richiesta connessione) impostato.

A questo punto è necessario stabilire una seconda connessione, quella che si occuperà dello scambio dei dati. E' possibile utilizzare sia una connessione attiva sia passiva come detto.

La modalità attiva crea grossi problemi in quanto è il client a stabilire indirizzo e porta su cui deve avvenire la trasmissione dei dati e ad inviare un pacchetto con queste informazioni e il comando PORT al server.

Questa situazione richiede che il server accetti e stabilisca una connessione con il client, solo che se il client è protetto da un firewall, quest'ultimo in genere rifiuta (e deve rifiutare!) questo tipo di connessioni dall'esterno verso l'interno, oltretutto effettuate su una porta qualsiasi. Ciò richiederebbe al firewall di aprire una grossa falla, ossia praticamente accettare tutte le richieste connessioni provenienti dall'esterno.

          +---+ 
          |PC1|----+            +---------- il pacchetto viene scartato (DROP)
          +---+    |            |                              
                   |            V                        
          +---+    |       +---+X<......................  +---+        
          |MAC|----+-------|PC0|---------- INTERNET ----- |   |
          +---+    |       +---+                          +---+ 
                   .
             LAN         Linux Box       Internet      Server FTP
        [rete locale]                             

Nel caso della modalità passiva la situazione è esattamente il contrario, il client invia un pacchetto contenente il comando PASV, e poi è il server a inviare al client indirizzo IP e porta per la connessione. Questa situazione è quindi molto simile alla connessione ftp vista all'inizio. Il client si può così connettere.

 
          +---+ ......
          |PC1|----+ .                   
          +---+    | .                   
                   | .                          
          +---+    | ....> +---+ .......................> +---+        
          |MAC|----+-------|PC0|---------- INTERNET ----- |   |
          +---+    |       +---+                          +---+ 
                   .
             LAN         Linux Box       Internet      Server FTP
        [rete locale]  

Il firewall non crea problemi, la connessione viene stabilita e i dati sono scambiati.

In alcuni casi si noterà che la modalità attiva utilizza esclusivamente la porta 20 (ftp-data), questa modifica è stata introdotta da non molto tempo, quindi alcuni server potrebbero non accettarla.

In questo caso il meccanismo è lo stesso del caso descritto prima solo che la porta sorgente utilizzata è la porta 20, ciò permette di identificare i pacchetti ftp-data e di ridurre i rischi.

# --------------------------------------------------------------------------------
# In questo caso i pacchetti provenienti dall'esterno hanno la porta sorgente 
# impostata a 20 (ftp-data) ciò permette di facilitare al firewall il riconoscimento.
# 1024: indica una porta alta (compresa tra 1024 e 65535). 
# --------------------------------------------------------------------------------
iptables -A FORWARD -s $INTERNET -p tcp         --sport ftp-data -d $LAN      --dport 1024:    -j ACCEPT

iptables -A FORWARD -s $LAN      -p tcp ! --syn --sport 1024:    -d $INTERNET --dport ftp-data -j ACCEPT

NOTA: in questo caso non è possibile utilizzare nella seconda linea l'opzione '--syn', in quanto la connessione è stabilita dal server.

Se possibile comunque è meglio utilizzare la modalità passiva, altrimenti è necessario caricare il modulo 'ip_conntrack_ftp.o' (usa insmod ip_conntrack_ftp) il quale si occuperà di cercare nel pacchetto eventuali comandi PORT e quindi ad aggiungere e riscrivere le informazioni in modo che tutto funzioni nel modo corretto. Se si utilizza inoltre il masquerading è necessario caricare anche il modulo 'ip_nat_ftp.o'.

Ecco un esempio di come impostare una connessione ftp data passiva:

# --------------------------------------------------------------------------------
# La connessione è stabilita da una macchina della rete locale. 
# Le porte scelte sono due porte alte.
# --------------------------------------------------------------------------------
iptables -A FORWARD -s $LAN      -p tcp         --sport 1024: -d $INTERNET --dport 1024: -j ACCEPT
iptables -A FORWARD -s $INTERNET -p tcp ! --syn --sport 1024: -d $LAN      --dport 1024: -j ACCEPT

NOTA: i browser MSIE, Netscape, Mozilla utilizzano la modalità passiva, quindi non dovrebbero esserci problemi. Altri programmi come quelli a riga di comando (es. ftp) e win utilizzano spesso la modalità attiva per default ma supportano anche la modalità passiva. Il programma ftp di Linux ad esempio usa la modalità attiva, per passare a quella passiva utilizzare:

# ftp 
ftp> passive
Passive mode on.
ftp> o
(o) ...

E' necessario segnalare inoltre che alcuni server, in genere pochi e molto vecchi, non supportano la modalità passiva.

23.2 Esempi

Esempio 1

Supponiamo che la nostra macchina appartenga ad una LAN e che la vogliamo più sicura, inoltre utilizziamo per comodità il connection tracking.


modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

iptables -A FORWARD -j REJECT

# --------------------------------------------------------------------------------
# prima di tutto dobbiamo accettare e far passare i pacchetti destinati alla porta ftp (indispensabile)
# --------------------------------------------------------------------------------
iptables -A OUTPUT -p tcp --sport 1024: --dport ftp      -j ACCEPT

# --------------------------------------------------------------------------------
# modalità attiva utilizzando ftp-data
# --------------------------------------------------------------------------------
iptables -A OUTPUT -p tcp --sport 1024: --dport ftp-data -j ACCEPT

# --------------------------------------------------------------------------------
# modalità passiva 
# --------------------------------------------------------------------------------
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024:    -j ACCEPT

# --------------------------------------------------------------------------------
# altro (es. www, telnet ...)
# --------------------------------------------------------------------------------
# ...

# --------------------------------------------------------------------------------
# Il resto invece sarà scartato
# --------------------------------------------------------------------------------
iptables -A OUTPUT -j REJECT

# --------------------------------------------------------------------------------
# se il pacchetto appartiene ad una connessione stabilita (ESTABLISHED) o comunque relativa (RELATED)
# allora pacchetto accettato.  
# --------------------------------------------------------------------------------
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# --------------------------------------------------------------------------------
# altrimenti registriamo i dati di questo pacchetto nel file di log e ...
# --------------------------------------------------------------------------------
iptables -A INPUT -j LOG --log-level info --log-prefix "FIREWALL (INPUT): "

# --------------------------------------------------------------------------------
# ... rifiutiamolo
# --------------------------------------------------------------------------------
iptables -A INPUT -j REJECT

Avanti Indietro Indice