De acuerdo, gracias a las personas que señalaron el sistema de capacidades y CAP_NET_BIND_SERVICE
capacidad. Si tiene un kernel reciente, es posible usarlo para iniciar un servicio como no root pero vincular 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á el CAP_NET_BIND_SERVICE
capacidad. setcap
está en el paquete debian libcap2-bin
.
Ahora las advertencias:
- Necesitará al menos un kernel 2.6.24
- Esto no funcionará si su archivo es un script. (es decir, usa una línea #! para iniciar un intérprete). En este caso, según tengo entendido, 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 manera limpia y fácil de solucionar este problema.
- Linux deshabilitará LD_LIBRARY_PATH en cualquier
program
que tiene privilegios elevados comosetcap
osuid
. Así que si tuprogram
usa su propio.../lib/
, es posible que deba buscar otra opción, como el reenvío de puertos.
Recursos:
- capabilities(7) página del manual. Lea esto largo y tendido si va a utilizar capacidades en un entorno de producción. Hay algunos detalles realmente complicados sobre cómo se heredan las capacidades a través de las llamadas exec() que se detallan aquí.
- página man de setcap
- "Enlazar puertos por debajo de 1024 sin root en GNU/Linux":el documento que primero me señaló hacia
setcap
.
Nota:RHEL agregó esto por primera vez en v6.
Puedes hacer una redirección de puerto. Esto es lo que hago para un servidor de políticas de Silverlight que se ejecuta en una caja de Linux
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
La forma estándar es hacerlos "setuid" para que se inicien como root, y luego descartan ese privilegio de root tan pronto como se vinculan al puerto, pero antes de que comiencen a aceptar conexiones. Puede ver buenos ejemplos de eso en el código fuente de Apache e INN. Me dijeron que Lighttpd es otro buen ejemplo.
Otro ejemplo es Postfix, que utiliza múltiples demonios que se comunican a través de conductos, 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.