web-dev-qa-db-fra.com

Permettre à un utilisateur de laisser écouter un port inférieur à 1024

Je dois autoriser un utilisateur (différent de root) à exécuter un serveur à l'écoute sur le port 80.

Y a-t-il un moyen de faire ça?

65
peoro

setcap 'cap_net_bind_service=+ep' /path/to/program

cela fonctionnera pour des processus spécifiques. Mais pour permettre à un utilisateur particulier de se lier à des ports inférieurs à 1024, vous devrez l'ajouter aux sudoers.

Jetez un oeil à cela discussion pour en savoir plus.

53
Rohan Monga

(Certaines de ces méthodes ont été mentionnées dans d'autres réponses; je donne plusieurs choix possibles dans un ordre approximatif de préférence.)

Vous pouvez rediriger le port bas vers un port haut et écouter sur le port haut.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

Vous pouvez démarrer votre serveur en tant que privilèges root et drop une fois qu'il a commencé à écouter sur le port privilégié. De préférence, plutôt que de le coder vous-même, démarrez votre serveur à partir d'un wrapper qui fait le travail pour vous. Si votre serveur démarre une instance par connexion, démarrez-la à partir de inetd (ou d'un programme similaire tel que xinetd ). Pour inetd, utilisez une ligne comme celle-ci dans /etc/inetd.conf:

http  stream  tcp  nowait  username:groupname  /path/to/server/executable  argv[0] argv[1]…

Si votre serveur écoute dans une seule instance, démarrez-le à partir d'un programme tel que authbind . Soit créez un fichier vide /etc/authbind/byport/80 et le rendre exécutable pour l'utilisateur exécutant le serveur; ou créez /etc/authbind/byuid/1234, où 1234 est l'UID exécutant le serveur, contenant la ligne 0.0.0.0/0:80,80.

Si l'exécutable de votre serveur est stocké sur un système de fichiers qui prend en charge des capacités, vous pouvez lui donner le cap_net_bind_servicecapacité . Méfiez-vous que les capacités sont encore relativement nouvelles et ont encore quelques défauts .

setcap cap_net_bind_service=ep /path/to/server/executable

Authbind , @Gilles l'a déjà mentionné, mais je voudrais développer un peu.

Il dispose d'un contrôle d'accès pratique (détails dans la page de manuel): vous pouvez filtrer l'accès par port, adresse d'interface, uid, plages d'adresses ou de port et combinaison de ceux-ci.

Il a un paramètre très utile --depth:

--depth niveaux

Authbind affecte les programmes qui se trouvent à des niveaux profonds dans le graphique appelant. La valeur par défaut est 1.

"Niveaux profonds" signifie lorsqu'un script (ou programme), exécute un autre script, il descend d'un niveau. Donc, si vous avez --depth 5 cela signifie que sur les niveaux 1 (ou est-ce 0?) à 5, vous avez la permission de lier, tandis qu'au niveau 6 et sur, vous ne l'avez pas. Utile lorsque vous voulez qu'un script ait accès, mais pas les programmes qu'il exécute avec ou à votre insu.


Pour illustrer, vous pourriez avoir quelque chose comme ceci: pour des raisons de sécurité, vous avez un utilisateur Java qui est destiné à exécuter uniquement Java et vous voulez lui donner accès au port 80:

echo > /etc/authbind/byport/80
chown root:Java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80

J'ai créé le ../byport/80 file, donné au groupe d'utilisateurs Java (chaque utilisateur a son propre groupe), et l'a rendu exécutable par groupe, ce qui signifie qu'il est exécutable par Java utilisateur. Si vous donnez accès par port, le fichier doit être exécutable par l'utilisateur qui devrait y avoir accès, nous l'avons donc fait.

Cela peut être suffisant pour le Joe moyen, mais parce que vous savez comment utiliser le --depth paramètre, vous exécutez (en tant qu'utilisateur Java) authbind --depth [depth] my_web_app's_start_script à partir de --depth 1 et remonter jusqu'à trouver la plus petite profondeur qui fonctionne et l'utiliser.

Lisez la page de manuel pour plus de détails .

4

La réponse courte est que cela n'est pas possible par conception.

La réponse longue est que dans les mondes open source, il y a beaucoup de gens qui jouent avec le design et proposent des méthodes alternatives. En général, il est largement admis que cela ne devrait pas être possible. Le fait que vous essayiez signifie probablement que vous avez un autre défaut de conception dans votre système et que vous devriez reconsidérer l'ensemble de votre architecture système à la lumière des meilleures pratiques * nix et des implications en matière de sécurité.

Cela dit, un programme pour autoriser l'accès non root aux ports bas est authbind . selinux et grsecurity fournissent également des cadres pour de telles authentifications affinées.

Enfin, si vous voulez que des utilisateurs spécifiques exécutent des programmes spécifiques en tant que root et ce dont vous avez vraiment besoin, c'est simplement de permettre à un utilisateur de redémarrer Apache ou quelque chose comme ça, Sudo est votre ami!

4
Caleb

Vous pouvez utiliser netcat ou xinetd ou la redirection de port iptables, ou utiliser Apache comme proxy frontal et exécuter le processus sur un port non privilégié.

3
jamespo

J'ai essayé la méthode iptables PREROUTING REDIRECT, mais j'ai constaté qu'elle affecte également les paquets transférés. Autrement dit, si la machine transfère également des paquets entre des interfaces (par exemple, si elle agit comme un point d'accès Wi-Fi connecté à un réseau Ethernet), la règle iptables interceptera également les connexions des clients connectés vers des destinations Internet et les redirigera vers la machine. Ce n'est pas ce que je voulais - je voulais seulement rediriger les connexions qui étaient dirigées vers la machine elle-même.

Une possibilité consiste à utiliser TCP redirection de port. Par exemple en utilisant socat:

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

Cependant, un inconvénient de cette méthode est que l'application qui écoute sur le port 8080 ne connaît pas l'adresse source des connexions entrantes (par exemple pour la journalisation ou à d'autres fins d'identification).

1
Craig McQueen