====== Derrière un routeur NAT ====== ===== Architecture du montage ===== Notre architecture devient un peu plus compliquée puisque : * le client FTP est derrière un routeur NAT ; * le serveur lui aussi se trouve derrière un routeur NAT. Ce qui nous donne :
{{ :205ftp:architecture.png?720 |Architecture NAT/NAT}} ===== Côté client ===== Sur la passerelle du client (GNU/Linux avec iptables), nous avons chargé les modules ''nf-conntrack-ftp'' et ''nf-nat-ftp'', nécessaires pour que le client puisse utiliser le mode actif. Notons que dans un cas de figure comme celui-ci, si nous comptons sur le suivi de connexion pour résoudre nos problèmes de connexions ''RELATED'', celui-ci sera mis en œuvre : * pour le mode passif côté serveur ; * pour le mode actif côté client. En nous souvenant de ce qui a déjà été vu à propos du suivi de connexion en FTPES, nous pouvons prévoir une impasse... ===== Côté serveur ===== Dans cette configuration, l'adresse IP(v4) du serveur sera une adresse privée. Or de l'extérieur, la seule adresse accessible sera l'IP publique attribuée par le fournisseur d'accès. La première idée qui vient à l'esprit est donc de rediriger en DNAT le port 21 du routeur sur l'adresse IP du serveur. iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 21 -j DNAT --to-destination 192.168.10.76 {{ :205ftp:dnat.png?450 |DNAT du port 21}} Pouvons-nous prévoir le comportement ? Une requête arrivant sur xxx.yyy.zzz.ttt port 21 va être redirigée sur notre serveur. Il répondra à la requête. Côté canal de contrôle, il ne devrait pas y avoir de problèmes. ===== Mode actif ===== Dans ce mode, où le client FTP devient serveur pour les DATA, le serveur ne devrait pas poser de problèmes, s'il reçoit l'adresse IP publique du routeur NAT du client. S'il y a un problème, il faudra donc chercher à le résoudre du côté du client, mais avec les modules de suivi de connexion du protocole FTP de ''Netfilter'', nous avons nos chances. ==== Essai en FTP ==== Si nous utilisons le mode actif, le client enverra son adresse et un port pour que ''pure-ftpd'' puisse ouvrir une connexion TCP et ça devrait fonctionner. Vérifions dans le compte-rendu de ''FileZilla'' :
Statut :	Connexion à 82.243.80.13:21...
...
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,204,129
Réponse :	200 PORT command successful
Commande :	MLSD
Réponse :	150 Connecting to port 52353
Réponse :	226-Options: -a -l 
Réponse :	226 7 matches total
Statut :	Succès de la lecture du contenu du dossier
Le client, en mode actif envoie **son adresse IP privée** et pourtant, tout fonctionne. Miracle ? Comment la passerelle côté serveur peut-elle interpréter une adresse IP privée qu'il ne sait pas router ? Sniffons sur la passerelle du serveur (''Tshark'', la version en ligne de commande de ''[[http://www.wireshark.org/|Wireshark]]'' est notre ami)...
...
     19 0.386311    82.229.41.132         82.243.80.13          FTP      Request: TYPE I
     20 0.386608    82.243.80.13          82.229.41.132         FTP      Response: 200 TYPE is now 8-bit binary
     21 0.435339    82.229.41.132         82.243.80.13          FTP      Request: PORT 82,229,41,132,143,22
     22 0.435765    82.243.80.13          82.229.41.132         FTP      Response: 200 PORT command successful
...
     25 0.522738    82.243.80.13          82.229.41.132         FTP      Response: 150 Connecting to port 36630
