¿Hay alguna manera para que los procesos no root se unan a & # 8220; privilegiado & # 8221; puertos en Linux?

StackOverflow https://stackoverflow.com/questions/413807

Pregunta

Es muy molesto tener esta limitación en mi cuadro de desarrollo, cuando nunca más habrá otros usuarios que yo.

Conozco las soluciones estándar , pero ninguna de ellas hace exactamente lo que Quiero:

  1. authbind (La versión en las pruebas de Debian, 1.0, solo es compatible con IPv4)
  2. Uso de iptables REDIRECT target para redirigir un puerto bajo a un puerto alto (la tabla " nat " aún no está implementada para ip6tables, la versión IPv6 de iptables)
  3. sudo (Ejecutar como root es lo que estoy tratando de evitar)
  4. SELinux (o similar). (Este es solo mi cuadro de desarrollo, no quiero introducir mucha complejidad adicional).

¿Existe alguna variable simple de sysctl para permitir que los procesos no root se unan a " privilegiado " puertos (puertos de menos de 1024) en Linux, o ¿acaso no tengo suerte?

EDITAR: en algunos casos, puede use las capacidades para hacer esto.

¿Fue útil?

Solución

Bien, gracias a las personas que señalaron el sistema de capacidades y la capacidad CAP_NET_BIND_SERVICE . Si tiene un kernel reciente, de hecho es posible usarlo para iniciar un servicio como no raíz pero enlazar puertos bajos. La respuesta corta es que usted hace:

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

Y luego, cada vez que se ejecute el programa , tendrá la capacidad CAP_NET_BIND_SERVICE . setcap está en el paquete debian libcap2-bin .

