La F.A.Q d'OpenBSD à ce sujet est très intéressante, mais il se pose un certain nombre de problèmes pas toujours faciles à regler. On va donc voir les cas suivants:
Ceci nous fournira une vue d'ensemble sur les points à connaitre pour gérer le FTP.
FTP est un protocole TCP permettant le transfert de fichiers entre deux hôtes d'un réseau. Il fonctionne en deux modes: passif et actif. En mode passif, le client initie la connection et demande au serveur de se mettre en écoute sur un port aléatoire qu'il (le serveur) aura choisi et qu'il indiquera au client. En mode actif, le client choisit lui-même le port, et en informe le serveur. Dans le premier cas, le firewall est problématique car il filtre le traffic entrant. Dans le second, le NAT peut poser problème.
Pour qu'un client FTP puisse passer “à travers” un firewall en NAT, il faut utiliser un daemon qui joue le rôle de mandataire entre le client et le serveur. Ce daemon est apellé proxy. OpenBSD fournit en standard un proxy pour le FTP: ftp-proxy(8). Dans la plupart des cas, il suffit de le lancer par inetd(8) (à moins d'avoir un nombre important de connections FTP par jour). Insérez la ligne suivante dans votre fichier /etc/inetd.conf:
127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy -m 49500 -M 50000
127.0.0.1:8021 indique qu'il faut créer un socket sur le port 8021 (port par défaut de ftp-proxy) sur l'interface loopback. -m 49500 définit le début de la plage de ports à utiliser et -M 50000 la fin. Vous pouvez choisit n'importe quelle plage de ports au delà des ports réservés, mais prenez soin de choisir une plage suffisament élevée pour ne pas interférer. Enregistrez les modifications, et rechargez inetd:
kill -HUP `cat /var/run/inetd.pid`
Ensuite, dans /etc/pf.conf, on crée une redirection. Afin que ce soit totalement transparent, tout le traffic provenant du réseau local de type FTP sera redirigé vers ftp-proxy.
rdr on $Internal_If inet proto tcp from $Internal_Net to any port ftp -> $Loopback port 8021
La redirection n'ouvrant pas de ports, il faut donc autoriser explicitement ceux-ci. Dans cette situation, nous avons deux choix:
* Ouvrir une plage de ports complète suivant nos choix pour ftp-proxy dans inetd.conf
Dans le premier cas, on inscrit la ligne suivante dans /etc/pf.conf:
pass in on $External_If inet proto tcp from any to $External_If port 49500:50000 keep state
Dans le second (que je trouve plus élégant, puisque les ports ne sont ouverts qu'en cas de connection):
pass in on $External_If inet proto tcp from any to $External_If user proxy keep state
Relancez PF:
pfctl -f /etc/pf.conf
Et c'est fini.
Le serveur FTP d'OpenBSD utilise les ports supérieurs à 49152 par défaut (ce qui peut être restreind en consultant ftpd(8)). Il faut donc ouvrir cette plage et le port FTP pour que cela fonctionne.
pass in on $ext_if proto tcp from any to any port 21 keep state pass in on $ext_if proto tcp from any to any port > 49151 keep state
Dans ce cas, il faut à la fois rediriger le traffic et l'autoriser. En utilisant à nouveau le serveur ftp d'OpenBSD, cela revient à rediriger et autoriser les ports 21 et 49152 à 65535.
ftp_server = "10.0.3.21" rdr on $External_If proto tcp from any to any port 21 -> $ftp_server port 21 rdr on $External_If proto tcp from any to any port 49152:65535 -> $ftp_server port 49152:65535 # in on $External_If pass in quick on $External_If proto tcp from any to $ftp_server port 21 keep state pass in quick on $External_If proto tcp from any to $ftp_server port > 49151 keep state # out on $Internal_If pass out quick on $Internal_If proto tcp from any to $ftp_server port 21 keep state pass out quick on $Internal_If proto tcp from any to $ftp_server port > 49151 keep state
Cette fois on se retrouve face à un problème, les connections sont initiés depuis la machine locale, qui s'accroche aux ports de l'interface externe. Que fait-on? on ouvre une plage de ports? un peu barbare. Je n'aime pas laisser un plage de ports ouverts en permanence. La solution élégante: wget. Si on consulte la page de manuel wget(1), on y lit:
--bind-address=ADDRESS
When making client TCP/IP connections, "bind()" to
ADDRESS on the local machine. ADDRESS may be speci-
fied as a hostname or IP address. This option can be
useful if your machine is bound to multiple IPs.
Voilà qui est intéressant, on peut dire à wget de s'accrocher à une interface spécifique pour télécharger. Si on repense à ce qu'on disait pour les clients derrière un firewall NAT, l'idée devient intéressante. Toutes les connections passeraient par ftp-proxy. Ok, mais y a pas un moyen de rendre ceci transparent? Si, /etc/wgetrc, où on peut définir cette interface pour tout le monde: Maintenant, voyons un autre problème dans cette situation: comment faire pour les ports? certains MASTER_SITE forcent le FTP passif! En consultant la page de man de bsd.port.mk(5), il y est précisé que l'on peut définir un client autre que ftp(1):
FETCH_CMD Command used to fetch distribution files for this port.
Defaults to ftp(1). User settings. Can be used to go
through excessively paranoid firewalls.
Voilà qui tombe bien! une petite ligne FETCH_CMD=wget dans mk.conf(5) et le tour est joué.
J'éspère que cette doc est suffisement complète, le seul outil qui reste problématique pour moi est Midnight Commander, mais pour le reste, tout marche.
Auteur Original : Eric DILLENSEGER
Mis Sur Le Wiki Par Azwaw OUSADOU
Date De Parrution : 20/07/2009