linux root ipv6 iptables linux-capabilities

¿Hay alguna forma para que los procesos no root se unan a puertos "privilegiados" en Linux?



ipv6 iptables (22)

Al inicio:

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

A continuación, puede enlazar al puerto que reenvía.

Es muy molesto tener esta limitación en mi cuadro de desarrollo, cuando no habrá ningún otro usuario que no sea yo.

Soy consciente de las soluciones alternativas , pero ninguna de ellas hace exactamente lo que quiero:

  1. authbind (La versión en Debian testing, 1.0, solo es compatible con IPv4)
  2. Usar el objetivo REDIRECT de iptables 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 (correr como root es lo que trato de evitar)
  4. SELinux (o similar). (Esto es solo mi cuadro de desarrollo, no quiero introducir mucha complejidad adicional).

¿Hay alguna variable de sysctl simple para permitir que los procesos no root se unan a puertos "privilegiados" (puertos menores a 1024) en Linux, o simplemente no tengo suerte?

EDITAR: En algunos casos, puede utilizar capacidades para hacer esto.


Bien, gracias a las personas que señalaron el sistema de capacidades y la capacidad CAP_NET_BIND_SERVICE . Si tiene un kernel reciente, es posible usar esto para iniciar un servicio como no root pero enlazar puertos bajos. La respuesta corta es que lo haces:

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

Y luego, en cualquier momento, el program se ejecuta a partir de entonces, tendrá la capacidad CAP_NET_BIND_SERVICE . setcap está en el paquete debian libcap2-bin .

Ahora para las advertencias:

  1. Necesitarás 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, por lo que entiendo, tendría 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 forma limpia y fácil de solucionar este problema.
  3. Linux deshabilitará LD_LIBRARY_PATH en cualquier program que tenga privilegios elevados como setcap o suid . Entonces, si su program usa su propio .../lib/ , es posible que tenga que buscar otra opción como el reenvío de puertos.

Recursos:

Nota: RHEL primero agregó esto en v6 .


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

Más tarde puedes usar el socket de systemd .

No se necesitan capacidades, iptables u otros trucos.

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

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


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

setcap puede usarse 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) y obtenga la raíz para establecer set en esta copia. Python2 (al menos) funciona correctamente con una copia local del intérprete en su árbol de desarrollo de script. 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 de todo el sistema para el intérprete, use 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 $*


La forma estándar es convertirlos en "setuid" para que se inicien como root y luego desechen ese privilegio de root tan pronto como se hayan vinculado al puerto, pero antes de que empiecen a aceptar conexiones. 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 varios 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 más bajo.


La redirección de puertos fue lo más sensata para nosotros, pero nos encontramos con un problema en el que nuestra aplicación resolvía una url local que también necesitaba ser redirigida; ( shindig significa shindig ).

Esto también le permitirá ser redirigido cuando acceda 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


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

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

Aquí hay una manera un tanto complicada de hacer esto:

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

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

  • sg cambia la ID de grupo efectiva a la del usuario del daemon. Esto es necesario porque capsh deja GID sin cambios y definitivamente no lo queremos.
  • Establece el bit ''mantener capacidades en cambio de UID''.
  • Cambia UID a $DAEMONUSER
  • Quita todas las mayúsculas (en este momento todas las mayúsculas aún están presentes debido a --keep=1 ), excepto heredable cap_net_bind_service
  • Ejecuta tu 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"


Linux admite capabilities para admitir permisos más específicos que solo "esta aplicación se ejecuta como root". Una de esas capacidades es CAP_NET_BIND_SERVICE que trata sobre la vinculación a un puerto privilegiado (<1024).

Desafortunadamente, no sé cómo explotar eso para ejecutar una aplicación como no root mientras aún le CAP_NET_BIND_SERVICE (probablemente usando setcap , pero es probable que haya una solución existente para esto).


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

socat tcp6-listen:80,fork tcp6:8080

Tenga en cuenta que esto no va a escalar, el forking es caro pero es la forma en que funciona socat.


O parchea tu kernel y quita el cheque.

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


Otras dos posibilidades simples:

