Devo consentire a un utente (diverso dal root) di eseguire un server in ascolto sulla porta 80.
C'è un modo per fare questo?
Devo consentire a un utente (diverso dal root) di eseguire un server in ascolto sulla porta 80.
C'è un modo per fare questo?
Risposte:
setcap 'cap_net_bind_service=+ep' /path/to/program
questo funzionerà per processi specifici. Ma per consentire a un determinato utente di collegarsi alle porte inferiori a 1024 dovrai aggiungerlo ai sudoer.
Dai un'occhiata a questa discussione per saperne di più.
(Alcuni di questi metodi sono stati menzionati in altre risposte; sto dando diverse possibili scelte in ordine di preferenza approssimativo.)
È possibile reindirizzare la porta bassa a una porta alta e ascoltare sulla porta alta.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080
Puoi avviare il tuo server come root e rilasciare i privilegi dopo aver iniziato l'ascolto sulla porta privilegiata. Preferibilmente, piuttosto che codificarlo tu stesso, avvia il tuo server da un wrapper che fa il lavoro per te. Se il tuo server avvia un'istanza per connessione, avviarla da inetd
(o un programma simile come xinetd
). Per inetd
, utilizzare una linea come questa in /etc/inetd.conf
:
http stream tcp nowait username:groupname /path/to/server/executable argv[0] argv[1]…
Se il server è in ascolto in una singola istanza, avviarlo da un programma come authbind
. Creare un file vuoto /etc/authbind/byport/80
e renderlo eseguibile per l'utente che esegue il server; oppure creare /etc/authbind/byuid/1234
, dove 1234 è l'UID che esegue il server, contenente la linea 0.0.0.0/0:80,80
.
Se il file eseguibile del tuo server è archiviato su un filesystem che supporta le funzionalità, puoi dargli la possibilità . Attenzione che le funzionalità sono ancora relativamente nuove e presentano ancora qualche nodo .cap_net_bind_service
setcap cap_net_bind_service=ep /path/to/server/executable
-A INPUT -p tcp --dport 1080 -j ACCEPT
altrimenti non funzionerebbe (ho anche un -j DROP
catch-all.) Quindi sono rimasto con due socket di ascolto.
La risposta breve è che ciò non è possibile in base alla progettazione.
La lunga risposta è che nei mondi open source ci sono molte persone che giocano con il design e escogitano metodi alternativi. In generale, è ampiamente riconosciuto che ciò non dovrebbe essere possibile. Il fatto che stai provando probabilmente significa che hai un altro errore di progettazione nel tuo sistema e dovresti riconsiderare l'intera architettura del tuo sistema alla luce delle migliori pratiche e delle implicazioni di sicurezza di * nix.
Detto questo, un programma per autorizzare l'accesso non root a porte basse è authbind . Sia selinux che grsecurity forniscono anche framework per autenticazioni così ottimizzate.
Infine, se vuoi che determinati utenti eseguano programmi specifici come root e ciò di cui hai veramente bisogno è solo consentire a un utente di riavviare apache o qualcosa del genere, sudo
è tuo amico!
È possibile utilizzare il port forwarding netcat o xinetd o iptables oppure utilizzare apache come proxy front-end ed eseguire il processo su una porta non privilegiata.
Authbind , @Gilles lo ha già menzionato, ma vorrei ampliarlo un po '.
Ha un comodo controllo degli accessi (dettagli nella pagina man): puoi filtrare l'accesso per porta, indirizzo dell'interfaccia, uid, intervalli di indirizzo o porta e combinazione di questi.
Ha un parametro molto utile --depth
:
- livelli di profondità
Fa sì che authbind influisca sui programmi con livelli profondi nel grafico chiamante. L'impostazione predefinita è 1.
"Livelli profondi" significa che quando uno script (o programma), esegue un altro script, scende di livello. Quindi se ce l'hai --depth 5
significa dai livelli 1 (o è 0?) Attraverso 5 hai il permesso di legare, mentre al livello 6 e oltre, non lo fai. Utile quando si desidera che uno script abbia accesso, ma non i programmi che viene eseguito con o senza la propria conoscenza.
Per illustrare, potresti avere qualcosa del genere: per motivi di sicurezza, hai un utente java
che ha lo scopo di eseguire solo Java e vuoi dargli accesso alla porta 80:
echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80
Ho creato il ../byport/80 file
, dato al java
gruppo di utenti (ogni utente ha il proprio gruppo) e l'ho reso eseguibile per gruppo, il che significa che è eseguibile java
dall'utente. Se stai dando accesso per porta, il file deve essere eseguibile dall'utente che dovrebbe avere accesso, quindi l'abbiamo fatto.
Questo potrebbe essere sufficiente per il Joe medio, ma poiché sai come usare il --depth
parametro, corri (come java
utente) a authbind --depth [depth] my_web_app's_start_script
partire --depth 1
e lavorando fino a trovare la profondità più piccola che funziona e usarlo.
Ho provato il metodo iptables PREROUTING REDIRECT, ma ho scoperto che influenza anche i pacchetti inoltrati. Cioè, se la macchina inoltra anche pacchetti tra le interfacce (ad es. Se agisce come un punto di accesso Wi-Fi collegato a una rete Ethernet), la regola iptables rileverà anche le connessioni dei client collegati a destinazioni Internet e li reindirizzerà a la macchina. Non è quello che volevo, volevo solo reindirizzare le connessioni dirette alla macchina stessa.
Una possibilità è utilizzare il port forwarding TCP. Ad esempio usando socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
Tuttavia uno svantaggio di questo metodo è che l'applicazione in ascolto sulla porta 8080 non conosce l'indirizzo di origine delle connessioni in entrata (ad es. Per la registrazione o altri scopi di identificazione).