Solución 1:
Por supuesto que esto es posible. Solo necesita dar el binario CAP_NET_BIND_SERVICE.
sudo setcap cap_net_bind_service=ep some-binary
En Linux, las cosas que la raíz puede hacer se han dividido en un conjunto de capacidades. CAP_NET_BIND_SERVICE es la capacidad de enlazar a puertos <=1024.
Probablemente incluso sea posible usar AppArmor, SELinux u otro módulo de seguridad de Linux (LSM) para otorgar acceso al programa para vincular ese puerto específicamente, pero creo que sería una pérdida de tiempo. La seguridad no se basa realmente en los números de puerto en la medida en que lo hacía en el pasado lejano.
Aquí hay una secuencia de comandos para que OSX reenvíe los puertos 80 y 443 a puertos sin privilegios:
echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -ef -
Solución 2:
Otra forma de hacer que su daemon responda a las solicitudes de un número de puerto más bajo es usar iptables o similar para redirigir un puerto con un número más bajo al puerto con un número más alto en el que está escuchando su daemon:
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
Sustituya 80 con el puerto para exponer y 8080 con el puerto de escucha de su aplicación.
Solución 3:
Creo que hay una forma de hacerlo, pero no estoy 100 % seguro de que funcione.
es el enlace del puerto lo que requiere root, no la aplicación que lo usa, por lo que el siguiente método puede funcionar, pero primero debe tener acceso a Sudo.
Primero inicia su proceso como usuario root usando sudo myApp
, una vez que se haya vinculado el puerto, puede cambiar el propietario del proceso a un usuario sin privilegios.
Solución 4:
Recuerdo vagamente una biblioteca llamada "authbind" que hace lo que necesita, envolviendo la llamada al sistema bind() (a través de una biblioteca LD_PRELOAD) y, si se solicita un puerto privilegiado, generando un programa raíz setuid que recibe una copia del descriptor de archivo, luego verifica que la aplicación tenga permiso para enlazar con el puerto, realiza el enlace () y sale.
No estoy seguro del estado del proyecto, pero el método debería ser bastante sencillo de (re)implementar si es necesario.