La Fibre
Télécom => Réseau => TCP/IP / Fonctionnement des réseaux => Discussion démarrée par: corrector le 07 septembre 2011 à 02:04:49
-
Le protocole FTP préhistorique stipule que le port par défaut du coté serveur de la connexion de données est (port de la connexion de contrôle - 1), soit par défaut 21 - 1 = 20 (dit "ftp-data").
Bien sur, les plupart des clients FTP utilisent le mode passif (PASV, EPSV), et donc le serveur choisit un port dynamique sur lequel il accepte la connexion de données. Rien à dire.
Il y a des clients FTP auxquels on peut indiquer d'utiliser le mode actif (PORT, EPRT) : dans ce cas le client indique au serveur sur quelle IP et quel port le contacter. La préhistorique norme veut que le serveur utilise comme port source le port "ftp-data" 20.
Cette règle antique est parfaitement ridicule, le choix du port source n'ayant strictement aucun intérêt (voir pouvant causer un problème de sécurité).
Je suis curieux de savoir :
- à part FileZilla Server (Windows), quel serveur FTP implèmente cela?
- quelle proportion approximative de serveurs d'importance significative supportent cette ânerie?
- si une norme récente l'a abolie officiellement?
-
Je t'ai mis à disposition deux serveur FTP sous linux pour faire des tests de débit si tu souhaites tester l'implèmentation :
- ftp://1.testdebit.info
- 100ms.lafibre.info
En mode "actif", c'est bien le port 20 qui est utilisé.
Le mode passif est par contre celui utilisé par défaut.
-
Heu... le ftpd est en root? :o
-
bien sur que non !
même méthode que pour Apache qui écoute un port < 1024 et qui tourne avec l'utilisateur www-data
-
Il bind la socket en root, puis il change ses UID?
-
bien sur que non !
même méthode que pour Apache qui écoute un port < 1024 et qui tourne avec l'utilisateur www-data
Même méthode?
Apache est un serveur. Il a besoin d'un socket en tout.
FTPD est un client. Il a besoin d'un socket par connexion.
Je ne vois pas du tout de quoi tu parles.
-
bien sur que non !
même méthode que pour Apache qui écoute un port < 1024 et qui tourne avec l'utilisateur www-data
J'ai un peu cherché, et je n'ai trouvé aucun FTP qui puisse faire cela; sur les serveurs populaires, les options sont :
- le serveur est root (ou partiellement root sous linux), le port 20 est utilisé
- ou alors, le serveur n'est pas root, le port 20 n'est jamais utilisé, et donc le serveur n'est pas conforme à la norme
Tu utilises quoi?
-
J'utilise ProFTPd (https://fr.wikipedia.org/wiki/ProFTPd), un des serveurs GNU GPL les plus utilisés.
Un PS AUX montre bien qu'il n'est pas démarré en root :
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
proftpd 7917 0.0 0.0 92148 2224 ? Ss 06:45 0:00 proftpd: (accepting connections)
-
Quelle est la config? RootRevoke?
-
La config par défaut sous debian / ubuntu server fait que le port 20 est utilisé et que le serveur n'est pas root :
# Set the user and group that the server normally runs at.
User proftpd
Group nogroup
-
Que raconte /proc/7917/status ?
-
Voila :
$ cat /proc/7917/status
Name: proftpd
State: S (sleeping)
Tgid: 7917
Pid: 7917
PPid: 1
TracerPid: 0
Uid: 0 104 0 104
Gid: 65534 65534 65534 65534
FDSize: 64
Groups: 65534
VmPeak: 92152 kB
VmSize: 92148 kB
VmLck: 0 kB
VmHWM: 2224 kB
VmRSS: 2224 kB
VmData: 1160 kB
VmStk: 268 kB
VmExe: 616 kB
VmLib: 4896 kB
VmPTE: 184 kB
VmSwap: 0 kB
Threads: 1
SigQ: 1/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000010401000
SigCgt: 000000000081ecef
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1645
nonvoluntary_ctxt_switches: 0
vgu@ip:~$ cat /proc/7917/status
Name: proftpd
State: S (sleeping)
Tgid: 7917
Pid: 7917
PPid: 1
TracerPid: 0
Uid: 0 104 0 104
Gid: 65534 65534 65534 65534
FDSize: 64
Groups: 65534
VmPeak: 92152 kB
VmSize: 92148 kB
VmLck: 0 kB
VmHWM: 2224 kB
VmRSS: 2224 kB
VmData: 1160 kB
VmStk: 268 kB
VmExe: 616 kB
VmLib: 4896 kB
VmPTE: 184 kB
VmSwap: 0 kB
Threads: 1
SigQ: 1/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000010401000
SigCgt: 000000000081ecef
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1645
nonvoluntary_ctxt_switches: 0
Pour info :
$ uptime
13:38:34 up 17 days, 50 min, 1 user, load average: 0.00, 0.02, 0.05
$ free -m
total used free shared buffers cached
Mem: 3963 3642 321 0 213 3214
-/+ buffers/cache: 214 3749
Swap: 1905 0 1905
-
Uid: 0 104 0 104
Qu'est-ce que tu disais, pas root?
Explication pour les non-linuxiens : Documentation/filesystems/proc.txt (http://lxr.linux.no/#linux+v3.0.4/Documentation/filesystems/proc.txt#L211)
Uid Real, effective, saved set, and file system UIDs
On voit donc que :
UID = 0
saved UID = 0
Le serveur FTP tourne en root, CQFD.
-
Uid: 0 104 0 104
Gid: 65534 65534 65534 65534
Uid Real : 0 (root)
Uid effective : 104 (proftpd)
Uid saved set : 0 (root)
file system UIDs : 104 (proftpd)
Gid: Real, effective, saved set, and file system GIDs : 65534
ProFTPd est lancé en root mais bascule ensuite en proftpd.
-
Mais comme tu n'utilises pas RootRevoke (http://www.proftpd.org/docs/directives/linked/config_ref_RootRevoke.html), il se garde les droits super-utilisateur de coté, afin de pouvoir se conformer à la norme pour ce qui est du port 20.
De là à dire que c'est une pratique sure, il y a un pas.
-
Donc il faudrait changer la norme pour ne plus utiliser le port 20, mais un port > 1024, c'est préconisation ?
-
Concernant le protocole FTP
Concernant 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 serveur
Sous Unix
Sous 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) : capabilities
Depuis 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) (http://linux.die.net/man/7/capabilities), 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.
-
J'utilise le port 20 en active et ça marche très bien.
C'est tout à fait normal qu'il tourne avec les privilèges root si on utilise le /etc/passwd, autrement il suffit de lui donner la permission d'utiliser ce port.
-
J'utilise le port 20 en active et ça marche très bien.
Avec quelle config?
C'est tout à fait normal qu'il tourne avec les privilèges root si on utilise le /etc/passwd, autrement il suffit de lui donner la permission d'utiliser ce port.
Comment lui donner juste cette permission?
-
Comment lui donner juste cette permission?
bah, j'ai modifié le noyau comme tu suggères plus haut :-)