Soluzione 1:
Naturalmente questo è possibile. Devi solo fornire il binario CAP_NET_BIND_SERVICE.
sudo setcap cap_net_bind_service=ep some-binary
In Linux, le cose che root può fare sono state suddivise in un insieme di funzionalità. CAP_NET_BIND_SERVICE è la capacità di collegarsi alle porte <=1024.
Probabilmente è persino possibile utilizzare AppArmor, SELinux o un altro modulo di sicurezza Linux (LSM) per concedere al programma l'accesso per associare specificamente quella porta, ma penso che sarebbe una perdita di tempo. La sicurezza non si basa realmente sui numeri di porta nella misura in cui lo era in un lontano passato.
Ecco uno script per OSX per inoltrare le porte 80 e 443 a porte non privilegiate:
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 -
Soluzione 2:
Un altro modo per far sì che il tuo demone risponda alle richieste da un numero di porta inferiore è utilizzare iptables o simili per reindirizzare una porta con un numero inferiore alla porta con un numero più alto su cui il tuo demone è in ascolto:
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
Sostituisci 80 con la porta da esporre e 8080 con la porta del listener dell'applicazione.
Soluzione 3:
Penso che ci sia un modo per farlo, ma non sono sicuro al 100% se funzionerebbe.
è l'associazione della porta che richiede root, non l'applicazione che la sta utilizzando, quindi il metodo seguente potrebbe funzionare ma è necessario disporre dell'accesso sudo in primo luogo.
Per prima cosa avvia il tuo processo come utente root usando sudo myApp
, una volta che la porta è stata associata puoi cambiare il proprietario del processo in un utente non privilegiato.
Soluzione 4:
Ricordo vagamente una libreria chiamata "authbind" che fa ciò di cui hai bisogno, avvolgendo la chiamata di sistema bind() (tramite una libreria LD_PRELOAD) e, se è richiesta una porta privilegiata, generando un programma root setuid che riceve una copia del descrittore di file, quindi verifica che l'applicazione sia effettivamente autorizzata a collegarsi alla porta, esegue bind() ed esce.
Non sono sicuro dello stato del progetto, ma il metodo dovrebbe essere abbastanza semplice da (re)implementare se necessario.