Mi piacerebbe avere un programma Python che inizi ad ascoltare sulla porta 80, ma successivamente eseguirlo senza i permessi di root. C'è un modo per eliminare root o ottenere la porta 80 senza di essa?Eliminazione dei permessi di root in Python
risposta
Non sarà possibile aprire un server sulla porta 80 senza privilegi di root, questa è una restrizione a livello di sistema operativo. Quindi l'unica soluzione è quella di eliminare i privilegi di root dopo aver aperto la porta.
Ecco una possibile soluzione per eliminare i privilegi di root in Python: Dropping privileges in Python. Questa è una buona soluzione in generale, ma dovrai anche aggiungere os.setgroups([])
alla funzione per assicurarti che l'appartenenza al gruppo dell'utente root non venga mantenuta.
Ho copiato e ripulito il codice un po 'e rimosso la registrazione e i gestori di eccezioni in modo che sia lasciato a voi per gestire correttamente OSError
(verrà generato quando il processo non è autorizzato a cambiare il suo UID effettivo o GID):
import os, pwd, grp
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
if os.getuid() != 0:
# We're not root so, like, whatever dude
return
# Get the uid/gid from the name
running_uid = pwd.getpwnam(uid_name).pw_uid
running_gid = grp.getgrnam(gid_name).gr_gid
# Remove group privileges
os.setgroups([])
# Try setting the new uid/gid
os.setgid(running_gid)
os.setuid(running_uid)
# Ensure a very conservative umask
old_umask = os.umask(077)
Ricorda che la directory HOME sarà ancora '/ root' e non '/ home/uid_name', e che uid_name non sarà in grado di fare nulla con' ~/', che verrà quindi espanso in'/root/'. Questo può influire su moduli come matplotlib che memorizzano i dati di configurazione nella directory HOME. 'authbind' sembra essere il modo corretto per gestire questo problema. –
E la variabile HOME non sarà l'unica a pensare che l'utente corrente sia root. –
* "Non sarà possibile aprire un server sulla porta 80 senza privilegi di root ..." * - Questo non è necessariamente vero (forse più?). Vedi anche [Permetti al processo non-root di collegarsi alla porta 80 e 443?] (Https://superuser.com/q/710253/173513) su SuperUser e [C'è un modo per i processi non-root di collegarsi a "privilegiati "Porte su Linux?] (Https://stackoverflow.com/q/413807/608639) – jww
mi consiglia di utilizzare authbind
per iniziare il vostro programma Python, quindi nessuno di esso deve essere eseguito come root.
Un esempio di come usare' authbind' - http://goo.gl/fxFde6 - Sostituisci NodeJS con quello che vuoi (ex : python) – starlocke
systemd può farlo per voi, se si avvia il programma attraverso systemd, systemd può mano fuori il socket di ascolto già aperto ad esso, e può anche attivare il programma sul primo collegamento . e non hai nemmeno bisogno di demonizzarlo.
Se si intende adottare l'approccio standalone, è necessario disporre della funzionalità CAP_NET_BIND_SERVICE (consultare la pagina man di funzionalità). Questo può essere fatto programma per programma con lo strumento della riga di comando corretto, o facendo in modo che l'applicazione (1) sia suid root (2) start up (3) ascolta i privilegi/le capacità di rilascio della porta (4) immediatamente .
Ricordate che con privilegi di root programmi sono dotati di un sacco di considerazioni di sicurezza (ambiente pulito e sicuro, umask, privilegi, rlimits, tutte quelle cose sono cose che il programma sta andando ad avere per impostare correttamente). Se puoi usare qualcosa come systemd, tanto meglio allora.
La maggior parte di questo funziona, a meno che non sia necessario richiedere la presa dopo aver fatto altre cose che non si desidera essere superutente.
Ho creato un progetto chiamato tradesocket qualche tempo fa. Permette di passare avanti e indietro i socket su un sistema POSIX tra i processi. Quello che faccio è far partire un processo all'inizio che rimane superutente, e il resto del processo cade giù nelle autorizzazioni e quindi richiede il socket dall'altro.
Non è una buona idea chiedere all'utente di inserire il proprio nome utente e il gruppo ogni volta che ho bisogno di rilasciare i privilegi. Ecco una versione leggermente modificata del codice di Tamás che lascerà cadere i privilegi e passerà all'utente che ha avviato il comando sudo. Suppongo che tu stia usando sudo (se no, usa il codice di Tamás).
#!/usr/bin/env python3
import os, pwd, grp
#Throws OSError exception (it will be thrown when the process is not allowed
#to switch its effective UID or GID):
def drop_privileges():
if os.getuid() != 0:
# We're not root so, like, whatever dude
return
# Get the uid/gid from the name
user_name = os.getenv("SUDO_USER")
pwnam = pwd.getpwnam(user_name)
# Remove group privileges
os.setgroups([])
# Try setting the new uid/gid
os.setgid(pwnam.pw_gid)
os.setuid(pwnam.pw_uid)
#Ensure a reasonable umask
old_umask = os.umask(0o22)
#Test by running...
#./drop_privileges
#sudo ./drop_privileges
if __name__ == '__main__':
print(os.getresuid())
drop_privileges()
print(os.getresuid())
Il seguente è un ulteriore adattamento di Tamás's answer, con le seguenti modifiche:
- Utilizzare il
python-prctl
module a goccia le capacità di Linux a un elenco specifico di funzionalità per preservare. - L'utente può facoltativamente essere passato come parametro (per impostazione predefinita, cerca l'utente che ha eseguito
sudo
). - Imposta tutti i gruppi dell'utente e
HOME
. - Opzionalmente cambia directory.
(io sono relativamente nuovo per utilizzare questa funzionalità, tuttavia, così io possa aver perso qualcosa. Potrebbe non funzionare su vecchi kernel (< 3.8) o kernel con capacità di filesystem disabilitati.)
def drop_privileges(user=None, rundir=None, caps=None):
import os
import pwd
if caps:
import prctl
if os.getuid() != 0:
# We're not root
raise PermissionError('Run with sudo or as root user')
if user is None:
user = os.getenv('SUDO_USER')
if user is None:
raise ValueError('Username not specified')
if rundir is None:
rundir = os.getcwd()
# Get the uid/gid from the name
pwnam = pwd.getpwnam(user)
if caps:
prctl.securebits.keep_caps=True
prctl.securebits.no_setuid_fixup=True
# Set user's group privileges
os.setgroups(os.getgrouplist(pwnam.pw_name, pwnam.pw_gid))
# Try setting the new uid/gid
os.setgid(pwnam.pw_gid)
os.setuid(pwnam.pw_uid)
os.environ['HOME'] = pwnam.pw_dir
os.chdir(os.path.expanduser(rundir))
if caps:
prctl.capbset.limit(*caps)
try:
prctl.cap_permitted.limit(*caps)
except PermissionError:
pass
prctl.cap_effective.limit(*caps)
#Ensure a reasonable umask
old_umask = os.umask(0o22)
può essere utilizzato come segue:
drop_privileges(user='www', rundir='~', caps=[prctl.CAP_NET_BIND_SERVICE])
- 1. Eliminazione dei privilegi di root
- 2. Eliminazione dei moduli Python?
- 3. Verifica dei permessi dei file in Linux con Python
- 4. EKEventStore prompt dei permessi
- 5. Ottenere i permessi di root su iOS per NSFileManager (Jailbreak)
- 6. Python - Verifica permessi directory
- 7. python shutil.copytree - ignora permessi
- 8. Eliminazione dei blocchi in linea?
- 9. Come garantire i permessi dei file corretti
- 10. : problemi di permessi non coerenti
- 11. Modifica dei permessi su/vagabondo
- 12. I permessi dei file non ereditano i permessi delle directory
- 13. permessi dei file Java per le discussioni
- 14. Eliminazione di variabili in librerie standard Python
- 15. imposta i permessi dei file nel file setup.py
- 16. Come acquisire pacchetti di rete in Android senza utilizzare i permessi di root
- 17. Gemfile.lock errore di scrittura, permessi?
- 18. Eliminazione dei privilegi in C++ su Windows
- 19. Eliminazione dei dati statici suDestroy()
- 20. Eliminazione dei vincoli non denominati
- 21. Sono permessi parziali permessi in VSCode?
- 22. Python eliminazione di alcune estensioni di file
- 23. Eliminazione dei file xcdatamodel della versione dei dati di base
- 24. Eliminazione di righe con Python in un file CSV
- 25. Python mkdir mi dà permessi errati
- 26. Eliminazione condizionale di duplicati python panda
- 27. Eliminazione di determinati file utilizzando python
- 28. Come posso cambiare i permessi dei file in Ubuntu
- 29. Modifica dei permessi del cluster di Google Container Engine
- 30. C'è un modo per un'app Java per ottenere i permessi di root?
http://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged -ports-1024-on-li –
Su Linux moderno è necessaria solo la funzionalità CAP_NET_ BIND_SERVICE per collegarsi alla porta 80, NON è necessario essere root, nemmeno all'avvio dell'applicazione. Capabilities è uno standard POSIX, 1003.1e, ovvero un partizionamento del potente privilegio di root in un insieme di privilegi distinti. See: python-cap-ng E/sbin/setcap,/sbin/getcap (questi sono equivalenti a chmod setuid, e ls -l) –
Per python2 e forse altri interpreti, guadagnando funzionalità è la parte che si vuoi stare attento con - libcap-ng può eliminare i cap ma non li concede. Questa risposta alla domanda Ian di riferimento è un modo relativamente sicuro di distribuire un limite alla volta per progetti specifici: http://stackoverflow.com/a/21895123/1724577 – duanev