Ahora para las advertencias:

  1. Necesitará al menos un kernel 2.6.24
  2. Esto no funcionará si su archivo es un script. (es decir, utiliza una línea #! para iniciar un intérprete). En este caso, hasta donde yo entiendo, tendrías que aplicar la capacidad al ejecutable del intérprete, lo que por supuesto es una pesadilla de seguridad, ya que cualquier programa que use ese intérprete tendrá la capacidad. No pude encontrar ninguna manera limpia y fácil de solucionar este problema.
  3. Linux deshabilitará LD_LIBRARY_PATH en cualquier programa que tenga privilegios elevados como setcap o suid . Entonces, si su programa usa su propio ... / lib / , es posible que tenga que buscar otra opción como el reenvío de puertos.

Recursos:

Nota: RHEL agregó esto por primera vez en v6 .

Otros consejos

La forma estándar es hacerlos "setuid" para que se inicien como root, y luego descarten ese privilegio de root tan pronto como se unan al puerto pero antes de que comiencen a aceptar conexiones a él. Puede ver buenos ejemplos de eso en el código fuente de Apache e INN. Me dicen que Lighttpd es otro buen ejemplo.

Otro ejemplo es Postfix, que usa múltiples demonios que se comunican a través de tuberías, y solo uno o dos de ellos (que hacen muy poco, excepto aceptar o emitir bytes) se ejecutan como root y el resto se ejecuta con un privilegio menor.

Puede hacer una redirección de puerto. Esto es lo que hago para un servidor de políticas Silverlight que se ejecuta en un cuadro de Linux

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

Puede configurar un túnel SSH local, por ejemplo, si desea que el puerto 80 llegue a su aplicación vinculada a 3000:

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

Esto tiene la ventaja de trabajar con servidores de script y ser muy simple.

O parchear su kernel y eliminar el cheque.

(Opción de último recurso, no recomendado).

En net / ipv4 / af_inet.c , elimine las dos líneas que leen

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

y el núcleo ya no comprobará los puertos privilegiados.

Las capacidades de archivo no son ideales, porque pueden romperse después de una actualización del paquete.

La solución ideal, en mi humilde opinión, debería ser la capacidad de crear un shell con el conjunto CAP_NET_BIND_SERVICE heredable.

Aquí hay una forma algo complicada de hacer esto:

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

capsh se puede encontrar en el paquete libcap2-bin en las distribuciones Debian / Ubuntu. Esto es lo que sucede:

  • sg cambia la identificación efectiva del grupo a la del usuario daemon. Esto es necesario porque capsh deja el GID sin cambios y definitivamente no lo queremos.
  • Establece el bit 'mantener capacidades en cambio de UID'.
  • Cambia el UID a $DAEMONUSER
  • Descarta todas las mayúsculas (en este momento todas las mayúsculas siguen presentes debido a --keep = 1 ), excepto cap_net_bind_service
  • heredable
  • Ejecuta su comando ('-' es un separador)

El resultado es un proceso con usuario y grupo especificados, y privilegios cap_net_bind_service .

Como ejemplo, una línea del script de inicio ejabberd :

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

Otras dos posibilidades simples:

Hay una solución antigua (pasada de moda) para el "demonio" que se une a un puerto bajo y controla las manos a su demonio ". Se llama inetd (o xinetd). Los contras son:

  • tu demonio necesita hablar sobre stdin / stdout (si no controlas el demonio, si no tienes la fuente, entonces esto es quizás un showtopper, aunque algunos servicios pueden tener un indicador de compatibilidad inetd )
  • se bifurca un nuevo proceso de demonio para cada conexión
  • es un eslabón adicional en la cadena

Pros:

  • disponible en cualquier UNIX antiguo
  • una vez que su administrador del sistema haya configurado la configuración, puede continuar con su desarrollo (cuando reconstruye su demonio, ¿podría perder las capacidades de setcap? Y luego tendrá que volver a su administrador " por favor señor ... ")
  • daemon no tiene que preocuparse por esas cosas de redes, solo tiene que hablar sobre stdin / stdout
  • puede configurar para ejecutar su demonio como usuario no root, según lo solicitado

Otra alternativa: un proxy pirateado (netcat o incluso algo más robusto ) desde el puerto privilegiado a algún puerto arbitrario de alto número donde puede ejecutar su demonio de destino. (Netcat obviamente no es una solución de producción, sino `` solo mi caja de desarrollo '', ¿verdad?). De esta manera, podría continuar utilizando una versión de su servidor con capacidad de red, solo necesitaría root / sudo para iniciar el proxy (en el arranque), no dependería de capacidades complejas / potencialmente frágiles.

Mi " solución estándar " usa socat como redirector de espacio de usuario:

socat tcp6-listen:80,fork tcp6:8080

Tenga en cuenta que esto no escalará, la bifurcación es costosa pero es la forma en que funciona socat.

Actualización 2017:

Use authbind


Mucho mejor que CAP_NET_BIND_SERVICE o un kernel personalizado.

  • CAP_NET_BIND_SERVICE otorga confianza al binario pero no proporciona control sobre el acceso por puerto.
  • Authbind otorga confianza al usuario / grupo y proporciona control sobre el acceso por puerto, y admite tanto IPv4 como IPv6 (últimamente se ha agregado compatibilidad con IPv6).

    1. Instalar: apt-get install authbind

    2. Configure el acceso a los puertos relevantes, p. 80 y 443 para todos los usuarios y grupos:

        

      sudo touch / 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. Ejecute su comando a través de authbind
      (opcionalmente especificando --deep u otros argumentos, vea la página del manual):

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

      p.

      authbind --deep java -jar SomeServer.jar
      

Como seguimiento a la recomendación fabulosa de Joshua (= no recomendado a menos que sepas lo que haces) para hackear el kernel:

Lo publiqué por primera vez aquí .

Simple. Con un núcleo normal o antiguo, no lo hace.
Como señalaron otros, iptables puede reenviar un puerto.
Como también señalaron otros, CAP_NET_BIND_SERVICE también puede hacer el trabajo.
Por supuesto, CAP_NET_BIND_SERVICE fallará si inicia su programa desde un script, a menos que establezca el límite en el intérprete de shell, lo cual no tiene sentido, podría ejecutar su servicio como root ...
p.ej. para Java, debe aplicarlo a JAVA JVM

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

Obviamente, eso significa que cualquier programa Java puede enlazar puertos del sistema.
Dito para mono / .NET.

También estoy bastante seguro de que xinetd no es la mejor de las ideas.
Pero dado que ambos métodos son hacks, ¿por qué no simplemente levantar el límite levantando la restricción?
Nadie dijo que tenía que ejecutar un núcleo normal, por lo que puede ejecutar el suyo.

Simplemente descargue la fuente del último kernel (o el mismo que tiene actualmente). Luego, vas a:

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

Allí buscas esta línea

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

y cámbielo a

#define PROT_SOCK 0

si no desea tener una situación ssh insegura, modifíquela así:     #define PROT_SOCK 24

Generalmente, usaría la configuración más baja que necesita, por ejemplo, 79 para http, o 24 cuando use SMTP en el puerto 25.

Eso ya es todo.
Compile el núcleo e instálelo.
Reiniciar.
Terminado: ese límite estúpido se ha ido, y eso también funciona para los scripts.

Así es como compila un núcleo:

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 pocas palabras, use iptables si desea mantenerse seguro, compile el núcleo si desea asegurarse de que esta restricción nunca lo moleste nuevamente.

Linux admite capacidades para admitir permisos más específicos que solo " esta aplicación es ejecutar como root " ;. Una de esas capacidades es CAP_NET_BIND_SERVICE , que trata sobre el enlace a un puerto privilegiado (< 1024).

Desafortunadamente, no sé cómo explotar eso para ejecutar una aplicación como no root mientras sigo dándole CAP_NET_BIND_SERVICE (probablemente usando setcap , pero seguramente habrá una solución existente para esto).

Sé que esta es una pregunta antigua, pero ahora con los núcleos recientes (> = 4.3) finalmente hay una buena respuesta para esto: capacidades ambientales.

La respuesta rápida es tomar una copia de la última versión (aún no publicada) de libcap de git y compílelo. Copie el binario resultante progs / capsh en alguna parte ( / usr / local / bin es una buena opción). Luego, como root, inicie su programa con

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

En orden, estamos

  • Declarando que cuando cambiamos de usuario, queremos mantener nuestros conjuntos de capacidades actuales
  • Cambio de usuario & amp; grupo a 'su-nombre-usuario-servicio'
  • Agregar la capacidad cap_net_bind_service al & amp; heredado conjuntos ambientales
  • Bifurcando bash -c 'your-command' (ya que capsh inicia automáticamente bash con los argumentos después de - )

Aquí pasan muchas cosas debajo del capó.

En primer lugar, nos estamos ejecutando como root, por lo que, de forma predeterminada, tenemos un conjunto completo de capacidades. Incluido en esto está la capacidad de cambiar uid & amp; gid con las llamadas al sistema setuid y setgid . Sin embargo, normalmente cuando un programa hace esto, pierde su conjunto de capacidades, esto es para que la antigua forma de soltar root con setuid todavía funcione. La bandera --keep = 1 le dice a capsh que emita el prctl (PR_SET_KEEPCAPS) syscall, que desactiva la caída de capacidades al cambiar de usuario. El cambio real de usuarios por capsh ocurre con la bandera --user , que ejecuta setuid y setgid .

El siguiente problema que debemos resolver es cómo establecer capacidades de una manera que continúe después de que exec nuestros hijos. El sistema de capacidades siempre ha tenido un conjunto de capacidades 'heredado', que es " un conjunto de capacidades preservadas en un execve (2) " [ capacidades (7) ]. Si bien esto parece que resuelve nuestro problema (simplemente configure la capacidad cap_net_bind_service como heredada, ¿verdad?), Esto en realidad solo se aplica a procesos privilegiados, y nuestro proceso ya no es privilegiado, porque ya cambiamos de usuario ( con la bandera --user ).

El nuevo conjunto de capacidades ambientales soluciona este problema: es un conjunto de capacidades que se conservan en un execve (2) de un programa que no tiene privilegios. Al poner cap_net_bind_service en el entorno, cuando capsh exec es nuestro programa de servidor, nuestro programa heredará esta capacidad y podrá vincular oyentes a puertos bajos.

Si está interesado en obtener más información, las capacidades página del manual explica esto con gran detalle. ¡Ejecutar capsh a través de strace también es muy informativo!

TLDR: para " la respuesta " (tal como lo veo), salte al > > TLDR < < parte de esta respuesta.

Bien, lo he descubierto (de verdad esta vez), la respuesta a esta pregunta, y esta respuesta mía también es una forma de disculparme por promover otra respuesta (tanto aquí como en Twitter) que pensé que era" la mejor ", pero después de intentarlo, descubrí que estaba equivocado al respecto. Aprenda de mi error, niños: ¡no promocionen algo hasta que lo hayan probado usted mismo!

Nuevamente, revisé todas las respuestas aquí. He probado algunos (y elegí no probar otros porque simplemente no me gustaron las soluciones). Pensé que la solución era usar systemd con sus configuraciones Capabilities = y CapabilitiesBindingSet = . Después de luchar con esto por un tiempo, descubrí que esta no es la solución porque:

¡Las capacidades están destinadas a restringir los procesos raíz!

Como el OP dijo sabiamente, es siempre mejor evitar eso (¡para todos sus demonios si es posible!).

No puede usar las opciones relacionadas con Capacidades con User = y Group = en los archivos de unidad systemd , porque las capacidades son SIEMPRE restablecer cuando se llama a execev (o cualquiera que sea la función). En otras palabras, cuando systemd se bifurca y deja caer sus permisos, las capacidades se restablecen. No hay forma de evitar esto, y toda esa lógica de enlace en el núcleo es básica en torno a uid = 0, no a las capacidades. Esto significa que es poco probable que Capacidades sea la respuesta correcta a esta pregunta (al menos en el corto plazo). Por cierto, setcap , como han mencionado otros, no es una solución. No funcionó para mí, no funciona bien con los scripts, y estos se restablecen de todos modos cada vez que cambia el archivo.

En mi pobre defensa, dije (en el comentario que he eliminado), que James ' iptables sugerencia (que el OP también menciona), fue la "segunda mejor solución". :-P

>>TLDR<<

La solución es combinar systemd con comandos iptables sobre la marcha, como este ( tomado 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

Aquí logramos lo siguiente:

  • El demonio escucha en 5333, pero las conexiones se aceptan con éxito en 53 gracias a iptables
  • Podemos incluir los comandos en el archivo de la unidad, y así ahorramos dolores de cabeza a las personas. systemd limpia las reglas del firewall para nosotros, asegurándose de eliminarlas cuando el demonio no se está ejecutando.
  • Nunca corremos como root, y hacemos imposible la escalada de privilegios (al menos systemd lo reclama), supuestamente incluso si el demonio está comprometido y establece uid = 0 .

iptables sigue siendo, desafortunadamente, una utilidad bastante fea y difícil de usar. Si el demonio está escuchando en eth0: 0 en lugar de eth0 , por ejemplo, los comandos son ligeramente diferente .

systemd es un reemplazo de sysvinit que tiene la opción de lanzar un demonio con capacidades específicas . Opciones Capacidades =, CapabilityBoundingSet = en systemd.exec (5) página de manual.

La redirección de puertos tenía más sentido para nosotros, pero nos encontramos con un problema en el que nuestra aplicación resolvería una URL localmente que también necesitaba ser redirigida; (eso significa que usted shindig ).

Esto también le permitirá ser redirigido al acceder a la URL en la máquina local.

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

Por alguna razón, nadie menciona la reducción de sysctl net.ipv4.ip_unprivileged_port_start al valor que necesita. Ejemplo: necesitamos vincular nuestra aplicación al puerto 443.

sysctl net.ipv4.ip_unprivileged_port_start=443

Algunos pueden decir que existe un posible problema de seguridad: los usuarios no privilegiados ahora pueden unirse a los otros puertos privilegiados (444-1024). Pero puede resolver este problema fácilmente con iptables, bloqueando otros puertos:

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

Comparación con otros métodos. Este método:

  • desde algún punto es (IMO) aún más seguro que configurar CAP_NET_BIND_SERVICE / setuid, ya que una aplicación no se establece en absoluto, incluso en parte (las capacidades en realidad lo son). Por ejemplo, para capturar un núcleo de aplicaciones habilitadas para capacidades, deberá cambiar sysctl fs.suid_dumpable (lo que conduce a otros posibles problemas de seguridad) Además, cuando se establece CAP / suid, el directorio / proc / PID es propiedad de root, por lo que su usuario no root no tendrá información / control completo del proceso en ejecución, por ejemplo, el usuario no podrá (en el caso común) determine qué conexiones pertenecen a la aplicación a través de / proc / PID / fd / (netstat -aptn | grep PID).
  • tiene una desventaja de seguridad: mientras su aplicación (o cualquier aplicación que use los puertos 443-1024) está inactiva por alguna razón, otra aplicación podría tomar el puerto. Pero este problema también podría aplicarse a CAP / suid (en caso de que lo configure en el intérprete, por ejemplo, java / nodejs) y iptables-redirect. Utilice el método systemd-socket para excluir este problema. Utilice el método authbind para permitir solo enlaces especiales para usuarios.
  • no requiere configurar CAP / suid cada vez que implementa una nueva versión de la aplicación.
  • no requiere soporte / modificación de aplicaciones, como el método systemd-socket.
  • no requiere la reconstrucción del núcleo (si la versión en ejecución admite esta configuración de sysctl)
  • no hace LD_PRELOAD como el método authbind / privbind, esto podría afectar el rendimiento, la seguridad y el comportamiento (¿no es cierto?) En el resto, authbind es un método realmente flexible y seguro.
  • sobrepasa el método REDIRECT / DNAT de iptables, ya que no requiere traducción de direcciones, seguimiento del estado de conexión, etc. Esto solo se nota en sistemas de alta carga.

Dependiendo de la situación, elegiría entre sysctl, CAP, authbind e iptables-redirect. Y es genial que tengamos tantas opciones.

Al inicio:

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

Luego puede enlazar con el puerto al que reenvía.

Con systemd, solo necesita modificar ligeramente su servicio para aceptar sockets preactivados.

Posteriormente puede usar systemd socket active .

No se necesitan capacidades, iptables u otros trucos.

Este es el contenido de los archivos relevantes de systemd de este ejemplo de servidor http python

Archivo httpd-true.service

[Unit]
Description=Httpd true 

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

PrivateTmp=yes

Archivo httpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target

También existe la 'forma djb'. Puede usar este método para iniciar su proceso como root que se ejecuta en cualquier puerto bajo tcpserver, luego le dará el control del proceso al usuario que especifique inmediatamente después de que comience el proceso.

#!/bin/sh

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

Para obtener más información, consulte: http://thedjbway.b0llix.net/daemontools/uidgid. html

Utilice la utilidad privbind : permite que una aplicación sin privilegios se una a puertos reservados.

Dado que el OP es solo desarrollo / prueba, las soluciones menos que elegantes pueden ser útiles:

setcap se puede usar en el intérprete de un script para otorgar capacidades a los scripts. Si setcaps en el binario del intérprete global no es aceptable, haga una copia local del binario (cualquier usuario puede hacerlo) y obtenga root para setcap en esta copia. Python2 (al menos) funciona correctamente con una copia local del intérprete en su árbol de desarrollo de scripts. No se necesita suid para que el usuario root pueda controlar a qué capacidades tienen acceso los usuarios.

Si necesita realizar un seguimiento de las actualizaciones del intérprete en todo el sistema, utilice un script de shell como el siguiente para ejecutar su 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 $*

Probé el método de redirección de PREROUTING de iptables. En núcleos anteriores parece que este tipo de regla no era compatible con IPv6 . Pero aparentemente ahora es compatible con ip6tables v1.4.18 y Linux kernel v3.8.

También descubrí que PREROUTING REDIRECT no funciona para conexiones iniciadas dentro de la máquina. Para trabajar para conexiones desde la máquina local, agregue una regla de SALIDA también & # 8212; consulte la redirección de puerto de iptables no funciona para localhost . P.ej. algo como:

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

También descubrí que PREROUTING REDIRECT también afecta los paquetes reenviados . Es decir, si la máquina también reenvía paquetes entre interfaces (por ejemplo, si actúa como un punto de acceso Wi-Fi conectado a una red Ethernet), entonces la regla de iptables también detectará las conexiones de los clientes conectados a los destinos de Internet y los redirigirá a la máquina. Eso no es lo que quería & # 8212; solo quería redirigir las conexiones que se dirigían a la máquina misma. Descubrí que solo puedo afectar los paquetes dirigidos a la caja, agregando -m addrtype --dst-type LOCAL . P.ej. algo como:

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

Otra posibilidad es utilizar el reenvío de puertos TCP. P.ej. utilizando socat :

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

Sin embargo, una desventaja de ese método es que la aplicación que está escuchando en el puerto 8080 no conoce la dirección de origen de las conexiones entrantes (por ejemplo, para el registro u otros fines de identificación).

Respuesta en 2015 / septiembre:

ip6tables ahora admite IPV6 NAT: http: // www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt

Necesitará el kernel 3.7+

Prueba:

[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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top