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


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

Soy consciente de las soluciones estándar , pero ninguna de ellas hace exactamente lo que quiero:

  1. authbind (La versión de Debian testing, 1.0, solo soporta IPv4)
  2. Usando el destino iptables REDIRECT 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 estoy tratando de evitar)
  4. SELinux (o similar). (Esta es solo mi caja de desarrollo, no quiero introducir mucha complejidad adicional.)

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

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

Author: tomix86, 2009-01-05

22 answers

Bien, gracias a la gente que señaló el sistema de capacidades y la capacidad CAP_NET_BIND_SERVICE. Si tiene un núcleo reciente, es posible usarlo para iniciar un servicio como no root pero enlazar puertos bajos. La respuesta corta es que sí:

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

Y luego en cualquier momento 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á al menos un núcleo 2.6.24
  2. Esto no funciona si tu archivo es un script. (es decir, utiliza un #! línea para lanzar un intérprete). En este caso, por lo que entiendo, tendría que aplicar la capacidad al ejecutable intérprete en sí, lo que por supuesto es una pesadilla de seguridad, ya que cualquier programa que utilice 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 program que tenga privilegios elevados como setcap o suid. Así que si su program utiliza su propio .../lib/, es posible que tenga que buscar en otra opción como el reenvío de puertos.

Recursos:

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

 341
Author: Jason Creighton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-20 00:06:41

La forma estándar es hacerlos "setuid" para que se inicien como root, y luego desechan ese privilegio root tan pronto como se hayan enlazado al puerto, pero antes de comenzar a aceptar conexiones a él. Puedes ver buenos ejemplos de eso en el código fuente de Apache y INN. Me han dicho que Lighttpd es otro buen ejemplo.

Otro ejemplo es Postfix, que utiliza 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 ejecuta como root y el resto se ejecuta en un privilegio inferior.

 31
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-05 17:43:39

Puede hacer un redireccionamiento de puerto. Esto es lo que hago para un servidor de políticas de Silverlight que se ejecuta en una caja Linux

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
 28
Author: FlappySocks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-19 11:57:18

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.

 17
Author: Gabriel Burt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-03 16:06:13

Las capacidades de archivo no son ideales, porque 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 heredable.

Aquí hay una forma 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 la utilidad se puede encontrar en el paquete libcap2-bin en las distribuciones Debian / Ubuntu. Esto es lo que sucede:

  • sg cambia el ID de grupo efectivo al del usuario del demonio. Esto es necesario porque capsh deja GID sin cambios y definitivamente no lo queremos.
  • Establece el bit 'keep capabilities on UID change'.
  • Cambia UID a $DAEMONUSER
  • Elimina todas las mayúsculas (en este momento todas las mayúsculas siguen presentes debido a --keep=1), excepto {[8 heredable]}
  • Ejecuta tu orden ('--'es un separador)

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

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

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"
 16
Author: Cyberax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-09 06:19:33

Otras dos posibilidades simples:

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

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

Ventajas:

  • disponible en cualquier UNIX antiguo
  • una vez que su administrador de sistemas haya configurado la configuración, estará listo para continuar con su desarrollo (cuando vuelva a construir 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 un usuario no root, según lo solicitado

Otra alternativa: un proxy hackeado (netcat o incluso algo más robusto) desde el puerto privilegiado a algún puerto arbitrario con números altos 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 compatible con la red de su servidor, solo necesitaría root / sudo para iniciar el proxy( al arrancar), no dependería de complejos / potencialmente frágiles capacidad.

 15
Author: Martin Carpenter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-06 02:07:23

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.

 14
Author: Astro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-15 14:08:34

O parchee su núcleo y elimine la comprobación.

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

 12
Author: Joshua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-05 17:32:13

TLDR: Para "la respuesta" (como yo lo veo), salta a la parte >>TLDR

OK, 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 sobre eso. Aprender de mi error niños: no promover algo hasta que realmente ¡lo probaste tú mismo!

Nuevamente, revisé todas las respuestas aquí. He probado algunos de ellos (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 durante algún 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 tus demonios si es posible!).

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

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

>>TLDR

La solución es combinar systemd con comandos sobre la marcha iptables, 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: {[24]]}

  • El demonio escucha en 5333, pero las conexiones se aceptan con éxito en 53 gracias a iptables
  • Podemos incluir los comandos en el propio archivo de la unidad, y así ahorramos dolores de cabeza a las personas. systemd limpia las reglas del firewall para nosotros, asegurándose para eliminarlos cuando el demonio no se está ejecutando.
  • Nunca ejecutamos 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 diferentes.

 12
Author: Greg Slepak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:41

Linux soporta capacidades para soportar permisos más detallados que solo "esta aplicación se ejecuta como root". Una de esas capacidades es CAP_NET_BIND_SERVICE que se trata de enlazar a un puerto privilegiado (

Desafortunadamente, no se como explotar eso para ejecutar una aplicación como no-root mientras todavía se le da CAP_NET_BIND_SERVICE (probablemente usando setcap, pero es probable que haya una solución existente para esto).

 12
Author: Joachim Sauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-20 00:07:48

Sé que esta es una pregunta antigua, pero ahora con kernels recientes (>= 4.3) finalmente hay una buena respuesta a 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 compilarla. Copie el binario progs/capsh resultante en algún lugar (/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{[25]]}

  • Declarando que cuando cambiamos de usuario, queremos mantener conjuntos de capacidades actuales
  • Cambiar de usuario y grupo a'su-servicio-nombre-de-usuario'
  • Añadiendo la capacidad cap_net_bind_service a los conjuntos & ambientales heredados
  • Forking bash -c 'your-command' (since capsh automatically starts bash with the arguments after --)

Aquí hay muchas cosas debajo del capó.

En primer lugar, estamos corriendo como root, por lo que por defecto, obtenemos un conjunto completo de capacidades. Incluido en esto es la capacidad de cambiar uid & gid con el setuid y setgid syscalls. Sin embargo, normalmente cuando un programa hace esto, pierde su conjunto de capacidades - esto es para que la antigua forma de eliminar root con setuid todavía funcione. La bandera --keep=1 le dice a capsh que emita la llamada prctl(PR_SET_KEEPCAPS) syscall, que deshabilita la eliminación de capacidades al cambiar de usuario. El cambio real de usuarios por capsh sucede con la bandera --user, que se ejecuta setuid y setgid.

El siguiente problema que tenemos que resolver es cómo establecer capacidades de una manera que continúe después de que exec nuestro niño. El sistema de capacidades siempre ha tenido un conjunto 'heredado' de capacidades, que es " un conjunto de capacidades preservadas a través de un execve(2)" [capacidades(7)]. Mientras que esto suena como si resolviera nuestro problema (simplemente establezca la capacidad cap_net_bind_service en heredado, ¿verdad?), esto en realidad solo se aplica a los procesos privilegiados-y nuestro proceso ya no es privilegiado, porque ya hemos cambiado de usuario (con la bandera --user).

El nuevo conjunto de capacidades ambientales funciona alrededor de esto problema-es "un conjunto de capacidades que se conservan a través de un execve (2) de un programa que no tiene privilegios."Al poner cap_net_bind_service en el conjunto de ambiente, cuando capsh exec es nuestro programa de servidor, nuestro programa heredará esta capacidad y podrá vincular los oyentes a puertos bajos.

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

 12
Author: KJ Tsanaktsidis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 15:17:55

Actualizar 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 soporta tanto IPv4 como IPv6 (soporte IPv6 se ha añadido últimamente).

    1. Instalar: apt-get install authbind

    2. Configurar 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. Ejecuta tu orden a través de authbind
    (opcionalmente especificando --deep u otros argumentos, vea el man página):

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

    Por ejemplo

    authbind --deep java -jar SomeServer.jar
    

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

Primero lo he publicado aquí.

Simple. 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 usted lanza 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...
por ejemplo, para Java, debe aplicarlo a la JVM de 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 puertos del sistema.
Dito para mono/. NET.

También estoy bastante seguro de que xinetd no es la mejor de las ideas.
Pero ya que ambos métodos son hacks, ¿por qué no simplemente levantar el límite levantando la restricción ?
Nadie dijo que tienes que ejecutar un kernel normal, así que puedes ejecutar el tuyo propio.

Solo tiene que descargar el código fuente para el núcleo más reciente (o el mismo que tiene actualmente). Después, vas a:

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

Allí se busca esta línea

/* 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 insegura de ssh, la alteras a esta: # define PROT_SOCK 24

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

Eso ya es todo.
Compilar el núcleo e instalarlo.
Reiniciar.
Terminado - ese estúpido límite se ha ido, y eso también funciona para los scripts.

Así es como se 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 le moleste de nuevo.

 11
Author: Stefan Steiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 15:10:19

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

 10
Author: zbyszek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-03 12:55:13

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 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
 8
Author: 00500005,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-03 19:49:47

Al inicio:

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

Entonces puede enlazar al puerto al que reenvía.

 7
Author: Prospero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-05 19:30:59

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

Puede usar más adelante systemd socket activate.

No se necesitan capacidades, iptables u otros trucos.

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

File httpd-true.service

[Unit]
Description=Httpd true 

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

PrivateTmp=yes

File httpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target
 5
Author: j123b567,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-27 09:37:41

Por alguna razón nadie menciona acerca de bajar sysctl net.ipv4.ip_unprivileged_port_start al valor que necesita. Ejemplo: Necesitamos enlazar nuestra aplicación al puerto 443.

sysctl net.ipv4.ip_unprivileged_port_start=443

Algunos pueden decir que hay 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 configurar CAP_NET_BIND_SERVICE / setuid, ya que una aplicación no establece setuid en absoluto, ni siquiera en parte (las capacidades en realidad lo son). Por ejemplo, para capturar un núcleo de una aplicación habilitada para capacidades, necesitará cambiar sysctl fs.suid_dumpable (lo que conduce a otros problemas de seguridad potenciales) 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 completa / control del proceso en ejecución, por ejemplo, el usuario no podrá (en caso común) para 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 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 interpreter, por ejemplo, java / nodejs) e iptables-redirect. Utilice el método systemd-socket para excluir este problema. Utilice el método authbind para permitir solo usuarios especiales vinculante.
  • no requiere configurar CAP/suid cada vez que implemente una nueva versión de la aplicación.
  • no requiere soporte/modificación de aplicaciones, como el método systemd-socket.
  • no requiere reconstrucción del kernel (si la versión en ejecución soporta esta configuración sysctl)
  • no hace LD_PRELOAD como el método authbind / privbind, esto podría afectar potencialmente el rendimiento, la seguridad, el comportamiento (¿lo hace? no han probado). En el resto authbind es realmente flexible y seguro método.
  • realiza el método iptables REDIRECT/DNAT, ya que no requiere traducción de direcciones, seguimiento de 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.

 3
Author: urusha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 09:45:11

También está la 'manera djb'. Puede usar este método para iniciar su proceso como root ejecutándose 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 más información, ver: http://thedjbway.b0llix.net/daemontools/uidgid.html

 2
Author: mti2935,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-03 17:25:29

Dado que el OP es solo desarrollo/pruebas, las soluciones menos 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 intérprete global no es aceptable, haga una copia local del binario (cualquier usuario puede) y obtenga root a setcap en esta copia. Python2 (al menos) funciona correctamente con una copia local del intérprete en el árbol de desarrollo del script. No se necesita suid para que el usuario root pueda controlar lo que capacidades a las que 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 $*
 1
Author: duanev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-12 20:27:01

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

 1
Author: Alexander Davydov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-19 19:08:15

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

También encontré que la REDIRECCIÓN de PREROUTING no funciona para las conexiones iniciadas dentro de la máquina. Para trabajar con conexiones desde la máquina local, agregue una regla de SALIDA también-vea iptables port redirect not working for 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 la REDIRECCIÓN PREROUTING también afecta a los paquetes reenviados. Es decir, si la máquina también está reenviando paquetes entre interfaces (por ejemplo, si está actuando como un punto de acceso Wi-Fi conectado a una red Ethernet), entonces la regla iptables también capturará las conexiones de los clientes conectados a destinos de Internet y los redirigirá a la máquina. Eso no es lo que quería, solo quería redirigir las conexiones que se dirigían a la máquina en sí. He encontrado 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 utilizar el reenvío de puertos TCP. Por ejemplo, usando 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).

 1
Author: Craig McQueen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 22:58:25

Respuesta en 2015 / Sep:

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
 0
Author: HVNSweeting,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-04 09:10:26