FTP et Netfilter

Mettons en place un pare-feu sur l'hôte du serveur FTP. Ce n'est pas une nécessité absolue si un autre pare-feu se trouve en amont, mais ce sera l'occasion de mieux comprendre le suivi de connexion en FTP et de comprendre aussi pourquoi ce suivi ne peut être réalisé si les transferts sont chiffrés (FTPES).

SSH sinon rien

Au départ, sur l'hôte du serveur (une seule interface eth0), nous posons ceci :

# iptables-save
# Generated by iptables-save v1.4.8 on Mon Jan 23 11:26:11 2012
*filter
:INPUT DROP [1:76]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:76]
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
COMMIT

Par défaut, rien ne peut entrer par aucune interface. Il est quand même judicieux de laisser passer SSH (port 22) et de laisser tout entrer sur lo (du moins pour ce qui nous intéresse ici).

FTP et son suivi de connexion

Dans de telles conditions, FTP ne peut bien entendu pas fonctionner. Nous allons ajouter ces deux règles :

iptables -A INPUT -p tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

ceci afin de laisser entrer les connexions des clients FTP sur le port 21

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

ceci afin d'avoir des chances de laisser passer les connexions DATA relatives aux commandes FTP lancées par le client. Mais le suivi de connexions sur FTP est, nous l'avons vu, assez particulier pour nécessiter le chargement d'un module spécialisé :

modprobe nf-conntrack-ftp

Autrefois, ce module s'appelait ip-conntrack-ftp. Ce nom est aujourd'hui (30/01/2012) devenu un alias et donc toujours utilisable, mais autant adopter l'appellation actuelle.

Il n'y a pas ici de NAT puisque nous sommes toujours dans le cas de deux réseaux locaux routés entre eux. Au final, nous avons :

# iptables-save
# Generated by iptables-save v1.4.8 on Mon Jan 23 11:42:34 2012
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:76]
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
COMMIT

Et, en ce qui concerne les modules de suivi :

# lsmod | grep conntrack
nf_conntrack_ipv4       9833  2 
nf_defrag_ipv4          1139  1 nf_conntrack_ipv4
xt_conntrack            2407  1 
x_tables               12845  4 xt_state,xt_tcpudp,xt_conntrack,ip_tables
nf_conntrack_ftp        5505  0 
nf_conntrack           46311  4 nf_conntrack_ipv4,xt_state,xt_conntrack,nf_conntrack_ftp

Essais FTP

Essayons maintenant une connexion FTP active :

Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 11:48. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	USER test
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	SYST
Réponse :	215 UNIX Type: L8
Commande :	FEAT
Réponse :	211-Extensions supported:
Réponse :	 EPRT
Réponse :	 IDLE
Réponse :	 MDTM
Réponse :	 SIZE
Réponse :	 REST STREAM
Réponse :	 MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :	 MLSD
Réponse :	 AUTH TLS
Réponse :	 PBSZ
Réponse :	 PROT
Réponse :	 UTF8
Réponse :	 TVFS
Réponse :	 ESTA
Réponse :	 PASV
Réponse :	 EPSV
Réponse :	 SPSV
Réponse :	 ESTP
Réponse :	211 End.
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PORT 192,168,0,16,171,235
Réponse :	200 PORT command successful
Commande :	MLSD
Réponse :	150 Connecting to port 44011
Réponse :	226-Options: -a -l 
Réponse :	226 8 matches total
Statut :	Succès de la lecture du contenu du dossier
Ça marche. Essayons maintenant en mode passif :
Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 11:51. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	USER test
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Statut :	Succès de la lecture du contenu du dossier
Ça fonctionne aussi. Pas vraiment étonnant, le conntrack de Netfilter fait son travail, grâce à la ligne :

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Essais FTPES

Essayons en FTPES mode actif :

Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 11:58. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	AUTH TLS
Réponse :	234 AUTH TLS OK.
Statut :	Initialisation TLS...
Statut :	Vérification du certificat...
Commande :	USER test
Statut :	Connexion TLS/SSL établie.
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	SYST
Réponse :	215 UNIX Type: L8
Commande :	FEAT
Réponse :	211-Extensions supported:
Réponse :	 EPRT
Réponse :	 IDLE
Réponse :	 MDTM
Réponse :	 SIZE
Réponse :	 REST STREAM
Réponse :	 MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :	 MLSD
Réponse :	 AUTH TLS
Réponse :	 PBSZ
Réponse :	 PROT
Réponse :	 UTF8
Réponse :	 TVFS
Réponse :	 ESTA
Réponse :	 PASV
Réponse :	 EPSV
Réponse :	 SPSV
Réponse :	 ESTP
Réponse :	211 End.
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Commande :	PBSZ 0
Réponse :	200 PBSZ=0
Commande :	PROT P
Réponse :	200 Data protection level set to "private"
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PORT 192,168,0,16,136,97
Réponse :	200 PORT command successful
Commande :	MLSD
Réponse :	150 Connecting to port 34913
Réponse :	226-Options: -a -l 
Réponse :	226 7 matches total
Statut :	Succès de la lecture du contenu du dossier
Pas de soucis. Mais en mode passif :
Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 12:00. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	AUTH TLS
Réponse :	234 AUTH TLS OK.
Statut :	Initialisation TLS...
Statut :	Vérification du certificat...
Commande :	USER test
Statut :	Connexion TLS/SSL établie.
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	SYST
Réponse :	215 UNIX Type: L8
Commande :	FEAT
Réponse :	211-Extensions supported:
Réponse :	 EPRT
Réponse :	 IDLE
Réponse :	 MDTM
Réponse :	 SIZE
Réponse :	 REST STREAM
Réponse :	 MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :	 MLSD
Réponse :	 AUTH TLS
Réponse :	 PBSZ
Réponse :	 PROT
Réponse :	 UTF8
Réponse :	 TVFS
Réponse :	 ESTA
Réponse :	 PASV
Réponse :	 EPSV
Réponse :	 SPSV
Réponse :	 ESTP
Réponse :	211 End.
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Commande :	PBSZ 0
Réponse :	200 PBSZ=0
Commande :	PROT P
Réponse :	200 Data protection level set to "private"
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PASV
Réponse :	227 Entering Passive Mode (192,168,10,76,252,141)
Commande :	MLSD
Erreur :	Délai d'attente expiré
Erreur :	Échec lors de la récupération du contenu du dossier
Ici, ça coince au moment d'utiliser un canal de DATA. Conntrack n'a pas pu voir passer les informations relatives au port passif et n'a pas pu gérer le RELATED à cause du chiffrement.

