Je dois autoriser un utilisateur (différent de root) à exécuter un serveur à l'écoute sur le port 80.
Est-ce qu'il y a un moyen de faire ça?
Je dois autoriser un utilisateur (différent de root) à exécuter un serveur à l'écoute sur le port 80.
Est-ce qu'il y a un moyen de faire ça?
Réponses:
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 aux ports inférieurs à 1024, vous devrez l’ajouter aux utilisateurs sudoers.
Regardez cette discussion pour plus.
(Certaines de ces méthodes ont été mentionnées dans d'autres réponses; je donne plusieurs choix possibles par ordre de préférence approximatif.)
Vous pouvez rediriger le port bas sur 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 root et supprimer des privilèges 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 à votre place. Si votre serveur démarre une instance par connexion, démarrez-le depuis inetd
(ou 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 en une seule instance, démarrez-le à partir d'un programme tel que authbind
. Soit créer un fichier vide /etc/authbind/byport/80
et le rendre exécutable pour l'utilisateur qui exécute le serveur; ou create /etc/authbind/byuid/1234
, où 1234 est l'UID exécutant le serveur, contenant la ligne 0.0.0.0/0:80,80
.
Si votre exécutable du serveur est stocké sur un système de fichiers qui prend en charge les capacités, vous pouvez lui donner la capacité . Attention, les fonctionnalités sont encore relativement nouvelles et ont encore quelques problèmes .cap_net_bind_service
setcap cap_net_bind_service=ep /path/to/server/executable
-A INPUT -p tcp --dport 1080 -j ACCEPT
sans quoi cela ne fonctionnerait pas (j'ai aussi une -j DROP
fourre-tout.) Il me reste donc deux sockets d'écoute.
La réponse courte est que cela n’est pas possible par conception.
La réponse longue est que dans les mondes open source, beaucoup de personnes 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 d'essayer signifie probablement que vous avez un autre défaut de conception dans votre système et que vous devez reconsidérer l'architecture de votre système tout entier à la lumière des meilleures pratiques * nix et des implications en matière de sécurité.
Cela dit, l'un des programmes permettant d'autoriser l'accès non root aux ports bas est authbind . Les deux SELinux et grsecurity fournissent également des cadres pour les authentifications à l' écoute de fines.
Enfin, si vous voulez que des utilisateurs spécifiques exécutent des programmes spécifiques en tant que root et que vous ayez vraiment besoin de permettre à un utilisateur de redémarrer Apache ou quelque chose du genre, sudo
c'est votre ami!
Vous pouvez utiliser la redirection de port netcat ou xinetd ou iptables, ou utiliser apache en tant que proxy frontal et exécuter le processus sur un port non privilégié.
Authbind , @Gilles en a déjà parlé, mais j'aimerais développer un peu.
Il offre un contrôle d’accès pratique (détails dans la page de manuel): vous pouvez filtrer les accès par port, adresse d’interface, uid, plages d’adresse ou de port et combinaison de ceux-ci.
Il a un paramètre très utile --depth
:
- niveaux de profondeur
Force authbind à affecter les programmes situés au plus profond du graphe appelant. La valeur par défaut est 1.
"Niveaux profonds" signifie quand un script (ou un programme) exécute un autre script qui descend d'un niveau. Donc, si vous avez --depth 5
cela signifie aux niveaux 1 (ou est-ce que c'est 0?) À 5, vous avez la permission de vous lier, alors qu'au niveau 6 et plus, vous n'avez pas. Utile lorsque vous voulez qu'un script ait accès, mais pas les programmes qu'il exécute avec ou sans votre connaissance.
Pour illustrer cela, vous pourriez avoir quelque chose comme ceci: pour des raisons de sécurité, vous avez un utilisateur java
qui est uniquement destiné à exécuter java et vous souhaitez 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
, le donné à un java
groupe d'utilisateurs (chaque utilisateur a son propre groupe) et je l'ai rendu exécutable par groupe, ce qui signifie qu'il est exécutable par java
utilisateur. Si vous donnez l'accès par port, le fichier doit être exécutable par l'utilisateur qui devrait y avoir accès. C'est ce que nous avons fait.
Cela peut être suffisant pour le Joe moyen, mais comme vous savez utiliser le --depth
paramètre, vous lancez (en tant java
qu'utilisateur) en authbind --depth [depth] my_web_app's_start_script
commençant --depth 1
et en remontant jusqu'à ce que vous trouviez la plus petite profondeur qui fonctionne et que vous l'utilisiez.
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 intercepte également les connexions des clients connectés aux destinations Internet et les redirige 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 le transfert de port TCP. Par exemple, en utilisant socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
Toutefois, l’un des inconvénients 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, à des fins de journalisation ou d’identification).