Ce que l'on voit passer ici n'est plus l'adresse IP privée du client, mais l'adresse publique de sa passerelle. Il est fort ce ''netfilter''... Il est fort, certes, mais i ne fait pas de miracles. Les modules ''nf-conntrack-ftp'' et surtout ''nf-nat-ftp'' dans le cas présent peuvent analyser et modifier le contenu des datagrammes FTP parce qu'ils ne sont pas chiffrés. ==== Essai en FTPES ==== Est-ce bien la peine ? ''Netfilter'' ne pourra pas faire son travail sur du FTP chiffré. Essayez si vous ne me croyez pas. Vous obtiendrez dans le ''FileZilla'' un message du type : Commande : PORT 192,168,0,16,186,176 Réponse : 500 I won't open a connection to 192.168.0.16 (only to 82.229.41.132) ''82.229.41.132'', c'est ici l'adresse publique du routeur du client. Même message que si les modules ''nf-conntrack-ftp'' et ''nf-nat-ftp'' n'étaient pas chargés sur le routeur NAT du client, soit dit en passant. Existe-t-il un contournement ? Rien de propre. Sauf si j'ai raté quelque chose, nous devrons nous passer du mode actif en FTPES dans cette topologie. ===== Le mode passif ===== Nous avons déjà vu ce qu'il se passe côté serveur. Sur le routeur NAT du serveur, il faudra donc aussi rediriger les ports que nous avons spécifié dans la configuration de ''pure-ftpd'' : iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 65525:65535 -j DNAT --to-destination 192.168.10.76 Cette solution sera acceptable dans la mesure où il n'y a qu'un seul serveur FTP derrière le NAT. ==== Essai en FTP ==== Ici, nous risquons de rencontrer un problème du fait que dans ce mode, le serveur va présenter son adresse IP qui est ici privée donc, non routée. ''FileZilla'' sait contourner cette erreur, mais nous allons lui dire de ne pas le faire : {{ :205ftp:filezilla-passif-2.png?720 |Filezilla passif sans intelligence}} Ce qui nous permettra de mettre en évidence cette erreur :
Commande :	PASV
Réponse :	227 Entering Passive Mode (192,168,10,76,255,251)
Statut :	Le serveur a envoyé une réponse passive avec une adresse non routable. Échec du mode passif.
Erreur :	Échec lors de la récupération du contenu du dossier
Comment corriger cette erreur ? Il y a deux façons de faire, dont une que nous avons déjà rencontrée côté client pour le mode actif : === Netfilter, au secours ! === En chargeant les modules ''nf-conntrack-ftp'' et ''nf-nat-ftp'', nous avons nos chances :
Commande :	PASV
Réponse :	227 Entering Passive Mode (82,243,80,13,255,245)
Commande :	MLSD
Réponse :	150 Accepted data connection
Réponse :	226-Options: -a -l 
Réponse :	226 6 matches total
Statut :	Succès de la lecture du contenu du dossier
Et ça fonctionne. Le ''conntrack'' corrige à la volée. C'est bien, surtout si le routeur NAT du serveur récupère une adresse IP publique qui change dans le temps, mais il est clair qu'en mode FTPES, ceci ne fonctionnera plus. === Dans pure-ftpd === Il est parfaitement possible de demander à ''pure-ftpd'' d'exposer l'adresse IP publique de sa passerelle, lorsqu'il travaille en mode passif. Cette solution ne sera acceptable que si cette passerelle dispose d'une adresse IP publique fixe, bien entendu. Nous modifions la ligne de commande comme suit (elle commence à devenir vraiment longue) dans ''/etc/inetd.conf'' : ftp stream tcp4 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535 -P 82.243.80.13 Cette opération va perturber le fonctionnement du suivi de connexions FTP de ''Netfilter'', aussi bien sur le serveur lui-même que sur son routeur NAT. Sur le routeur, ce n'est pas important puisque les ports réservés au mode passif sont déjà explicitement redirigés. Sur le serveur lui-même, en revanche nous avons actuellement :
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i eth1 -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 conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
Il nous faut maintenant ouvrir explicitement les ports 65525 à 65535 à cause du suivi de connexion rendu inopérant : iptables -A INPUT -i eth1 -p tcp --dport 65525:65535 -j ACCEPT Nous rechargeons la configuration de ''inetd'' et nous essayons :
Commande :	PASV
Réponse :	227 Entering Passive Mode (82,243,80,13,255,248)
Commande :	MLSD
Réponse :	150 Accepted data connection
Réponse :	226-Options: -a -l 
Réponse :	226 6 matches total
Statut :	Succès de la lecture du contenu du dossier
Tout va bien. ==== Essai en FTPES ==== Avec les modifications apportées aux règles ''iptables'' du côté du serveur, le suivi de connexion n'est plus nécessaire. Du côté du client, en mode passif, il n'y a pas besoin de suivi de connexion spécifique à FTP. Nous pouvons nous attendre à ce que tout fonctionne correctement :
Commande :	AUTH TLS
Réponse :	234 AUTH TLS OK.
...
Commande :	PASV
Réponse :	227 Entering Passive Mode (82,243,80,13,255,245)
Commande :	MLSD
Réponse :	150 Accepted data connection
Réponse :	226-Options: -a -l 
Réponse :	226 6 matches total
Statut :	Succès de la lecture du contenu du dossier
Pas de mauvaise surprise. ===== Bilan ===== Si nous donnons la priorité à l'usage du FTPES qui offre le chiffrement de la connexion, dans une telle topologie où le serveur comme les clients se trouvent derrière des routeurs NAT, la seule solution est de faire du FTP passif. Bien entendu, en IPv6 tout devient plus simple puisqu'il n'y a plus de NAT nulle part. Un jour peut-être ? En attendant résumons les configurations des divers protagonistes : ==== Serveur FTP ==== * Les lignes de commande dans ''inetd'' (IPv4 et IPv6) :ftp stream tcp4 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535 -P 82.243.80.13 ftp stream tcp6 nowait root /usr/sbin/pure-ftpd -j -lpuredb:/etc/pure-ftpd/pureftpd.pdb -E -T:30 -c3 -C2 -Y1 -p 65525:65535 * les règles Iptables : # iptables-save # Generated by iptables-save v1.4.8 on Sun Jan 29 11:46:57 2012 *nat :PREROUTING ACCEPT [1255:400710] :POSTROUTING ACCEPT [715:52251] :OUTPUT ACCEPT [715:52251] COMMIT # Completed on Sun Jan 29 11:46:57 2012 # Generated by iptables-save v1.4.8 on Sun Jan 29 11:46:57 2012 *filter :INPUT DROP [400:95800] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [884:74191] -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 conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i eth0 -p tcp -m tcp --dport 65525:65535 -j ACCEPT COMMIT Le suivi de connexion est resté en place pour permettre la connexion en mode FTP actif (sans chiffrement) ; * les modules chargés pour le suivi de connexion FTP :# lsmod | grep ftp nf_conntrack_ftp 5505 0 nf_conntrack 46311 6 iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state,xt_conntrack,nf_conntrack_ftp ==== Routeur NAT du FTP ==== * les règles Iptables relatives au fonctionnement du FTP : # iptables-save # Generated by iptables-save v1.4.8 on Sun Jan 29 11:56:26 2012 *nat :PREROUTING ACCEPT [3838277:231166320] :POSTROUTING ACCEPT [916200:55004844] :OUTPUT ACCEPT [47781:3326346] ... -A PREROUTING -i eth0 -p tcp -m tcp --dport 21 -j DNAT --to-destination 192.168.10.76 -A PREROUTING -i eth0 -p tcp -m tcp --dport 65525:65535 -j DNAT --to-destination 192.168.10.76 -A POSTROUTING -o eth0 -j MASQUERADE COMMIT ... * les modules de suivi de connexion ne sont pas nécessaires pour ce qui nous intéresse ici, compte tenu des règles Iptables mises en place. Il peut cependant être utile de les charger si par ailleurs des clients du même réseau souhaitent faire du FTP actif sur l'internet :# lsmod | grep ftp nf_nat_ftp 1999 0 nf_conntrack_ftp 5505 1 nf_nat_ftp nf_nat 13276 3 nf_nat_ftp,ipt_MASQUERADE,iptable_nat nf_conntrack 46327 7 nf_nat_ftp,nf_conntrack_ftp,ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state ==== Routeur NAT des clients ==== Il n'y a rien de spécial, à part optionnellement charger les modules de suivi de connexion ''nf-conntrack-ftp'' et ''nf-nat-ftp'' pour autoriser le FTP actif, aussi bien sur notre serveur que sur d'autres, situés quelque part sur l'internet. Nous supposons que par ailleurs, Iptables configure correctement la passerelle pour autoriser les connexions ''RELATED'' et ''ESTABLISHED'' venant de l'internet dans le routage NAT. ==== Rappel important ==== Souvenons-nous que les modules de suivi de connexion ''nf-conntrack-ftp'' et ''nf-nat-ftp'' sont dans l'incapacité totale de faire leur travail en présence d'un flux chiffré (FTPES). La conséquence principale est que même si le serveur FTP est installé directement sur une passerelle et peut donc être atteint sans DNAT, le client derrière un routeur NAT n'aura pas de possibilité d'y accéder en FTPES actif. ==== Une autre piste ==== Une solution intéressante, mais qui sort du cadre de cette étude sur FTP consiste à établir un tunnel chiffré, par exemple entre la passerelle du réseau contenant le serveur FTP et le poste du client : {{ :205ftp:solution-vpn.png?720 |Solution VPN}} Dans ce cas, le tunnel étant lui-même chiffré, rien n'interdirait d'abandonner FTPES au profit de FTP, ce qui simplifierait le problème. Dans une telle topologie, le client pourrait même à travers son tunnel accéder à tous les nœuds de son réseau privé. Une solution comme ''openvpn'' supporte très bien de passer un routeur NAT, encore faudra-t-il que les pare-feux laissent passer le tunnel. Mais tout ceci est une [[280vpn:start|autre histoire ]].