Chciałbym, aby program w języku Python zaczął nasłuchiwać na porcie 80, ale po tym uruchomieniu bez uprawnień root. Czy istnieje sposób, aby opuścić root lub uzyskać port 80 bez niego?Upuszczanie uprawnień roota w Pythonie
Odpowiedz
Nie będzie można otworzyć serwera na porcie 80 bez uprawnień roota, jest to ograniczenie na poziomie systemu operacyjnego. Jedynym rozwiązaniem jest porzucenie uprawnień roota po otwarciu portu.
Oto możliwe rozwiązanie polegające na zrzucaniu uprawnień roota w Pythonie: Dropping privileges in Python. Jest to dobre rozwiązanie w ogólności, ale musisz również dodać do funkcji funkcję os.setgroups([])
, aby zagwarantować, że członkostwo grupy użytkownika root nie zostanie zachowane.
Skopiowałem i trochę wyczyściłem kod, usunąłem rejestrowanie i procedury obsługi wyjątków, więc pozostało ci właściwe obsłużenie OSError
(zostanie ono wysłane, gdy proces nie będzie mógł zmienić jego efektywnego UID lub 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)
Należy pamiętać, że katalog HOME nadal będzie "/ root', a nie '/ home/uid_name', a nazwa uid_name nie będzie w stanie nic zrobić z' ~/', która rozwinie się do'/root/'. Może to wpłynąć na moduły takie jak matplotlib przechowujące dane konfiguracyjne w katalogu HOME. 'authbind' wydaje się właściwym sposobem na rozwiązanie tego problemu. –
A zmienna HOME nie będzie jedyną, która wciąż myśli, że bieżący użytkownik jest rootem. –
* "Nie można otworzyć serwera na porcie 80 bez uprawnień root'a ..." * - To niekoniecznie musi być prawda (może już?). Zobacz także: Czy zezwolić procesowi spoza root na powiązanie z portem 80 i 443?] (Https://superuser.com/q/710253/173513) na SuperUser i [Czy jest sposób, aby procesy inne niż root wiązały się z "uprzywilejowanymi" "Porty na Linuksie?" (Https://stackoverflow.com/q/413807/608639) – jww
Polecam używanie authbind
aby uruchomić program Pythona, więc nic z tego nie ma uruchomić jako root.
Przykład użycia 'authbind' - http://goo.gl/fxFde6 - Zamień NodeJS na cokolwiek chcesz (np. : python) – starlocke
Systemd może zrobić dla ciebie, jeśli uruchomić program przez Systemd, Systemd może przekazać wyłączyć już otwarte gniazdo słuchając go, a to może także aktywować swój program na pierwszym połączeniu . i nawet nie musisz go dememonizować.
Jeśli zamierzasz korzystać z samodzielnego podejścia, potrzebujesz możliwości CAP_NET_BIND_SERVICE (sprawdź stronę podręcznika możliwości). Można to zrobić programując program, korzystając z odpowiedniego narzędzia wiersza poleceń lub ustawiając aplikację (1) na suid root (2) start up (3) nasłuchuj przywilejów/możliwości przywracania portu (4) natychmiast .
Pamiętaj, że korzeń suid programy pochodzą z wielu względów bezpieczeństwa (czyste i bezpieczne środowisko, umask, przywileje, rlimits, wszystkie te rzeczy są rzeczy, które program będzie musiał skonfigurować poprawnie). Jeśli możesz użyć czegoś takiego jak systemd, tym lepiej.
Większość z nich działa, chyba że musisz poprosić o gniazdo po wykonaniu innych czynności, których nie chcesz być superużytkownikiem.
Zrobiłem projekt o nazwie tradesocket jakiś czas temu. Pozwala na przekazywanie do gniazdka w systemie posix między procesami. To, co robię, polega na wyłapywaniu procesu na początku, który pozostaje superużytkownikiem, a reszta procesu spada w uprawnienia, a następnie żąda gniazda od drugiego.
Nie jest dobrym pomysłem, aby poprosić użytkownika o podanie swojej nazwy użytkownika i grupy, kiedy tylko chcę upuścić uprawnienia. Oto nieco zmodyfikowana wersja kodu Tamása, która zrzuci przywileje i przełączy się na użytkownika, który zainicjował polecenie sudo. Zakładam, że używasz sudo (jeśli nie, użyj kodu Tamás'a).
#!/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())
Poniżej znajduje się dalsze dostosowanie Tamás's answer, z następującymi zmianami:
- Użyj
python-prctl
module do spadku możliwości systemu Linux do określonej listy możliwości zachować. - Użytkownik może być opcjonalnie przekazany jako parametr (domyślnie szuka użytkownika, który prowadził
sudo
). - Ustawia wszystkie grupy użytkowników i
HOME
. - Opcjonalnie zmienia katalog.
(Jestem stosunkowo nowy w użyciu tej funkcji, jednak, więc może coś przeoczyć. To może nie działać na starszych jąder (< 3.8) lub jądra z możliwościami systemu plików wyłączone.)
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)
może być stosowany w sposób następujący:
drop_privileges(user='www', rundir='~', caps=[prctl.CAP_NET_BIND_SERVICE])
- 1. Upuszczanie uprawnień roota
- 2. Upuszczanie uprawnień roota dla niektórych operacji w Pythonie
- 3. Zainstaluj zsh bez uprawnień roota?
- 4. Upuszczanie przywilejów roota i wciąż generowanie coredumpów
- 5. Upuszczanie uprawnień w C++ w systemie Windows
- 6. Linux nieprzetworzone dane wejściowe bez uprawnień roota?
- 7. zmiana uprawnień plików w pythonie
- 8. Jak wykonać nieliniowe, kompleksowe odnajdywanie roota w Pythonie
- 9. Upuszczanie kolumn w ramce danych
- 10. Uprawnienia roota dla aplikacji iOS
- 11. Podnoszenie uprawnień do używania mach_inject
- 12. error_perm: 550 Odmowa uprawnień
- 13. Upuszczanie wszystkich kolekcji w Mongoengine
- 14. Jak wyświetlić bash_history dla roota?
- 15. Jak .bashrc dla roota w Dockerze
- 16. dostęp klienta do roota w stacji dokującej
- 17. Jak wykonać dokowanie jako roota?
- 18. Utwórz hasło roota dla PHPMyAdmin
- 19. Admin Django Upuszczanie wyborów
- 20. Złomowanie - Cicho upuszczanie elementu
- 21. Jak symulować przeciąganie i upuszczanie HTML5 w Selenium Webdriver?
- 22. Dlaczego PyUSB/libusb wymaga uprawnień root (sudo) w systemie Linux?
- 23. Odmowa uprawnień w tmp
- 24. Przeciąganie i upuszczanie zdarzeń w osadzonym SVG?
- 25. Jak zaimplementować przeciąganie i upuszczanie w Angular2?
- 26. Niestandardowe przeciąganie i upuszczanie Java w JPanel
- 27. Przeciąganie i upuszczanie * FROM * przeglądarki?
- 28. Jak zmienić hasło roota na puste?
- 29. Windows 10 - Bash (Ubuntu) SU (hasło roota)
- 30. Wdrażanie usług trybu roota w Dockerze w wielu domenach awarii
http://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged -ports-1024-on-li –
Na współczesnym Linuxie potrzebujesz tylko możliwości CAP_NET_ BIND_SERVICE, aby powiązać port 80, NIE musisz być rootem, nawet przy uruchomieniu aplikacji. Możliwości to standard POSIX, 1003.1e, czyli partycjonowanie wszystkich potężnych uprawnień roota w zestaw odrębnych uprawnień. Patrz: python-cap-ng i/sbin/setcap,/sbin/getcap (te są równoważne chmod setuid i ls -l) –
Dla python2 i być może inni tłumacze, zyskując możliwości jest częścią ty chcesz być ostrożny z - libcap-ng może zrzucić ograniczenia, ale nie daje im. Ta odpowiedź na pytanie, o którym wspomniał Ian, jest względnie bezpiecznym sposobem na rozdzielenie jednego pułapu w czasie dla konkretnych projektów: http://stackoverflow.com/a/21895123/1724577 – duanev