La problemática es simple: Tenemos una maquina donde queremos correr un servicio en un puerto privilegiado (como 80 o 443), pero al intentar arrancar este servicio nos arroja un error de permisos.

Y es que si no arrancamos el servicio como root, no podremos usar ningún puerto bajo el 1024. Esto corresponde a una política de seguridad que protege los puertos well-known de ser utilizados por usuarios no privilegiados.

Por otro lado, ejecutar un proceso como root no es una buena practica de seguridad. Entonces, cual es la forma correcta de correr un servicio en un puerto privilegiado sin ser root? A continuación se explica en 3 pasos como utilizar authbind para poder asignar puertos privilegiados a usuarios no privilegiados.

authbind es una utilidad que permite a usuarios no privilegiados acceder a recursos de red que están disponibles para usuarios privilegiados.

1) Instalación

Lo primero es tener instalado authbind en el sistema. Si estás en Debian/Ubuntu:

apt-get install authbind

2) Asignar un puerto

Y para asignar un puerto, ejecutamos los siguientes 3 comandos:

touch /etc/authbind/byport/443
chown appuser /etc/authbind/byport/443
chmod 755 /etc/authbind/byport/443

El primer paso es crear un archivo vacío cuyo nombre debe ser el numero de puerto que queremos utilizar.

Luego, mediante chown y chmod asignamos permisos al usuario no privilegiado al archivo que recién creamos.

authbind luego traducirá esto como un privilegio para que appuser pueda utilizar el puerto 443.

3) Correr servicio utilizando authbind

El ultimo paso consiste en modificar la forma en que arrancamos nuestro proceso, ya sea que el comando esté en una integración continua, en un cron o un script cualquiera, debemos modificarlo para que se arranque bajo authbind.

Por ejemplo, tengo un servicio en Node que lo arranco via pm2 con el siguiente comando:

pm2 start main.js --name mynodeapp

La forma correcta de invocarlo ahora es:

authbind --deep pm2 start main.js --name mynodeapp

Esto significa que primero arrancamos authbind, y este arrancará nuestro servicio con la nueva regla.

El modificador --deep se utiliza para que en caso de que el runtime de Node o nuestro mismo proyecto llame a su vez otros nuevos procesos, estos también corran con la regla de authbind.

El esquema authbind --deep <comando> se aplica de igual forma si nuestro servicio estuviera hecho en Java:

authbind --deep java -jar Aplicacion.jar

Conclusión

authbind nos da una solución rápida y fácil de implementar a la problemática de asignar puertos privilegiados a usuarios normales. Pero también existen otras alternativas para lograrlo utilizando SELinux o setcap que pueden ser mas apropiadas dependiendo del contexto de seguridad que manejes en tus servidores.