Existe una solución antigua (no de moda) para el "daemon que se une a un puerto bajo y el control de manos a su daemon". Se llama inetd (o xinetd). Los contras son:

  • su daemon necesita hablar sobre stdin / stdout (si no controla el daemon, si no tiene la fuente, entonces esto es quizás un showstopper, aunque algunos servicios pueden tener una marca de compatibilidad inetd)
  • Un nuevo proceso de daemon se bifurca para cada conexión
  • Es un eslabón adicional en la cadena.

Pros:

  • disponible en cualquier antiguo UNIX
  • Una vez que su administrador de sistemas haya configurado la configuración, podrá continuar con su desarrollo (cuando vuelva a compilar 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 en stdin / stdout
  • Puede configurarse para ejecutar su daemon como un usuario no root, según lo solicitado

Otra alternativa: un proxy pirateado (netcat o incluso algo más robusto ) desde el puerto privilegiado a un puerto arbitrario de alto número donde puede ejecutar su demonio de destino. (Obviamente, Netcat no es una solución de producción, sino "solo mi caja de desarrollo", ¿no?). De esta manera, podría seguir 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.


Por alguna razón, nadie menciona cómo reducir 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 problema de seguridad potencial: los usuarios sin privilegios 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) incluso más seguro que la configuración de CAP_NET_BIND_SERVICE / setuid, ya que una aplicación no se configura en absoluto, incluso parcialmente (las capacidades en realidad lo son). Por ejemplo, para capturar un conjunto de aplicaciones habilitadas para la capacidad, tendrá que cambiar sysctl fs.suid_dumpable (lo que conduce a otros posibles problemas de seguridad) Además, cuando CAP / suid está configurado, el directorio / proc / PID es propiedad de la raíz, por lo que su usuario no root no tendrá información completa / control del proceso en ejecución, por ejemplo, el usuario no podrá (en el caso común) determinar qué conexiones pertenecen a la aplicación a través de / proc / PID / fd / (netstat -aptn | grep PID).
  • tiene una desventaja de seguridad: mientras que 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 un 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 el enlace especial del usuario.
  • no requiere configurar CAP / suid cada vez que implemente una nueva versión de la aplicación.
  • no requiere soporte / modificación de la aplicación, como el método systemd-socket.
  • no requiere la reconstrucción del kernel (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 potencialmente afectar el rendimiento, la seguridad, el comportamiento (¿no? no lo he probado). 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 la conexión, etc. Esto solo se nota en sistemas de alta carga.

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


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

También encontré que PREROUTING REDIRECT no funciona para las conexiones iniciadas dentro de la máquina. Para trabajar con conexiones desde la máquina local, agregue también una regla de SALIDA - vea que la redirección de puertos de iptables no funciona para localhost . Por ejemplo, algo como:

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

También encontré 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 redireccionará la máquina. Eso no es lo que quería, solo quería redirigir las conexiones que estaban dirigidas a la máquina misma. Descubrí que puedo hacer que solo afecte a los paquetes dirigidos a la caja, agregando -m addrtype --dst-type LOCAL. Por ejemplo, algo como:

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

Otra posibilidad es usar el reenvío de puertos TCP. Por ejemplo, utilizando socat:

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

Sin embargo, una desventaja con 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).


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

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

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


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


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

La respuesta rápida es obtener una copia de la última versión (aún no publicada) de libcap de git y compilarla. Copie los progs/capsh binarios progs/capsh resultantes en algún lugar ( /usr/local/bin es una buena opción). Entonces, como root, comienza tu 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

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

Hay mucho que hacer bajo el capó aquí.

En primer lugar, nos estamos ejecutando como root, por lo que de forma predeterminada, obtenemos un conjunto completo de capacidades. Incluida en esto está la capacidad de cambiar uid & gid con las llamadas de configuración setuid y setgid . Sin embargo, normalmente cuando un programa hace esto, pierde su conjunto de capacidades; esto es así, la forma anterior de eliminar la raíz con setuid todavía funciona. El --keep=1 le dice a capsh que emita el prctl(PR_SET_KEEPCAPS) , 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 las 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 a través de un execve (2)" [ capabilities(7) ]. Si bien esto parece que resuelve nuestro problema (solo configura la capacidad cap_net_bind_service como heredada, ¿no?), En realidad esto solo se aplica a procesos privilegiados, y nuestro proceso ya no tiene privilegios, porque ya cambiamos de usuario (con la --user ) .

