54 votes

Se lier à des ports inférieurs à 1024 sans accès root

J'aimerais utiliser des applications sur lesquelles je travaille et qui se lient à des numéros de port inférieurs à 1000 sans avoir besoin d'un accès root.

J'utilise Linux Mint et j'ai un accès root pour le configurer. J'aimerais idéalement pouvoir le faire via SSH.

Je suis également heureux de savoir si c'est impossible ou si je ne devrais pas le faire, si c'est le cas.

EDIT : En général, je suis heureux d'utiliser des numéros de port plus élevés pour le développement, mais Flash attend une politique de socket sur le port 843. Actuellement, je dois exécuter l'application en tant que root et je ne peux donc pas l'exécuter à partir de mon Makefile, ce qui est une PITA.

8 votes

Ce n'est pas possible et vous ne devriez pas le faire :) (et si vous devez le faire, suexec et abandonnez les privilèges après le binding)

0 votes

@Tzarium - J'apprécie cette réponse directe, même si ce n'est pas ce que je voulais entendre :) Je vais malheureusement marquer comme accepté dans peu de temps.

3 votes

@Tzarium C'est non seulement possible mais facile si votre système supporte les capacités du système de fichiers. Voir l'article de @joeforker setcap réponse ci-dessous.

52voto

Roddy Points 32503

Bien sûr, c'est possible. Il suffit de donner au binaire CAP_NET_BIND_SERVICE.

sudo setcap cap_net_bind_service=ep some-binary

Dans Linux, les choses que la racine peut faire ont été divisées en un ensemble de capacités. CAP_NET_BIND_SERVICE est la capacité de se lier aux ports <= 1024.

Il est probablement possible d'utiliser AppArmor, SELinux ou un autre module de sécurité Linux (LSM) pour autoriser le programme à lier ce port en particulier, mais je pense que ce serait une perte de temps. La sécurité n'est plus vraiment basée sur les numéros de port comme elle l'était dans un passé lointain.

Voici un script pour OSX qui redirige les ports 80 et 443 vers des ports non privilégiés :

echo " 
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -ef -

0 votes

Génial, c'est la réponse que je cherchais. J'essaierai ce soir. Je vous remercie.

0 votes

Quelques informations supplémentaires sur pourquoi C'est la seule approche qui fonctionne : kneuro.net/cgi-bin/lxr/http/source/net/ipv4/ . PROT_SOCK =1024, et snum est le port ciblé.

0 votes

Pour les points bonus : consultez AccessFS pour un véritable retournement de situation.

45voto

Thierry-Dimitri Roy Points 449

Une autre façon de faire en sorte que votre démon réponde à des requêtes provenant d'un numéro de port inférieur est d'utiliser iptables ou un outil similaire pour rediriger un port inférieur vers le port supérieur sur lequel votre démon écoute :

sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080

Remplacez 80 par le port à exposer, et 8080 par le port d'écoute de votre application.

0 votes

Ok, cela semble être une solution viable. Je vais y réfléchir, merci.

4 votes

C'est ce que j'ai fait auparavant et cela fonctionne bien : iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 843 -j REDIRECT --to-port 8430 (redirige les connexions entrantes sur le port 843 vers le port 8430)

7 votes

Contrairement à setcap, n'importe quel programme, et pas seulement celui que vous avez désigné, pourra écouter sur le port non privilégié.

8voto

RobertPitt Points 410

Je pense qu'il y a un moyen de le faire mais je ne suis pas sûr à 100% que cela fonctionnerait.

c'est la liaison du port qui nécessite l'utilisateur root, pas l'application qui l'utilise, donc la méthode ci-dessous peut fonctionner mais vous devez avoir un accès sudo en premier lieu.

Tout d'abord, vous démarrez votre processus en tant qu'utilisateur root en utilisant sudo myApp Une fois que le port a été lié, vous pouvez changer le propriétaire du processus en un utilisateur non privilégié.

3 votes

Cela exécutera l'application en tant que root et exposera potentiellement le système à des risques de sécurité. Cela fonctionne, mais la redirection iptables est plus sûre.

5 votes

C'est ainsi que fonctionnent presque tous les démons ; root les démarre (init), ils ouvrent les ports nécessaires, puis transmettent leur UID/GID à un utilisateur non privilégié.

8voto

Simon Richter Points 3161

Je me souviens vaguement d'une bibliothèque appelée "authbind" qui fait ce dont vous avez besoin, en enveloppant l'appel système bind() (via une bibliothèque LD_PRELOAD) et, si un port privilégié est demandé, en lançant un programme root setuid qui reçoit une copie du descripteur de fichier, puis vérifie que l'application est effectivement autorisée à se lier au port, exécute le bind() et sort.

Je ne suis pas sûr de l'état d'avancement du projet, mais la méthode devrait être assez simple à (re)mettre en œuvre si nécessaire.

2 votes

Authbind est excellent. install authbind ; touch /etc/authbind/byport/{80,443} ; chown <username> /etc/authbind/byport/* ; chmod u+x /etc/authbind/byport/* ; authbind ./myprog

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X