C'est très ennuyeux d'avoir cette limitation sur ma boîte de développement, quand il n'y aura jamais d'autres utilisateurs que moi.
Je connais les solutions de contournement standard , mais aucun ne fait exactement ce que je veux:
- authbind (La version dans les tests Debian, 1.0, prend uniquement en charge IPv4)
- Utilisation de la cible iptables REDIRECT pour rediriger un port bas vers un port haut (la table "nat" n'est pas encore implémentée pour ip6tables, la version IPv6 d'iptables)
- sudo (Exécuter en tant que root est ce que j'essaie d'éviter)
- SELinux (ou similaire). (Ceci est juste ma boîte de développement, je ne veux pas introduire beaucoup de complexité supplémentaire.)
Existe-t-il une sysctl
variable simple pour permettre aux processus non root de se lier à des ports "privilégiés" (ports inférieurs à 1024) sous Linux, ou suis-je simplement malchanceux?
EDIT: Dans certains cas, vous pouvez utiliser des capacités pour ce faire.
Réponses:
D'accord, merci aux personnes qui ont souligné le système de
CAP_NET_BIND_SERVICE
capacités et la capacité. Si vous avez un noyau récent, il est en effet possible de l'utiliser pour démarrer un service en tant que non root mais lier des ports bas. La réponse courte est que vous faites:Et puis à tout moment
program
est exécuté par la suite, il aura laCAP_NET_BIND_SERVICE
capacité.setcap
est dans le paquet debianlibcap2-bin
.Maintenant pour les mises en garde:
program
qui ont des privilèges élevés commesetcap
ousuid
. Donc, si votreprogram
utilise le sien.../lib/
, vous devrez peut-être chercher une autre option comme la redirection de port.Ressources:
setcap
.Remarque: RHEL a d'abord ajouté cela dans la v6 .
la source
/usr/bin/java
, puis ouvrirait la capacité à n'importe quelle application java exécutée sur le système. Dommage que les capacités ne puissent pas non plus être définies par utilisateur./etc/security/capability.conf
sur Debian / Ubuntu une aide?Vous pouvez faire une redirection de port. Voici ce que je fais pour un serveur de stratégie Silverlight fonctionnant sur une boîte Linux
la source
/etc/network/if-up.d/firewall
.La manière standard est de les rendre "setuid" afin qu'ils démarrent en tant que root, puis ils jettent ce privilège root dès qu'ils se sont liés au port mais avant de commencer à accepter les connexions à celui-ci. Vous pouvez voir de bons exemples de cela dans le code source d'Apache et INN. On me dit que Lighttpd est un autre bon exemple.
Un autre exemple est Postfix, qui utilise plusieurs démons qui communiquent via des canaux, et seulement un ou deux d'entre eux (qui font très peu sauf accepter ou émettre des octets) s'exécutent en tant que root et le reste s'exécute avec un privilège inférieur.
la source
binfmt_misc
et son drapeau 'C'; je ne suis pas sûr pour les autres.)Ou corrigez votre noyau et supprimez la coche.
(Option de dernier recours, non recommandée).
Dans
net/ipv4/af_inet.c
, supprimez les deux lignes qui lisentet le noyau ne vérifiera plus les ports privilégiés.
la source
Vous pouvez configurer un tunnel SSH local, par exemple si vous voulez que le port 80 frappe votre application liée à 3000:
Cela a l'avantage de travailler avec des serveurs de script et d'être très simple.
la source
sudo nc -l 80 | nc localhost 3000
Mise à jour 2017:
Utiliser authbind
Beaucoup mieux que CAP_NET_BIND_SERVICE ou un noyau personnalisé.
Authbind accorde la confiance à l'utilisateur / groupe et fournit un contrôle sur l'accès par port, et prend en charge IPv4 et IPv6 (la prise en charge IPv6 a été ajoutée récemment).
Installer:
apt-get install authbind
Configurez l'accès aux ports appropriés, par exemple 80 et 443 pour tous les utilisateurs et groupes:
Exécutez votre commande via
authbind
(en spécifiant éventuellement
--deep
ou d'autres arguments, voir la page de manuel):par exemple
Dans le prolongement de la fabuleuse recommandation de Joshua (= déconseillée sauf si vous savez ce que vous faites) de pirater le noyau:
Je l'ai d'abord posté ici .
Facile. Avec un noyau normal ou ancien, vous ne le faites pas.
Comme souligné par d'autres, iptables peut transférer un port.
Comme d'autres l'ont également souligné, CAP_NET_BIND_SERVICE peut également faire le travail.
Bien sûr, CAP_NET_BIND_SERVICE échouera si vous lancez votre programme à partir d'un script, sauf si vous définissez le plafond sur l'interpréteur de commandes, ce qui est inutile, vous pourriez tout aussi bien exécuter votre service en tant que root ...
par exemple pour Java, vous devez l'appliquer à la JAVA JVM
Évidemment, cela signifie alors que tout programme Java peut lier des ports système.
Dito pour mono / .NET.
Je suis également sûr que xinetd n'est pas la meilleure des idées.
Mais comme les deux méthodes sont des hacks, pourquoi ne pas simplement lever la limite en levant la restriction?
Personne n'a dit que vous deviez exécuter un noyau normal, vous pouvez donc simplement exécuter le vôtre.
Vous venez de télécharger la source pour le dernier noyau (ou le même que vous avez actuellement). Ensuite, vous allez à:
Là vous cherchez cette ligne
et changez-le en
si vous ne voulez pas avoir une situation ssh non sécurisée, vous la modifiez comme suit: #define PROT_SOCK 24
En règle générale, j'utiliserais le paramètre le plus bas dont vous avez besoin, par exemple 79 pour http, ou 24 lorsque vous utilisez SMTP sur le port 25.
C'est déjà tout.
Compilez le noyau et installez-le.
Redémarrez.
Terminé - cette limite stupide est GONE, et cela fonctionne également pour les scripts.
Voici comment compiler un noyau:
https://help.ubuntu.com/community/Kernel/Compile
En un mot, utilisez iptables si vous voulez rester en sécurité, compilez le noyau si vous voulez être sûr que cette restriction ne vous dérange plus.
la source
Les capacités des fichiers ne sont pas idéales, car elles peuvent se casser après une mise à jour du package.
La solution idéale, à mon humble avis, devrait être une capacité à créer un shell avec héritable
CAP_NET_BIND_SERVICE
ensemble .Voici une façon quelque peu compliquée de le faire:
capsh
l'utilitaire peut être trouvé dans le paquet libcap2-bin dans les distributions Debian / Ubuntu. Voici ce qui se passe:sg
remplace l'ID de groupe effectif par celui de l'utilisateur du démon. Ceci est nécessaire carcapsh
GID reste inchangé et nous ne le voulons certainement pas.$DAEMONUSER
--keep=1
), sauf héritablecap_net_bind_service
Le résultat est un processus avec un utilisateur et un groupe et des
cap_net_bind_service
privilèges spécifiés .À titre d'exemple, une ligne du
ejabberd
script de démarrage:la source
capsh
faire quoi que ce soit autre que « ne peut pas exécuter le fichier binaire » lorsque vous utilisez les--
ou==
options. Je me demande ce qui me manque.--
est transmis à/bin/bash
, donc vous voudrez peut-être essayer avec-c 'your command'
. Hélas, je semble rencontrer le même problème que @Cyberax, car j'obtiens une "autorisation refusée" lorsque j'essayebind
.--gid
lieu desg
(ou--user
qui ensembles--uid
,--gid
et--groups
):sudo capsh --caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' --keep=1 --user="$service_user" --addamb=cap_net_bind_service -- -c 'exec $service $service_args'
Pour une raison quelconque, personne ne mentionne la réduction de sysctl net.ipv4.ip_unprivileged_port_start à la valeur dont vous avez besoin. Exemple: nous devons lier notre application au port 443.
Certains pourraient dire qu'il existe un problème de sécurité potentiel: les utilisateurs non privilégiés peuvent désormais se lier aux autres ports privilégiés (444-1024). Mais vous pouvez résoudre ce problème facilement avec iptables, en bloquant d'autres ports:
Comparaison avec d'autres méthodes. Cette méthode:
Selon la situation, je choisirais entre sysctl, CAP, authbind et iptables-redirect. Et c'est formidable que nous ayons tant d'options.
la source
Deux autres possibilités simples:
Il existe une ancienne solution (démodée) au "démon qui se lie sur un port bas et remet le contrôle à votre démon". Cela s'appelle inetd (ou xinetd). Les inconvénients sont:
Avantages:
Une autre alternative: un proxy piraté (netcat ou même quelque chose de plus robuste ) du port privilégié à un port arbitraire de numéro élevé où vous pouvez exécuter votre démon cible. (Netcat n'est évidemment pas une solution de production, mais "juste ma boîte de développement", non?). De cette façon, vous pourriez continuer à utiliser une version compatible réseau de votre serveur, n'auriez besoin que de root / sudo pour démarrer le proxy (au démarrage), ne dépendriez pas de capacités complexes / potentiellement fragiles.
la source
Ma «solution de contournement standard» utilise socat comme redirecteur de l'espace utilisateur:
Attention, cela ne va pas évoluer, la fourche coûte cher mais c'est la façon dont socat fonctionne.
la source
Linux prend en charge des capacités pour prendre en charge des autorisations plus précises que simplement "cette application est exécutée en tant que root". L'une de ces capacités
CAP_NET_BIND_SERVICE
concerne la liaison à un port privilégié (<1024).Malheureusement, je ne sais pas comment exploiter cela pour exécuter une application en tant que non root tout en la donnant
CAP_NET_BIND_SERVICE
(probablement en utilisantsetcap
, mais il y a forcément une solution existante pour cela).la source
Je sais que c'est une vieille question, mais maintenant avec les noyaux récents (> = 4.3), il y a enfin une bonne réponse à cela - les capacités ambiantes.
La réponse rapide est de récupérer une copie de la dernière version (non encore publiée) de libcap de git et de la compiler. Copiez le
progs/capsh
binaire résultant quelque part (/usr/local/bin
c'est un bon choix). Ensuite, en tant que root, démarrez votre programme avecDans l'ordre, nous sommes
cap_net_bind_service
capacité aux ensembles hérités et ambiantsbash -c 'your-command'
(puisquecapsh
démarre automatiquement bash avec les arguments après--
)Il se passe beaucoup de choses sous le capot ici.
Premièrement, nous fonctionnons en tant que root, donc par défaut, nous obtenons un ensemble complet de capacités. Inclus dans cela est la possibilité de changer uid & gid avec les appels système
setuid
etsetgid
sys. Cependant, habituellement, lorsqu'un programme fait cela, il perd son ensemble de capacités - c'est ainsi que l'ancienne méthode de suppression de root avecsetuid
fonctionne toujours. L'--keep=1
indicateur indiquecapsh
d'émettre l'prctl(PR_SET_KEEPCAPS)
appel système, qui désactive la suppression des capacités lors du changement d'utilisateur. Le changement réel d'utilisateurscapsh
se produit avec le--user
drapeau, qui s'exécutesetuid
etsetgid
.Le prochain problème que nous devons résoudre est de savoir comment définir les capacités d'une manière qui continue après nous,
exec
nos enfants. Le système de capacités a toujours eu un ensemble de capacités «héritées», qui est «un ensemble de capacités préservées à travers un execve (2)» [ capacités (7) ]. Bien que cela semble résoudre notre problème (définissez simplement lacap_net_bind_service
capacité sur hérité, non?), Cela ne s'applique en fait que pour les processus privilégiés - et notre processus n'est plus privilégié, car nous avons déjà changé d'utilisateur (avec l'--user
indicateur).Le nouvel ensemble de capacités ambiantes contourne ce problème - c'est "un ensemble de capacités qui sont préservées sur un execve (2) d'un programme qui n'est pas privilégié". En mettant
cap_net_bind_service
dans l'ensemble ambiant, lorsquecapsh
exec est notre programme serveur, notre programme héritera de cette capacité et pourra lier des écouteurs à des ports bas.Si vous souhaitez en savoir plus, la page du manuel des fonctionnalités explique cela en détail. Courir à
capsh
traversstrace
est également très instructif!la source
--addamb
drapeau a été introduit avec libcap 2.26. Mon système avait 2.25 et je devais construire à partir des sources.TLDR: Pour "la réponse" (telle que je la vois), passez à la partie >> TLDR << de cette réponse.
OK, je l'ai compris (pour de vrai cette fois), la réponse à cette question, et cette réponse est aussi un moyen de m'excuser d'avoir fait la promotion d' une autre réponse (ici et sur Twitter) que je pensais être "la meilleure ", mais après l'avoir essayé, j'ai découvert que je me trompais. Apprenez de mes erreurs les enfants: ne faites pas la promotion de quelque chose avant de l'avoir essayé vous-même!
Encore une fois, j'ai passé en revue toutes les réponses ici. J'ai essayé certains d'entre eux (et j'ai choisi de ne pas en essayer d'autres parce que je n'aimais tout simplement pas les solutions). Je pensais que la solution était d'utiliser
systemd
avec ses paramètresCapabilities=
etCapabilitiesBindingSet=
. Après avoir lutté avec cela pendant un certain temps, j'ai découvert que ce n'était pas la solution car:Les capacités visent à restreindre les processus root!
Comme l'OP l'a judicieusement indiqué, il est toujours préférable d'éviter cela (pour tous vos démons si possible!).
Vous ne pouvez pas utiliser les options liées aux capacités avec
User=
etGroup=
dans lessystemd
fichiers d'unité, car les capacités sont TOUJOURS réinitialisées lorsqueexecev
(ou quelle que soit la fonction) est appelée. En d'autres termes, lorsque lasystemd
fourche et baisse ses perms, les capacités sont réinitialisées. Il n'y a aucun moyen de contourner cela, et toute cette logique de liaison dans le noyau est basique autour de uid = 0, pas de capacités. Cela signifie qu'il est peu probable que les capacités soient jamais la bonne réponse à cette question (au moins dans un proche avenir). Par ailleurs,setcap
comme d'autres l'ont mentionné, ce n'est pas une solution. Cela n'a pas fonctionné pour moi, cela ne fonctionne pas bien avec les scripts, et ceux-ci sont réinitialisés de toute façon chaque fois que le fichier change.Dans ma maigre défense, j'ai déclaré (dans le commentaire que j'ai maintenant supprimé) que la suggestion de James iptables (que le PO mentionne également) était la "2ème meilleure solution". :-P
>> TLDR <<
La solution consiste à combiner
systemd
avec desiptables
commandes à la volée , comme celle-ci ( tirée de DNSChain ):Ici, nous accomplissons ce qui suit:
iptables
systemd
nettoie les règles de pare-feu pour nous, en veillant à les supprimer lorsque le démon n'est pas en cours d'exécution.systemd
prétend), même si le démon est compromis et définiuid=0
.iptables
est encore, malheureusement, un utilitaire assez laid et difficile à utiliser. Si le démon écoute aueth0:0
lieu deeth0
, par exemple, les commandes sont légèrement différentes .la source
eth0:0
moins d'avoir une distribution Linux vraiment ancienne . Ils sont obsolètes depuis des années et finiront par disparaître.# Generated by SolusVM
AmbientCapabilities=CAP_NET_BIND_SERVICE
a parfaitement fonctionné pour moi en combinaison avecUser=
.systemd est un remplacement de sysvinit qui a une option pour lancer un démon avec des capacités spécifiques. Options Capabilities =, CapabilityBoundingSet = dans la page de manuel systemd.exec (5) .
la source
systemd
.La redirection de port était la plus logique pour nous, mais nous avons rencontré un problème où notre application résoudrait une URL localement qui devait également être réacheminée; (cela signifie que vous shindig ).
Cela vous permettra également d'être redirigé lors de l'accès à l'URL sur la machine locale.
la source
Prise en charge de Linux moderne
/sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0
.la source
Avec systemd, il vous suffit de modifier légèrement votre service pour accepter les sockets préactivés.
Vous pourrez ultérieurement utiliser la prise systemd socket activate .
Aucune capacité, iptables ou autres astuces ne sont nécessaires.
C'est le contenu des fichiers systemd pertinents de cet exemple de serveur http python simple
Fichier
httpd-true.service
Fichier
httpd-true.socket
la source
Au démarrage:
Ensuite, vous pouvez vous lier au port vers lequel vous transférez.
la source
--to-port
n'existe?man iptables
mentionne seulement--to-ports
(pluriel).systemd
.Utilisez l' utilitaire privbind : il permet à une application non privilégiée de se lier aux ports réservés.
la source
Il y a aussi la «voie djb». Vous pouvez utiliser cette méthode pour démarrer votre processus en tant que root s'exécutant sur n'importe quel port sous tcpserver, puis il donnera le contrôle du processus à l'utilisateur que vous spécifiez immédiatement après le démarrage du processus.
Pour plus d'informations, voir: http://thedjbway.b0llix.net/daemontools/uidgid.html
la source
Étant donné que l'OP n'est qu'un développement / test, des solutions moins qu'élégantes peuvent être utiles:
setcap peut être utilisé sur l'interpréteur d'un script pour accorder des capacités aux scripts. Si setcaps sur le binaire de l'interpréteur global n'est pas acceptable, faites une copie locale du binaire (n'importe quel utilisateur peut) et obtenez root pour setcap sur cette copie. Python2 (au moins) fonctionne correctement avec une copie locale de l'interpréteur dans votre arbre de développement de script. Aucun suid n'est nécessaire pour que l'utilisateur root puisse contrôler les capacités auxquelles les utilisateurs ont accès.
Si vous devez suivre les mises à jour de l'interpréteur à l'échelle du système, utilisez un script shell comme le suivant pour exécuter votre script:
la source
J'ai essayé la méthode iptables PREROUTING REDIRECT. Dans les noyaux plus anciens, il semble que ce type de règle ne soit pas pris en charge pour IPv6 . Mais apparemment, il est désormais pris en charge dans ip6tables v1.4.18 et le noyau Linux v3.8.
J'ai également constaté que PREROUTING REDIRECT ne fonctionne pas pour les connexions initiées dans la machine. Pour travailler pour les connexions depuis la machine locale, ajoutez également une règle de SORTIE - voir La redirection de port iptables ne fonctionne pas pour localhost . Par exemple, quelque chose comme:
J'ai également constaté que PREROUTING REDIRECT 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. J'ai trouvé que je peux faire en sorte qu'il n'affecte que les paquets adressés à la boîte, en ajoutant
-m addrtype --dst-type LOCAL
. Par exemple, quelque chose comme:Une autre possibilité consiste à utiliser la redirection de port TCP. Par exemple en utilisant
socat
: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).
la source
Réponse à 2015 / septembre:
ip6tables prend désormais en charge IPV6 NAT: http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt
Vous aurez besoin du noyau 3.7+
Preuve:
la source