El nuevo conjunto de capacidades ambientales resuelve 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 conjunto de ambientes, cuando el programa de servidor de capsh exec sea nuestro programa, heredará esta capacidad y podrá vincular a los oyentes con puertos bajos.

Si está interesado en obtener más información, la capabilities(7) capacidades lo explica con gran detalle. ¡Correr capsh través de strace también es muy informativo!


También existe la ''forma djb''. Puede usar este método para iniciar su proceso como root en cualquier puerto bajo tcpserver, luego entregará 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


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


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


TLDR: Para "la respuesta" (como lo veo), salta a la parte >> TLDR << 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 (aquí y en Twitter) que pensé que era "la mejor". ", pero después de intentarlo, descubrí que estaba equivocado acerca de eso. Aprende de mi error, niños: ¡no promuevas algo hasta que tú mismo lo hayas probado!

Una vez más, he revisado todas las respuestas aquí. He probado algunos de ellos (y decidí 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 algún tiempo, descubrí que esta no es la solución porque:

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

Como bien lo indicó el OP, siempre es mejor evitar eso (¡para todos sus demonios si es posible!).

No puede usar las opciones relacionadas con Capacidades con User= y Group= en archivos de unidades del sistema, porque las capacidades SIEMPRE se reinician cuando se execev (o cualquiera que sea la función). En otras palabras, cuando systemd 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 kernel es básica alrededor de uid = 0, no de capacidades. Esto significa que es poco probable que las Capacidades sean la respuesta correcta a esta pregunta (al menos en cualquier momento). Por cierto, setcap , como han mencionado otros, no es una solución. No funcionó para mí, no funciona bien con scripts, y estos se restablecen de todos modos cada vez que el archivo cambia.

En mi escasa defensa, afirmé (en el comentario que ahora he eliminado) que la sugerencia de iptables James (que también menciona el OP) fue la "2ª mejor solución". :-PAG

>> TLDR <<

La solución es combinar systemd con los comandos de 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í realizamos 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 daemon no se está ejecutando.
  • Nunca ejecutamos como root, y hacemos imposible la escalada de privilegios (al menos las reclamaciones de systemd ), supuestamente incluso si el daemon 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 lugar de eth0 , por ejemplo, los comandos son ligeramente diferentes .


Actualización 2017:

Usar 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 (se ha agregado compatibilidad con IPv6 en los últimos tiempos).

    1. Instalar: apt-get install authbind

    2. Configure el acceso a los puertos relevantes, por ejemplo, 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

  1. 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.ej

    authbind --deep java -jar SomeServer.jar

Como seguimiento a la fabulosa recomendación de Joshua (= no recomendado a menos que sepa lo que hace) para piratear el kernel:

Primero lo publiqué here .

Sencillo. Con un núcleo normal o viejo, no lo haces.
Como han señalado otros, iptables puede reenviar un puerto.
Como también han señalado otros, CAP_NET_BIND_SERVICE también puede hacer el trabajo.
Por supuesto, CAP_NET_BIND_SERVICE fallará si ejecuta su programa desde un script, a menos que establezca el límite en el intérprete de shell, que no tiene sentido, podría ejecutar su servicio como root ...
Por ejemplo, para Java, debe aplicarlo a la JVM JAVA.

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 los puertos del sistema.
Dito para mono / .NET.

También estoy bastante seguro de que xinetd no es la mejor de las ideas.
Pero como ambos métodos son piruetas, ¿por qué no levantar el límite levantando la restricción?
Nadie dijo que tengas que ejecutar un núcleo normal, así que solo puedes ejecutar el tuyo.

Simplemente descargue la fuente para el último kernel (o el mismo que tiene actualmente). Después, vas a:

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

Ahí buscas esta linea

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

y cambiarlo a

#define PROT_SOCK 0

Si no quieres tener una situación ssh insegura, modifícala a esto: # define PROT_SOCK 24

En general, 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.
Compila el kernel, e instálalo.
Reiniciar.
Terminado: ese límite estúpido se ha ido, y eso también funciona para los scripts.

Así es como se compila un kernel:

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 quiere estar seguro, compile el kernel si quiere estar seguro de que esta restricción nunca más le moleste.


Respuesta a 2015 / septiembre:

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

Necesitará 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