Concernant le protocole FTPConcernant la norme, comme j'ai dis je pense que la fixation du port source n'apporte strictement rien. D'ailleurs dans netfilter (le système de filtrage IP de linux) dans les sous-systèmes de suivi de conversations conntrack et de réécriture de paquet NAT, les gestionnaires du protocole FTP se moquent éperdument du choix du port source de la connexion de données non-passive.
En revanche, j'ai lu que dans le système de répartition de charge de linux (système des virtual servers), le gestionnaire du protocole FTP tient absolument au port 20 pour les connexions de données non-passives.
Concernant les clients FTP, je n'ai pas constaté de problème avec un port source arbitraire (p.ex. avec ftp.free.fr).
Concernant l'implèmentation du serveurSous UnixSous Un*x, il n'est pas possible de lier un socket Internet à un port privilégié (< 1024) sans être l'utilisateur privilégié justement, c'est à dire EUID = 0. Donc le serveur FTP doit rester privilégié (EUID = 0) ou garder le privilège d'être privilégié (UID = 0). (Je ne me souviens plus comment marche le saved UID de 0.)
Ce qui veut dire que toutes les restrictions mises en places comme chroot ne sont que de la complication inutile!
En réalité, il existe bien une solution pour que le serveur fonctionne en suivant la norme sans rester root. Comme on dit : pour tout problème qu'on ne sait résoudre, il faut ajouter un niveau d'indirection. Ici il faut séparer l'appel à bind(2) du reste du serveur, c'est à dire confier la production de socket TCP de port source 20 à un processus compagnon qui reste root, et que le serveur FTP se contente de connecter les sockets qu'il récupère.
Le passage de sockets entre processus se fait essentiellement au moment de la création d'un nouveau processus : les descripteurs de fichiers (filedes) du père sont repris dans le processus fils. Cela ne peut pas bien sûr être utilisé pour transférer des filedes en cours de fonctionnement d'un processus. Heureusement il existe un autre moyen : une socket connectée de domaine LOCAL (= UNIX = FILE) permet de passer un filedes à n'importe quel autre processus (même s'ils ont des *UID différents, *GID différents, ID de groupes additionnels différents, etc.).
Sous linux (et POSIX) : capabilitiesDepuis plus de 10 ans, linux promet de rendre les privilèges plus fins avec un gadget pathétique (inventé par POSIX) : les "capabilities", une atrocité "sécuritaire" (lire
capabilities(7), c'est à se rouler par terre). Les sockets Internet sont peut-être le seul domaine où cette glanderie a la moindre utilité!
Le principe des capabilities est de diviser les privilèges de EUID = 0 en plusieurs domaines séparés. (Sauf que la séparation est remarquablement foireuse, et les capabilities une grosse perte de temps.)
Ici on a bien l'exemple canonique de l'utilité des capabilities :
pour lier une socket à un port privilégié, il faut CAP_NET_BIND_SERVICE. Un des rares bénéfices "effectif" des capabilities.
Ceci les capabilities devraient quand même être exterminées. (Concernant le fait d'appliquer la même mesure aux zozos de chez POSIX, je n'ai pas d'avis.)
Solution "custom"Si c'est possible, je pense que la meilleure solution est de très légèrement modifier linux, pour attribuer définitivement certains ports à certains UID. (Non, je n'ai pas honte de suggérer ça. J'ai fait bien pire.)
C'est moche, mais pas plus que la bazar des capabilities.
Et ça n'introduira certainement pas de trous de sécurité, contrairement au bricolage de sécurité des capabilities.