A ma connaissance il n'y a pas de solution du côté de Netfilter. Il existe cependant une solution de contournement que nous allons voir maintenant.

FTPES en mode passif

Si l'on souhaite que le serveur fonctionne en FTPES passif, il faut abandonner le suivi de connexion, indiquer au serveur une plage de ports à ouvrir en mode passif et de laisser entrer les paquets NEW par ces ports. Ceci ne présente pas un très gros danger dans la mesure où :

  • nous n'aurons pas beaucoup de connexions DATA simultanées, il n'est donc pas nécessaire d'ouvrir une grande plage ;
  • ces ports seront normalement fermés en dehors d'une connexion DATA qui en utiliserait.

Spécifier les ports

Nous avons une configuration -c3 -C2 ce qui laisse entendre deux connexions DATA par client, avec deux clients simultanés. Nous ne devrions pas avoir besoin de plus de 4 ports, nous allons en prévoir 10 avec le paramètre -p 65525:65535 qui indique assez clairement que le serveur choisira un port disponible sur la plage [65525,65535], ce qui nous donne une ligne de commande :

pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535

Ouvrir les ports concernés

Il faut le dire à Netfilter :

iptables -A INPUT -p tcp --dport 65525:65535 -m state --state NEW,ESTABLISHED -j ACCEPT

Vérification

Connexion en FTPES mode passif :

Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 15:13. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	USER test
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PASV
Réponse :	227 Entering Passive Mode (192,168,10,76,102,168)
Commande :	MLSD
Réponse :	150 Accepted data connection
Réponse :	226-Options: -a -l 
Réponse :	226 7 matches total
Statut :	Succès de la lecture du contenu du dossier
Statut :	Déconnecté du serveur
Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 15:22. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	AUTH TLS
Réponse :	234 AUTH TLS OK.
Statut :	Initialisation TLS...
Statut :	Vérification du certificat...
Commande :	USER test
Statut :	Connexion TLS/SSL établie.
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	SYST
Réponse :	215 UNIX Type: L8
Commande :	FEAT
Réponse :	211-Extensions supported:
Réponse :	 EPRT
Réponse :	 IDLE
Réponse :	 MDTM
Réponse :	 SIZE
Réponse :	 REST STREAM
Réponse :	 MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;
Réponse :	 MLSD
Réponse :	 AUTH TLS
Réponse :	 PBSZ
Réponse :	 PROT
Réponse :	 UTF8
Réponse :	 TVFS
Réponse :	 ESTA
Réponse :	 PASV
Réponse :	 EPSV
Réponse :	 SPSV
Réponse :	 ESTP
Réponse :	211 End.
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Commande :	PBSZ 0
Réponse :	200 PBSZ=0
Commande :	PROT P
Réponse :	200 Data protection level set to "private"
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PASV
Réponse :	227 Entering Passive Mode (192,168,10,76,196,229)
Commande :	MLSD
Erreur :	Délai d'attente expiré
Erreur :	Échec lors de la récupération du contenu du dossier
Statut :	Connexion à 192.168.10.76:21...
Statut :	Connexion établie, attente du message d'accueil...
Réponse :	220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Réponse :	220-You are user number 1 of 3 allowed.
Réponse :	220-Local time is now 15:54. Server port: 21.
Réponse :	220-This is a private system - No anonymous login
Réponse :	220-IPv6 connections are also welcome on this server.
Réponse :	220 You will be disconnected after 15 minutes of inactivity.
Commande :	AUTH TLS
Réponse :	234 AUTH TLS OK.
Statut :	Initialisation TLS...
Statut :	Vérification du certificat...
Commande :	USER test
Statut :	Connexion TLS/SSL établie.
Réponse :	331 User test OK. Password required
Commande :	PASS ********
Réponse :	230-Your bandwidth usage is restricted
Réponse :	230-User test has group access to:  ftpgroup  
Réponse :	230 OK. Current directory is /
Commande :	OPTS UTF8 ON
Réponse :	200 OK, UTF-8 enabled
Commande :	PBSZ 0
Réponse :	200 PBSZ=0
Commande :	PROT P
Réponse :	200 Data protection level set to "private"
Statut :	Connecté
Statut :	Récupération du contenu du dossier...
Commande :	PWD
Réponse :	257 "/" is your current location
Commande :	TYPE I
Réponse :	200 TYPE is now 8-bit binary
Commande :	PASV
Réponse :	227 Entering Passive Mode (192,168,10,76,255,248) Donc le port 65528
Commande :	MLSD
Réponse :	150 Accepted data connection
Réponse :	226-Options: -a -l 
Réponse :	226 7 matches total
Statut :	Succès de la lecture du contenu du dossier
Ça fonctionne sans surprise, mais sans le conntrack.