web-dev-qa-db-fra.com

Existe-t-il un moyen pour les processus non root de se lier aux ports "privilégiés" sous Linux?

C'est très ennuyant d'avoir cette limitation sur ma boîte de développement, alors qu'il n'y aura jamais d'autres utilisateurs que moi.

Je suis conscient de les solutions de contournement standard , mais aucun ne fait exactement ce que je veux:

  1. authbind (La version de test de Debian, 1.0, ne supporte que IPv4)
  2. tilisation de la cible REDIRECT d'iptables 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)
  3. Sudo (J'essaie d'éviter de courir en tant que root)
  4. SELinux (ou similaire). (Ceci est juste ma boîte de dev, je ne veux pas introduire beaucoup de complexité supplémentaire.)

Existe-t-il une variable simple sysctl permettant aux processus non root de se lier à des ports "privilégiés" (ports inférieurs à 1024) sous Linux, ou ai-je tout simplement de la chance?

EDIT: Dans certains cas, vous pouvez tiliser des fonctionnalités pour le faire.

356
Jason Creighton

Très bien, merci aux personnes qui ont signalé le système de capacités et la capacité CAP_NET_BIND_SERVICE. Si vous avez un noyau récent, il est en effet possible de l'utiliser pour démarrer un service en tant que lecteur non root mais lier des ports faibles. La réponse courte est que vous faites:

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

Et puis à tout moment, program est exécuté par la suite, il aura la capacité CAP_NET_BIND_SERVICE. setcap est dans le paquet Debian libcap2-bin.

