Bien que 80 et 443 soient des ports système, comment la plupart des serveurs Web peuvent-ils s'y lier de toute façon?

18

L'exécution d'un service Web qui se lie au port 80 ne nécessite généralement pas de privilèges sudoer. Étant donné que les ports 80/443 sont des ports système, ce qui signifie qu'ils ne peuvent être utilisés que par des utilisateurs privilégiés, comment se fait-il que ces services puissent toujours se lier à ces ports?

adaml
la source
1
"ne requiert généralement pas les privilèges sudoer" est incorrect.
tedder42

Réponses:

29

Il existe essentiellement deux approches différentes:

  1. Commencez initialement à exécuter en tant que root, liez au port privilégié, puis accédez à un utilisateur non privilégié.

  2. inetd ou xinetd s'exécute avec privilèges et transfère les requêtes au serveur Web fonctionnant sans privilèges.

Joe Sniderman
la source
3
Sous Linux, vous pouvez également appliquer la capacité CAP_NET_BIND_SERVICE au programme ou vous pouvez utiliser iptables pour rediriger un port système vers un port normal.
Zan Lynx,
10
et juste pour clarifier pour OP: l'option # 1 fonctionne parce que lorsque les processus abandonnent les privilèges, ils sont autorisés à conserver les descripteurs de fichiers ouverts - même s'ils ne seraient pas autorisés à les ouvrir une deuxième fois.
strugee
Il y a aussi Authbind .
Boris l'araignée
5

Étant donné que le port 80/443 sont des ports système, ce qui signifie qu'ils ne peuvent être utilisés que par des utilisateurs privilégiés

Je pense que vous vous trompez. Tout le monde peut utiliser ces ports. Contraignant avec eux est une opération privilégiée.

La raison ici est qu'un utilisateur Joe ne devrait pas être en mesure d'écrire un serveur Web malveillant et de créer un hôte sur lequel il n'a aucun droit d'administration. Bien sûr, c'est un modèle assez faible, rien n'empêche généralement Joe de mettre son propre ordinateur sur le réseau, et il pourrait avoir des droits administratifs sur n'importe quelle machine à laquelle il a un accès physique.

Je ferai une démonstration avec netcat.

En tant qu'utilisateur ordinaire, je ne peux pas me lier au port 80:

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

Je peux me lier au port 8080:

$ nc -l -p 8080

Pendant ce temps, dans un autre terminal, je peux me connecter au port 80 et envoyer des données, et les voir apparaître côté serveur, je viens de commencer:

$ nc 127.0.0.1 8080 <<<"Hello world"

Si je veux me lier au port 80, je dois être root:

$ sudo nc -l -p 80

Ou je peux attribuer la CAP_NET_BIND_SERVICEcapacité aunc binaire:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

Une autre option consiste à écrire le programme serveur de telle sorte qu'après son appel, listen()il abandonne les privilèges root. C'est une solution assez courante, et vous la verrez avec la plupart des démons. Apache, par exemple, démarre à partir d'init en tant que root, puis abandonne les privilèges root et devient l'utilisateur www-dataou quelque chose de similaire une fois qu'il est lié au port 80. Essayez /etc/init.d/apache startde lancer en tant que non root et Apache échouera probablement au démarrage.

Phil Frost
la source
La question dit "se lier à ces ports". Pourquoi pensez-vous qu'il s'est trompé?
Barmar