Cet article traite de la sécurisation des transferts FTP au moyen de SSL (FTPS), et des conséquences sur la traversée des firewalls. 1. Rappels sur FTP FTP est un des protocoles encore les plus utilisés sur Internet, et c'est aussi celui qui depuis le début pose le plus de problèmes de sécurité. Ces problèmes sont multiples et bien connus: . passage en clair (la plupart du temps) des authentifications (les contournements tels que OPIE ou les mots de passe dépendants du temps sont soit très lourds soit très chers). . absence de contrôle de l'intégrité des données transmises (pas de somme de contrôle en plus des checksums TCP). . protocole « compliqué » mettant en jeu deux connexions: - contrôle sur le port 21 - en mode actif, connexion de données dans le sens serveur -> client, le client fixant le port et le serveur s'y connectant depuis le port source 20. - en mode passif, connexion de données vers un port haut choisi par le serveur. 1.1. Mode actif Le dialogue entre un client et un serveur en mode "actif" est le suivant: Client Serveur 192.168.230.1 192.168.230.2 -----------> Ouverture de la connexion sur le port TCP 21 <----------- 220 ProFTPD 1.2.9 Server (synda.rominet.net) -----------> USER foo <----------- 331 Password required for foo. -----------> PASS bar <----------- 230 User foo logged in. -----------> PORT 192,168,230,1,7,12 <----------- 200 PORT command successful RETR toto -----------> TCP:1804 <=========== TCP:20 Ouverture de la connexion de données (1804 = 7*256 + 12) <----------- 150 Opening ASCII mode data connection for toto <=========== <=========== Envoi des données <=========== <=========== FIN,ACK <----------- 226 Transfer complete. Le fonctionnement en envoi de fichiers est le même : la connexion de données est toujours ouverte dans le même sens mais le client envoie les données. Dans ce mode, en supposant que le client soit derrière un firewall effectuant également de la traduction d'adresses, celui-ci a alors plusieurs rôles: . changer l'adresse IP et le port dans la commande PORT afin d'y mettre l'adresse translatée et un port libre, pour que le serveur se connecte à la bonne machine et non pas à l'adresse privée. . ouvrir un "trou" dynamique dans ses règles de filtrage afin de permettre la connexion de données. Cette règle dynamique doit être la plus étroite possible, et vérifier en particulier que la connexion vient bien du serveur accédé, et uniquement du port 20. Beaucoup de firewalls hélas ne vérifient pas toutes ces conditions. . effectuer une traduction dynamique de port vers la machine privée quand il reçoit une connexion sur le port choisi initialement. 1.2. Mode passif Le fonctionnement en mode passif est le même au démarrage de la session, mais l'ouverture de la connexion de données est différente: PASV -----------> <----------- 227 Entering Passive Mode (192,168,230,2,81,181). RETR toto -----------> ===========> TCP:20917 Ouverture de la connexion de données (20917 = 81*256 + 181) <----------- 150 Opening ASCII mode data connection for toto <=========== <=========== Envoi des données <=========== <=========== FIN,ACK <----------- 226 Transfer complete. Dans ce cas la, le firewall coté client doit laisser passer une connexion sortante sur un port dynamique pris dans la réponse 227 du serveur, vérifier qu'il traduit la connexion de données avec la même adresse que la connexion de contrôle, mais ne touche pas le contenu des paquets échangés. En revanche coté serveur, si un firewall et/ou une traduction d'adresse est présent, il doit: . analyser la réponse à la commande PASV afin de détecter le port choisi par le serveur . modifier la réponse à la commande PASV si l'adresse IP du serveur est traduite. . ouvrir un "trou" dynamique dans ses règles de filtrage afin de laisser la connexion de données venant du client s'établir. La aussi, selon la classe du firewall, un nombre différent de contrôles sera effectué. 1.3. Autres fonctions du firewall Plus généralement, les firewalls modernes doivent évidemment s'assurer que le port 21 n'est pas utilisé afin de tunneliser un autre protocole, et vérifier que les commandes envoyées sont bien en séquence (par exemple un client ne doit pas envoyer de commande PASV ou PORT avant d'être identifié ...). Certains firewalls permettent également d'interdire le transfert de fichiers dans un sens donné (par exemple l'envoi de fichiers en dehors du réseau contrôlé). De plus en plus de passerelles peuvent également effectuer un contrôle de contenu (anti-virus, vérification des types de fichiers pour éviter le téléchargement de contenus illégaux) sur la connexion de données. 1.4. Failles Cette complexité du protocole a entrainé de nombreuses failles dans les serveurs FTP ou dans l'inspection du protocole par de nombreux firewalls, telles que par exemple: . FTP Bounce Attack http://www.cert.org/advisories/CA-1997-27.html . FireWall-1 stateful inspection vulnerability http://www.securiteam.com/exploits/5QP0C0A0KW.html . Multiple FTP Inspection Vulnerabilities http://www.kb.cert.org/vuls/id/328867 De nombreux débordements de buffers ont également été trouvés dans quasiment tous les serveurs FTP du marché, qu'ils soient libres ou commerciaux. 2. Présentation de STP/SSL 2.1. RFCs et Internet Drafts L'intégration de SSL dans FTP procède des mêmes objectifs que ceux couverts par HTTPS ou SMTP-TLS: . permettre la confidentialité des échanges, en protégeant l'authentification, les commandes, et éventuellement les données transmises. . effectuer une authentification mutuelle, en permettant au client de vérifier l'identité du serveur, et optionnellement, de permettre l'authentification par certificats X509. . assurer l'intégrité et la signature des données transmises. Deux méthodes ont été successivement énoncées pour remplir ces tâches: - la première consiste à encapsuler tout le protocole FTP dans un connexion SSL/TLS, comme le fait HTTPS. Un port (990/tcp) est officiellement réservé à cet effet. Le reste du protocole est inchangé (mais la connexion de données s'effectue depuis le port 989 au lieu du port 20). L'inconvénient de cette méthode est qu'il ne permet pas d'adapter les méthodes de chiffrement au type de données transmises (on peut imaginer que dans la même connexion, on transfère des données en clair et d'autres chiffrées). D'autre part elle va à l'encontre des principes récents de l'IETF qui demande que la sécurité des transmissions soit gérée par le protocole lui même. Cette méthode est officiellement considérée comme obsolète et ne doit plus être utilisée. - La seconde consiste à intégrer SSL dans les extensions FTP décrites dans les RFCs 2228 (FTP Security Extensions) et 2389 (Feature negotiation mechanism for FTP). Le RFC 2389 permet au serveur d'annoncer en réponse à la commande FEAT les mécanismes non standards qu'il supporte, le 2228 introduit en particulier les commandes AUTH (extensions de sécurité) et PROT (chiffrement de la connexion de données). Ces extensions permettent d'introduire SSL/TLS relativement facilement : SSL devient un mécanisme de sécurité dans FTP et géré directement par le serveur. Ces mécanismes permettent par exemple de changer le niveau de chiffrement de la connexion de contrôle, et de ne protéger que l'authentification. AUTH-TLS et AUTH-SSL sont décrits dans l'Internet Draft "Securing FTP with TLS" http://www.ietf.org/internet-drafts/draft-murray-auth-ftp-ssl-14.txt . Ce Draft en est à sa 14e version, la première version date de 1997 ! Depuis lors, il a donc profondément évolué, en se complexifiant et en étendant les fonctionnalités (par exemple l'authentification par certificat client). Même si FTP/SSL n'est pas encore au stade du RFC, un grand nombre de clients et de serveurs l'implémentent déjà, comme indiqué sur la page de l'auteur du draft: http://www.ford-hutchinson.com/~fh-1-pfh/ftps-ext.html#client . Il existe en particulier des clients et serveurs OpenSource sous Unix et Windows. 2.2. Fonctionnement des extensions L'établissement d'une session FTP/SSL utilisant AUTH TLS n'est pas très différente dans son initialisation d'une session FTP normale. Le client évolué doit interroger le serveur afin de lui demander la liste de ses extensions, avec la commande FEAT. La plupart des clients modernes effectuent déjà cette interrogation afin de connaître présence d'autres fonctionnalités comme SIZE ou REST. Le schéma de connexion devient donc: Client Serveur 192.168.230.1 192.168.230.2 -----------> Ouverture de la connexion sur le port TCP 21 <----------- 220 ProFTPD 1.2.9 Server (synda.rominet.net) -----------> FEAT <----------- 211-Features: MDTM REST STREAM SIZE AUTH TLS PBSZ PROT 211 End Le serveur renvoit dans une liste (le caractère « - » apres 211 indique comme pour SMTP que la réponse est multi-ligne) les fonctionnalités qu'ils supportent. Dans l'exemple ci-dessus les trois fonctions "AUTH TLS", "PBSZ" et "PROT" sont celles qui nous intéressent. Le client peut initier le mode SSL dès le début de la connexion, en envoyant la commande "AUTH TLS" : le serveur répond alors "234 Successful" et passe en mode TLS: le client doit alors commencer la négociation avec son "Client Hello" TLS: -----------> AUTH TLS <----------- 234 AUTH TLS successful Si l'on examine la suite avec Ethereal en lui indiquant que le port 21 doit être décodé comme du TLS, on s'aperçoit que le dialogue est bien une négociation TLS classique. Source Destination Protocol Info client serveur SSLv2 Client Hello client serveur TLS Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done client serveur TCP 34507 > ftp [ACK] Seq=2558039014 Ack=2558034501 Win=37215 Len=0 TSV=18527234 TSER=18527234 client serveur TLS Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message client serveur TLS Change Cipher Spec, Encrypted Handshake Message La suite du protocole ne peut évidemment pas être visualisée, mais il est possible de suivre le dialogue en regardant par exemple les traces du client (comme lftp http://ftp.yars.free.net/projects/lftp/ ): <--- 234 AUTH TLS successful ... Certificate depth: 0; subject: /C=FR/ST=Paris/L=Paris/O=Rominet Networks Inc./CN=synda.rominet.net/emailAddress=at@rominet.net; issuer: /C=FR/ST=Paris/L=Paris/O=Rominet Networks Inc./CN=Rominet Networks/emailAddress=root@rominet.net ---> USER foo <--- 331 Password required for at. ---> PASS XXXX <--- 230 User at logged in. ---> PWD <--- 257 "/home/foo" is current directory. ---> PBSZ 0 <--- 200 PBSZ 0 successful ---> PROT P <--- 200 Protection set to Private ---> PASV <--- 227 Entering Passive Mode (192,70,106,104,81,49). ---- Connecting data socket to (192.70.106.104) port 20785 ---> LIST /home/ftp <--- 150 Opening ASCII mode data connection for file list <--- 226 Transfer complete. Après la réception du certificat, l'authentification s'effectue ici de la même manière que sur une connexion ftp classique. On remarque l'usage de la commande PROT qui indique avec son argument P que la connexion de données doit également être chiffrée. La commande PBSZ indique la taille maximale du tampon de chiffrement, dans le cas de TLS qui peut chiffrer des blocs de taille arbitraire, elle est toujours nulle. L'écoute de la connexion de données montre aussi qu'elle est bien chiffrée. La connexion peut également s'effectuer en mode "actif": ---> USER foo <--- 331 Password required for at. ---> PASS XXXX <--- 230 User at logged in. ---> PWD <--- 257 "/home/foo" is current directory. ---> PBSZ 0 <--- 200 PBSZ 0 successful ---> PROT P <--- 200 Protection set to Private ---> PORT 192,70,106,104,135,66 <--- 200 PORT command successful ---> LIST /home/ftp <--- 150 Opening ASCII mode data connection for file list <--- 226 Transfer complete. Dans ce mode là, malgré l'ouverture de la connexion vers le client, le serveur est toujours « Serveur SSL » malgré le fait que la connexion soit dans un sens inhabituel. On peut également indiquer que la connexion de données n'est pas chiffrée (en passant les options de lftp ftp:ssl-protect-data et ftp:ssl-protect-list à no). lftp foo@192.70.106.104:~> set ftp:ssl-protect-list no lftp foo@192.70.106.104:~> ls /home/ftp ---> PROT C <--- 200 Protection set to Clear ---> PORT 192,70,106,104,135,73 <--- 200 PORT command successful ---> LIST /home/ftp <--- 150 Opening ASCII mode data connection for file list ---- Closing data socket <--- 226 Transfer complete. La commande PROT est alors utilisée avec le paramètre C (Clear). L'Internet Draft reconnait au serveur le droit de refuser le passage en clair des données. Dans le cadre client/serveur lftp/proftpd, cela ne fonctionne pas, puisque si l'on force la connexion TLS dans proftpd et que le client n'envoie pas de ClientHello dans la connexion DATA, le transfert reste bloqué: ---> USER foo <--- 331 Password required for at. ---> PASS XXXX <--- 230 User at logged in. ---> PWD <--- 257 "/home/foo" is current directory. ---> PBSZ 0 <--- 200 PBSZ 0 successful ---> PORT 192,70,106,104,135,99 <--- 200 PORT command successful ---> LIST /home/ftp <--- 150 Opening ASCII mode data connection for file list `ls /home/ftp' at 0 [Receiving data] Le serveur est en tort, puisqu'il est écrit dans le RFC que le mode de connexion est initialement "C", donc le serveur aurait du refuser la connexion sur le LIST puisque "PROT P" n'a pas été envoyé. Si un "PROT P" a été envoyé puis que le client essaye de repasser en mode clair, le fonctionnement est revanche bien celui attendu, le serveur renvoie une erreur 534, et le client s'adapte. ---> PROT C <--- 534 Unwilling to accept security parameters ---> TYPE I <--- 200 Type set to I ---> SIZE toto.txt <--- 213 6 ---> MDTM toto.txt <--- 213 20040730131651 ---> PORT 192,70,106,104,135,122 <--- 200 PORT command successful ---> RETR toto.txt <--- 150 Opening BINARY mode data connection for toto.txt (6 bytes) ---- Closing data socket L'écoute de la connexion de données a confirmé qu'elle était bien chiffrée. 3. Impact sur le fonctionnement des firewalls On a vu précédemment que le traitement correct du protocole FTP par les firewalls nécessitait une inspection profonde des échanges, et en particulier des commandes PASV et PORT. L'utilisation de TLS change évidemment complètement le travail, puisque apres la négociation TLS, le canal de contrôle sur le port 21 est chiffré : le firewall ne peut donc plus du tout inspecter le trafic. Plusieurs problèmes se posent alors: . Les données échangées sur le port TCP ne sont plus reconnaissables par le firewall. En particulier, il n'y a plus de lignes de longueur raisonnable ne contenant que de l'Ascii. Certains firewalls vont refuser le passage des données: c'est le cas de Firewall-1 par exemple dans sa configuration par défaut. Il est possible parfois de changer ce comportement, mais souvent en baissant le niveau de sécurité de toutes les connexions (http://www.phoneboy.com/bin/view.pl/FAQs/FTPOverSSL ). . Il n'est plus possible au firewall d'ouvrir dynamiquement les ports nécessaires : - en mode actif, il est donc nécessaire du coté client de revenir aux technologies de filtrage statiques, en laissant entrer vers tous les ports hauts les connexions venant de tous les serveurs potentiels depuis le port TCP/20. Cela a bien entendu des conséquences terribles sur la sécurité. Du coté serveur, il faut que les connexion sortantes vers n'importe quel port haut soient possibles. - en mode passif, il faut que le client puisse accéder aux ports hauts de tous les serveurs potentiels. Cela nécessite d'ouvrir des règles très larges du coté client et du coté serveur. Si des services non sécurisés sont présents sur les ports prévus pour le mode passif, alors ils sont en danger. . Il n'est plus possible d'effectuer la traduction d'adresse du client en mode actif : de ce fait en pratique, le mode actif devient inutilisable pour tous les usages de FTP dans lequel un client d'un réseau local se connecte à un serveur sur Internet. Si c'est le serveur qui a une traduction d'adresse, alors le mode passif n'est plus utilisable (puisque l'adresse est contenue dans le paquet envoyé en réponse à PASV), sauf si le serveur dispose d'une option permettant de "forger" une adresse IP. . Il n'est évidemment plus possible si les données sont chiffrées de les traiter par un contrôle de contenu (anti-virus). Même si elles restent en clair, le firewall n'a plus de moyen de connaître l'instant et le port de la connexion, et ne peut donc pas intercepter les données échangées pour les inspecter. Ce problème n'est pas différent des sessions HTTPS ou des mails chiffrés qui échappent également à l'inspection. . Il n'est plus possible de filtrer les commandes FTP, et donc il n'est plus possible de limiter par exemple les transferts dans un seul sens ou de filtrer les extensions. Les problèmes sont résumés dans le document suivant: http://www.ietf.org/internet-drafts/draft-fordh-ftp-ssl-firewall-04.txt 4. Exemple de configuration avec proftpd Le serveur FTP Proftpd (http://www.proftpd.org/) contient désormais en standard un module FTP/SSL, qui est compilé automatiquement si la librairie OpenSSL est trouvée par le script « configure ». La documentation du module mod_tls est disponible à l'URL http://www.castaglia.org/proftpd/modules/mod_tls.html , un HOWTO permettant de régler les problèmes les plus courants se trouve à http://www.castaglia.org/proftpd/doc/contrib/ProFTPD-mini-HOWTO-TLS.html . Il faut évidemment commencer par posséder une autorité de certification afin de créer un certificat pour le serveur. La configuration du module est ensuite très simple, on ajoute dans la section globale le bloc suivant: # Activation du mode TLS (reponse AUTH TLS à la commande FEAT) TLSEngine on # Journalisation des sessons TLS TLSLog /var/log/proftp/tls.log # Version du protocole utilise. On peut accepter SSLV3 en laissant # le défaut : SSLv23 TLSProtocol TLSv1 # TLS forcé, on peut le limiter à la connexion de contrôle avec # le mot clé "ctrl" TLSRequired on # Certificat du serveur TLSRSACertificateFile /etc/proftpd/synda.crt # Clé du serveur TLSRSACertificateKeyFile /etc/proftpd/synda.key # Certificat de l'Autorité de certification TLSCACertificateFile /etc/proftpd/ca-cert.pem # Authentification par TLS (Certificat client) TLSVerifyClient off Certaines de ces directives peuvent être placées uniquement par hôte virtuel, afin de paramétrer FTP/SSL pour chaque adresse IP de la machine. Il est possible d'effectuer une authentification par certificat client : le client donne son login, et proftpd vérifie si un certificat correspondant existe dans le fichier $HOME/.tlslogin de l'utilisateur. Cette option doit être spécifiée en ajoutant AllowDotLogin comme paramètre de la directive TLSOptions. Certaines restrictions peuvent être ajoutées aux certificats clients acceptés, par exemple qu'ils doivent contenir une adresse IP dans l'extension X509 subjectAltName, qui est alors vérifiée par rapport l'adresse IP du client. TLSOptions AllowDotLogin, iPAddressRequired Le debugging de mod_tls est rendu assez difficile par le fait que les commandes étendues (AUTH TLS, PROT, PBSZ) ne sont pas enregistrées dans le fichier journal, même avec la directive: ExtendedLog /var/log/proftp/proftpd.log ALL Le fichier /var/log/proftp/tls.log ne contient pas beaucoup d'information non plus sur les causes éventuelles d'erreur: Jul 30 15:18:44 mod_tls/2.0.6[17142]: TLS/TLS-C requested, starting TLS handshake Jul 30 15:18:44 mod_tls/2.0.6[17142]: TLSv1/SSLv3 connection accepted, using cipher DHE-RSA-AES256-SHA (256 bits) Jul 30 15:18:44 mod_tls/2.0.6[17142]: Protection set to Private Jul 30 15:18:44 mod_tls/2.0.6[17142]: starting TLS negotiation on data connection Jul 30 15:18:44 mod_tls/2.0.6[17142]: TLSv1/SSLv3 data connection accepted, using cipher DHE-RSA-AES256-SHA (256 bits) Jul 30 15:18:48 mod_tls/2.0.6[17142]: PROT: unwilling to accept security parameter (C), declining 5. Conclusions L'ajout des extensions SSL sur FTP permet de résoudre les problèmes de confidentialité et d'intégrité de FTP. Hélas, le chiffrement de la session de contrôle ne permet plus aux firewalls d'inspecter le protocole et de réagir dynamiquement en adaptant leurs tables d'états et leur traduction d'adresse. On revient donc quelques années en arrière, quand FTP était le protocole le plus difficile à faire passer de manière sécurisée dans les filtres statiques de l'époque. L'utilisation de FTP-SSL pour des échanges sur Internet est donc très difficile, et ne peut être envisagée que dans des cas précis, par exemple entre deux organisations prêtes à collaborer pour ouvrir les flux nécessaires dans leurs firewalls. Les échanges en mode batch dans un intranet peuvent également être sécurisés en utilisant FTP-SSL, en utilisant des certificats clients qui éviteront de stocker des secrets en clair sur le client. Pour les autres échanges, l'utilisation de SSH (avec sftp) ou HTTPS (avec par exemple des outils en ligne de commande et serveurs d'upload spécialisés) ont sans doute un meilleur avenir. par Alain Thivillon (29/07/2004)