Maintenant pour les mises en garde:

  1. Vous aurez besoin d'au moins un noyau 2.6.24
  2. Cela ne fonctionnera pas si votre fichier est un script. (c’est-à-dire qu’il utilise une ligne #! pour lancer un interprète). Si je comprends bien, dans ce cas, vous devez appliquer la capacité à l'exécutable de l'interprète lui-même, ce qui est bien sûr un cauchemar pour la sécurité, car tout programme utilisant cet interpréteur en aura la capacité. Je n'ai pas été en mesure de trouver un moyen simple et clair de contourner ce problème.
  3. Linux désactivera LD_LIBRARY_PATH sur tout program disposant de privilèges élevés, comme setcap ou suid. Ainsi, si votre program utilise son propre .../lib/, vous devrez peut-être envisager une autre option, telle que la redirection de port.

Ressources:

Remarque: RHEL a d'abord ajouté ceci dans la v6 .

367
Jason Creighton

La méthode standard consiste à les définir comme "setuid" afin qu'ils démarrent en tant que root, puis ils jettent ce privilège root dès qu'ils se sont connectés au port, mais avant de commencer à accepter les connexions avec celui-ci. Vous pouvez en voir de bons exemples dans le code source d’Apache et de 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. Seuls un ou deux d'entre eux (qui ne font que 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.

31
Paul Tomblin

Vous pouvez faire une redirection de port. C’est ce que je fais pour un serveur de règles Silverlight fonctionnant sous Linux

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
31
FlappySocks

Ou corrigez votre noyau et supprimez la vérification.

(Option de dernier recours, non recommandé).

Dans net/ipv4/af_inet.c, supprimez les deux lignes qui lisent

      if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
              goto out;

et le noyau ne vérifiera plus les ports privilégiés.

20
Joshua

Vous pouvez configurer un tunnel SSH local, par exemple si vous voulez que le port 80 frappe votre application liée à 3000:

Sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

Cela présente l’avantage de travailler avec des serveurs de script et d’être très simple.

19
Gabriel Burt

Les fonctionnalités de fichier ne sont pas idéales, car elles peuvent se rompre après la mise à jour d'un paquet.

La solution idéale, à mon humble avis, devrait être la possibilité de créer un shell avec un jeu CAP_NET_BIND_SERVICE héritable.

Voici une façon un peu compliquée de faire ceci:

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

L'utilitaire capsh peut être trouvé dans le paquet libcap2-bin des distributions Debian/Ubuntu. Voici ce qui se passe:

  • sg change l'identifiant de groupe effectif en celui de l'utilisateur démon. Ceci est nécessaire parce que capsh laisse GID inchangé et nous ne l’en voulons absolument pas.
  • Définit le bit 'garder les capacités sur le changement d'UID'.
  • Change UID en $DAEMONUSER
  • Supprime toutes les majuscules (à ce moment toutes les majuscules sont encore présentes à cause de --keep=1), à l'exception de cap_net_bind_service pouvant être hérité
  • Exécute votre commande ('-' est un séparateur)

Le résultat est un processus avec l'utilisateur et le groupe spécifiés, ainsi que les privilèges cap_net_bind_service.

Par exemple, une ligne du script de démarrage ejabberd:

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"
18
Cyberax

Mise à jour 2017:

Utilisez authbind




  • CAP_NET_BIND_SERVICE accorde la confiance au binaire mais ne fournit aucun contrôle sur l'accès par port.
  • Authbind accorde la confiance à l'utilisateur/au groupe et permet de contrôler l'accès par port. Il prend en charge IPv4 et IPv6 (la prise en charge d'IPv6 a été ajoutée récemment).

    1. Installer: apt-get install authbind

    2. Configurez l’accès aux ports appropriés, par exemple 80 et 443 pour tous les utilisateurs et groupes:

      Touchez Sudo/etc/authbind/byport/80
      Sudo touch// etc/authbind/byport/443
      Sudo chmod 777/etc/authbind/byport/80
      Sudo chmod 777/etc/authbind/byport/443

    3. Exécutez votre commande via authbind
      (spécifiant éventuellement --deep ou d'autres arguments, voir la page de manuel):

      authbind --deep /path/to/binary command line args
      

      par exemple.

      authbind --deep Java -jar SomeServer.jar
      

En guise de suivi de la recommandation fabuleuse (= non recommandée à moins que vous ne sachiez ce que vous faites) de pirater le noyau:

Je l'ai d'abord posté ici .

Facile. Avec un noyau normal ou ancien, ce n'est pas le cas.
Comme l'ont souligné d'autres personnes, 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 une limite sur l'interpréteur Shell, 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 JVM Java

Sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/Java-8-openjdk/jre/bin/Java

Cela signifie évidemment que tout programme Java peut lier des ports système.
Dito pour mono/.NET.

Je suis également convaincu que xinetd n'est pas la meilleure des idées.
Mais puisque 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 exécuter le vôtre.

Vous venez de télécharger le code source du dernier noyau (ou du même logiciel que vous avez actuellement). Ensuite, vous allez à:

/usr/src/linux-<version_number>/include/net/sock.h:

Là vous cherchez cette ligne

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

et le changer en

#define PROT_SOCK 0

si vous ne voulez pas avoir une situation ssh non sécurisée, vous la changez en ceci: #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 vous compilez un noyau:

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

En bref, 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.

15
Stefan Steiger

Deux autres possibilités simples:

Il existe une ancienne solution (non à la mode) au "démon qui se lie sur un port faible et qui contrôle le démon". Cela s'appelle inetd (ou xinetd). Les inconvénients sont:

  • votre démon doit parler sur stdin/stdout (si vous ne le contrôlez pas - si vous n'avez pas la source - alors c'est peut-être un showstopper, bien que certains services puissent avoir un indicateur de compatibilité inetd)
  • un nouveau processus démon est créé pour chaque connexion
  • c'est un maillon supplémentaire dans la chaîne

Avantages:

  • disponible sur tout ancien UNIX
  • une fois que votre administrateur système a configuré la configuration, vous pouvez poursuivre votre développement (lorsque vous reconstruisez votre démon, risquez-vous de perdre les fonctionnalités de setcap? Ensuite, vous devrez revenir à votre administrateur ", s'il vous plaît, monsieur .. . ")
  • le démon n'a pas à s'inquiéter de ce genre de réseau, il suffit de parler sur stdin/stdout
  • peut configurer pour exécuter votre démon en tant qu'utilisateur non root, comme demandé

Une autre alternative: un proxy piraté (netcat ou même quelque chose plus robuste) du port privilégié à un port arbitraire portant un 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 dev", non?). De cette façon, vous pouvez continuer à utiliser une version de votre serveur compatible réseau, vous n’auriez besoin que de root/Sudo pour démarrer le proxy (au démarrage), sans compter sur des capacités complexes/potentiellement fragiles.

15
Martin Carpenter

Mon "solution de contournement standard" utilise socat comme redirecteur d'espace utilisateur:

socat tcp6-listen:80,fork tcp6:8080

Attention, cela n'échelonnera pas, le bricolage coûte cher, mais c'est la façon dont fonctionne le socat.

14
Astro

Je sais que c’est une vieille question, mais avec les noyaux récents (> = 4.3), il ya finalement 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 binaire progs/capsh résultant quelque part (/usr/local/bin est un bon choix). Ensuite, en tant que root, lancez votre programme avec

/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
    --inh='cap_net_bind_service' --addamb='cap_net_bind_service' \ 
    -- -c 'your-program'

Dans l'ordre, nous sommes

  • En déclarant que lorsque nous changeons d’utilisateur, nous voulons conserver nos ensembles de capacités actuels.
  • Changer d'utilisateur et de groupe pour 'votre-nom-service-service'
  • Ajout de la capacité cap_net_bind_service aux ensembles & ambient hérités
  • Forking bash -c 'your-command' (puisque capsh démarre automatiquement bash avec les arguments après --)

Il se passe beaucoup de choses sous le capot ici.

Tout d’abord, nous fonctionnons en tant qu’utilisateur root. Par conséquent, nous disposons par défaut d’un ensemble complet de fonctionnalités. Cela inclut la possibilité de commuter uid & gid avec les appels système setuid et setgid. Cependant, normalement, lorsqu'un programme fait cela, il perd son ensemble de capacités - c'est ainsi que l'ancienne méthode de suppression de racine avec setuid fonctionne toujours. L’indicateur --keep=1 indique à capsh d’émettre le prctl(PR_SET_KEEPCAPS) syscall, qui désactive la suppression de fonctionnalités lors du changement d’utilisateur. Le changement effectif d'utilisateurs de capsh a lieu avec l'indicateur --user, qui exécute setuid et setgid.

Le problème suivant que nous devons résoudre est de savoir comment définir les capacités de manière à ce que nous continuions après 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 sur un execve (2)" [ capacités (7) ]. Bien que cela semble résoudre notre problème (il suffit de définir la capacité cap_net_bind_service sur héritée, non?), Cela ne s'applique en réalité qu'aux processus privilégiés - et notre processus n'est plus privilégié, car nous avons déjà changé d'utilisateur (avec le --user drapeau).

Le nouvel ensemble de capacités ambiantes contourne ce problème: il s'agit "d'un ensemble de capacités préservées sur un execve (2) d'un programme non privilégié". En plaçant cap_net_bind_service dans le jeu d'ambiances, lorsque capsh exec est notre programme serveur, notre programme héritera de cette capacité et pourra lier les écouteurs à des ports bas.

Si vous souhaitez en savoir plus, les capacités page de manuel expliquent cela en détail. Utiliser capsh à strace est également très instructif!

13
KJ Tsanaktsidis

Linux prend en charge fonctionnalités pour prendre en charge des autorisations plus détaillées que "cette application est exécutée en tant que root". Une de ces fonctionnalités est CAP_NET_BIND_SERVICE, qui 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 lui donnant CAP_NET_BIND_SERVICE (utilisant probablement setcap , mais il y a forcément une solution existante pour cela) .

13
Joachim Sauer

TLDR: Pour "la réponse" (à mon avis), sautez à 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 s'excuser pour la promotion de une autre réponse (les deux ici et sur Twitter) que je pensais être "le meilleur", mais après l'avoir essayé, j'ai découvert que je m'étais trompé à ce sujet. Apprenez de mon erreur, 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 consistait à utiliser systemd avec ses paramètres Capabilities= et CapabilitiesBindingSet=. Après avoir lutté avec cela pendant un certain temps, j'ai découvert que ce n'était pas la solution car:

Les fonctionnalités sont destinées à restreindre les processus racine!

Comme l'OP l'a sagement déclaré, 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 fonctionnalités avec User= et Group= dans systemd fichiers d'unité, car les fonctionnalités sont TOUJOURS réinitialisées lorsque execev (ou quelle que soit la fonction) est appelée. En d’autres termes, lorsque systemd forche et abandonne ses perms, les capacités sont réinitialisées. Il n'y a pas 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 Capabilities fournira jamais la bonne réponse à cette question (du moins dans un avenir rapproché). Incidemment, setcap, comme d'autres l'ont mentionné, n'est pas une solution. Cela n'a pas fonctionné pour moi, cela ne fonctionne pas très bien avec les scripts, et ceux-ci sont réinitialisés quand le fichier change.

Dans ma maigre défense, j’ai indiqué (dans le commentaire que j’ai maintenant supprimé), que la suggestion de James iptables (que le PO mentionne également) était la "2e meilleure solution" ". :-P

>> TLDR <<

La solution consiste à combiner systemd avec des commandes à la volée iptables, comme ceci ( tiré de DNSChain ):

[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service

[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc

# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps

[Install]
WantedBy=multi-user.target

Ici, nous accomplissons les tâches suivantes:

  • Le démon écoute 5333, mais les connexions sont acceptées sur 53 grâce à iptables
  • Nous pouvons inclure les commandes dans le fichier unité lui-même et ainsi éviter les maux de tête aux gens. 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.
  • Nous ne courons jamais en tant qu'utilisateur root et nous rendons l'impossibilité d'augmenter les privilèges (au moins systemd prétend à), même si le démon est compromis et définit uid=0.

iptables est malheureusement toujours un utilitaire assez laid et difficile à utiliser. Si le démon écoute sur eth0:0 au lieu de eth0, par exemple, les commandes sont légèrement différent .

12
Greg Slepak

systemd est un remplacement sysvinit doté d'une option permettant de lancer un démon doté de fonctionnalités spécifiques. Options Capabilities =, CapabilityBoundingSet = in systemd.exec (5) page de manuel.

10
zbyszek

Pour une raison quelconque, personne ne mentionne la possibilité d'abaisser sysctl net.ipv4.ip_unprivileged_port_start à la valeur dont vous avez besoin. Exemple: nous devons lier notre application au port 443.

sysctl net.ipv4.ip_unprivileged_port_start=443

Certains pourraient dire qu'il existe un problème de sécurité potentiel: les utilisateurs non privilégiés peuvent désormais se connecter aux autres ports privilégiés (444-1024). Mais vous pouvez résoudre ce problème facilement avec iptables, en bloquant d’autres ports:

iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP

Comparaison avec d'autres méthodes. Cette méthode:

  • à un moment donné, (IMO) est encore plus sûr que de définir CAP_NET_SERVICE/setuid, puisqu’une application n’a pas du tout setuid, même partiellement (les capacités le sont réellement). Par exemple, pour intercepter une application remplissant une fonctionnalité, vous devez modifier sysctl fs.suid_dumpable (ce qui entraîne d'autres problèmes de sécurité potentiels). De plus, lorsque CAP/suid est défini, le répertoire/proc/PID appartient à root. votre utilisateur non root n'aura pas toutes les informations/le contrôle du processus en cours; par exemple, il ne sera pas en mesure (dans le cas habituel) de déterminer quelles connexions appartiennent à l'application via/proc/PID/fd/(netstat -aptn | grep PID).
  • a un désavantage en matière de sécurité: pendant que votre application (ou toute application utilisant les ports 443-1024) est en panne pour une raison quelconque, une autre application peut prendre le port. Mais ce problème pourrait également être appliqué à CAP/suid (si vous le définissez sur un interpréteur, par exemple Java/nodejs) et iptables-redirect. Utilisez la méthode systemd-socket pour exclure ce problème. Utilisez la méthode authbind pour n'autoriser que les liaisons utilisateur spéciales.
  • ne nécessite pas de définir CAP/suid à chaque fois que vous déployez une nouvelle version de l'application.
  • ne nécessite pas de support/modification d'application, comme la méthode systemd-socket.
  • ne nécessite pas de reconstruction du noyau (si la version en cours supporte ce paramètre sysctl)
  • ne fait pas LD_PRELOAD comme la méthode authbind/privbind, cela pourrait potentiellement affecter les performances, la sécurité, le comportement (ça n'a pas été testé). Dans le reste, authbind est une méthode vraiment flexible et sécurisée.
  • sur-exécute la méthode REDIRECT/DNAT iptables, car elle ne nécessite pas de traduction d’adresse, de suivi de l’état de la connexion, etc. Ceci n’est visible que sur les systèmes à forte charge.

En fonction de la situation, je choisirais entre sysctl, CAP, authbind et iptables-redirect. Et c’est formidable que nous ayons tant d’options.

10
urusha

La redirection de port nous paraissait la plus logique, mais nous avons rencontré un problème dans lequel notre application résoudrait localement une URL qui devait également être redirigée. (cela signifie que vous shindig ).

Cela vous permettra également d'être redirigé lors de l'accès à l'URL sur la machine locale.

iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
9
00500005

Au démarrage:

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

Ensuite, vous pouvez vous connecter au port que vous transférez.

7
Arcabard

Avec systemd, il vous suffit de modifier légèrement votre service pour accepter les sockets préactivés.

Vous pouvez utiliser plus tard activation de la prise systemd .

Aucune capacité, iptables ou autres astuces sont nécessaires.

Ceci est le contenu des fichiers systemd pertinents de cet exemple de simple serveur python http

Fichier httpd-true.service

[Unit]
Description=Httpd true 

[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic

PrivateTmp=yes

Fichier httpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target
7
j123b567

Il y a aussi la "manière de djb". Vous pouvez utiliser cette méthode pour démarrer votre processus en tant qu'utilisateur root sur n'importe quel port sous tcpserver. Le contrôle du processus sera ensuite confié à l'utilisateur spécifié immédiatement après le démarrage du processus.

#!/bin/sh

UID=`id -u yourusername`
GID=`id -g yourusername`
exec tcpserver -u $UID -g $GID -RHl0 0 portnumber   /path/to/your/process &

Pour plus d'informations, voir: http://thedjbway.b0llix.net/daemontools/uidgid.html

2
mti2935

Utilisez l'utilitaire privbind : il permet à une application sans privilège de se lier à des ports réservés.

2
Alexander Davydov

J'ai essayé la méthode iptables PREROUTING REDIRECT. Dans les noyaux plus anciens, il semble que ce type de règle n'était pas supporté par IPv6 . Mais apparemment, il est maintenant supporté par ip6tables v1.4.18 et le noyau Linux v3.8.

J'ai également constaté que PREROUTING REDIRECT ne fonctionnait pas pour les connexions initiées dans la machine. Pour utiliser les connexions de la machine locale, ajoutez également une règle OUTPUT - voir la redirection du port iptables ne fonctionne pas pour localhost . Par exemple. quelque chose comme:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

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 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. J'ai trouvé que je ne pouvais que faire en sorte que les paquets adressés à la boîte soient affectés en ajoutant -m addrtype --dst-type LOCAL. Par exemple. quelque chose comme:

iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080

Une autre possibilité consiste à utiliser TCP transfert de port. 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).

1
Craig McQueen

Puisque le PO n’est qu’une phase de développement/test, il peut être utile de trouver des solutions moins sophistiquées:

setcap peut être utilisé sur un interpréteur de script pour attribuer des fonctionnalités à des scripts. Si setcaps sur le binaire d'interprète global n'est pas acceptable, créez une copie locale du fichier 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 fonctionnalité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 suit pour exécuter votre script:

#!/bin/sh
#
#  Watch for updates to the Python2 interpreter

PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7

cmp $PRG_ORIG $PRG || {
    echo ""
    echo "***** $PRG_ORIG has been updated *****"
    echo "Run the following commands to refresh $PRG:"
    echo ""
    echo "    $ cp $PRG_ORIG $PRG"
    echo "    # setcap cap_net_raw+ep $PRG"
    echo ""
    exit
}

./$PRG $*
1
duanev

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:

[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:80 redir ports 8080
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:443 redir ports 1443

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination
0
HVNSweeting

Linux moderne supporte /sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0.

0
Gene McCulley