Czy można dostroić parametr jądra, aby umożliwić programowi użytkownika powiązanie z portami 80 i 443?
Pytam, ponieważ uważam, że głupotą jest zezwolenie uprzywilejowanemu procesowi na otwarcie gniazda i słuchanie. Wszystko, co otwiera gniazdo i nasłuchuje, jest ryzykowne, a aplikacje wysokiego ryzyka nie powinny działać jako root.
Wolałbym raczej dowiedzieć się, jaki nieuprzywilejowany proces nasłuchuje na porcie 80, niż próbować usunąć złośliwe oprogramowanie, które zagrzebało się w uprawnieniach administratora.
Odpowiedzi:
Nie jestem pewien, do czego odnoszą się inne odpowiedzi i komentarze tutaj. Jest to możliwe dość łatwo. Istnieją dwie opcje, które pozwalają na dostęp do portów o niższych numerach bez konieczności podnoszenia procesu rootowania:
Opcja 1: Użyj,
CAP_NET_BIND_SERVICE
aby przyznać dostęp do portu o niskim numerze procesowi:Dzięki temu możesz przyznać stały dostęp do określonego pliku binarnego, aby połączyć się z portami o niskiej liczbie za pomocą
setcap
polecenia:Aby uzyskać więcej informacji na temat części e / i / p, patrz
cap_from_text
.Po wykonaniu tej czynności
/path/to/binary
będzie można połączyć się z portami o niskim numerze. Pamiętaj, że musisz używaćsetcap
samego pliku binarnego, a nie dowiązania symbolicznego.Opcja 2: Użyj,
authbind
aby przyznać jednorazowy dostęp, z lepszą kontrolą użytkownika / grupy / portu:Narzędzie
authbind
( strona podręcznika) istnieje właśnie w tym celu.Zainstaluj
authbind
za pomocą swojego ulubionego menedżera pakietów.Skonfiguruj go, aby udzielić dostępu do odpowiednich portów, np. Aby zezwolić na 80 i 443 od wszystkich użytkowników i grup:
Teraz wykonaj polecenie za pomocą
authbind
(opcjonalnie podając--deep
lub inne argumenty, patrz strona podręcznika):Na przykład
Oba powyższe mają swoje zalety i wady. Opcja 1 zapewnia zaufanie do pliku binarnego, ale nie zapewnia kontroli dostępu do portu. Opcja 2 zapewnia zaufanie użytkownikowi / grupie i zapewnia kontrolę nad dostępem do portu, ale AFAIK obsługuje tylko IPv4.
źródło
rwx
pozwolenia?-p
intead of+eip
?setcap
zgodę na specyficzny dla wersji plik wykonywalny ruby , np./usr/bin/ruby1.9.1
chmod
abybyport
plik do 777 był najlepszym pomysłem. Widziałem dawanie pozwoleń od500
do744
. Trzymałbym się najbardziej restrykcyjnego, który działa dla ciebie.Dale Hagglund jest na miejscu. Więc powiem to samo, ale w inny sposób, z pewnymi szczegółami i przykładami. ☺
W światach Uniksa i Linuksa właściwą rzeczą jest:
Nie masz pojęcia, gdzie jest wysokie ryzyko. Wysokie ryzyko polega na czytaniu z sieci i działaniu na podstawie tego, co nie jest odczytywane w prostych czynnościach otwierania gniazda, wiązania go z portem i wywoływania
listen()
. Jest to część usługi, która faktycznie komunikuje się, co jest dużym ryzykiem. Części, które otwarty,bind()
ilisten()
, a nawet (do pewnego stopnia) część, któraaccepts()
, nie są wysokie ryzyko i może być prowadzony pod egidą administratora. Nie używają i nie działają na danych (z wyjątkiem źródłowych adresów IP waccept()
przypadku) danych, które są pod kontrolą niezaufanych nieznajomych w sieci.Można to zrobić na wiele sposobów.
inetd
Jak mówi Dale Hagglund,
inetd
robi to stary „superserver sieciowy” . Konto, na którym jest uruchamiany proces obsługi, jest jedną z kolumn winetd.conf
. Nie dzieli części nasłuchującej i upuszczania części na dwa osobne programy, małe i łatwe do skontrolowania, ale dzieli główny kod usługi na osobny program,exec()
edytowany w procesie serwisowym, który spawnuje z otwartym deskryptorem pliku dla gniazda.Trudność audytu nie stanowi większego problemu, ponieważ wystarczy skontrolować tylko jeden program.
inetd
Głównym problemem nie jest zbyt wiele inspekcji, ale raczej to, że nie zapewnia prostej, precyzyjnej kontroli usług środowiska wykonawczego w porównaniu z nowszymi narzędziami.UCSPI-TCP i daemontools
Pakiety UCSPI-TCP i daemontools Daniela J. Bernsteina zostały zaprojektowane w tym celu w połączeniu. Alternatywnie można użyć w dużej mierze równoważnego zestawu narzędzi do bisów Daemontools Bruce'a Guentera .
Program do otwierania deskryptora pliku gniazda i łączenia się z uprzywilejowanym portem lokalnym pochodzi
tcpserver
z UCSPI-TCP. Robi zarównolisten()
iaccept()
.tcpserver
następnie spawnuje albo program usługowy, który sam upuszcza uprawnienia roota (ponieważ obsługiwany protokół wymaga uruchomienia jako superużytkownik, a następnie „zalogowania się”, jak ma to miejsce na przykład w przypadku demona FTP lub SSH) lubsetuidgid
który jest samodzielny mały i łatwy do skontrolowania program, który jedynie upuszcza uprawnienia, a następnie łączy obciążenia z odpowiednim programem serwisowym (z którego żadna część nigdy nie działa z uprawnieniami administratora, jak ma to miejsce, powiedzmy,qmail-smtpd
).run
Skrypt usługi byłby więc na przykład (ten dla dummyidentd zapewniający zerową usługę IDENT):nosh
Mój pakiet nosh jest do tego przeznaczony. Ma małą
setuidgid
użyteczność, podobnie jak inne. Jedyną niewielką różnicą jest to, że można go używać zsystemd
usługami typu „LISTEN_FDS”, a także z usługami UCSPI-TCP, więc tradycyjnytcpserver
program został zastąpiony przez dwa osobne programy:tcp-socket-listen
itcp-socket-accept
.Ponownie, narzędzia jednocelowe odradzają się i ładują się nawzajem. Jednym z interesujących elementów tego projektu jest to, że można zrezygnować z uprawnień administratora po,
listen()
ale nawet wcześniejaccept()
. Otorun
skrypt,qmail-smtpd
który naprawdę robi dokładnie to:Programy, które działają pod egidą administratora są drobne narzędzia chain-loading service-agnostyk
fdmove
,clearenv
,envdir
,softlimit
,tcp-socket-listen
, isetuidgid
. Do momentush
uruchomienia gniazdo jest otwarte i powiązane zsmtp
portem, a proces nie ma już uprawnień administratora.s6, s6-networking i execline
Pakiety sieciowe Laurent Bercot s6 i s6 zostały zaprojektowane do tego w połączeniu. Polecenia są strukturalnie bardzo podobne do poleceń
daemontools
i UCSPI-TCP.run
skrypty byłyby prawie takie same, z wyjątkiem podstawienia nas6-tcpserver
fortcpserver
is6-setuidgid
forsetuidgid
. Jednakże, można również zdecydować się na korzystanie z M. Bercot za execline zestawu narzędzi jednocześnie.Oto przykład usługi FTP, lekko zmodyfikowanej w stosunku do oryginału Wayne'a Marshalla , która wykorzystuje execline, s6, s6-networking i program serwera FTP z pliku publicznego :
ipsvd
Ipsvd Gerrit Pape to kolejny zestaw narzędzi, który działa na tych samych zasadach, co ucspi-tcp i s6-networking. Narzędzia są
chpst
itcpsvd
tym razem, ale robią to samo, a kod wysokiego ryzyka, który odczytuje, przetwarza i zapisuje rzeczy wysyłane przez sieć przez niezaufanych klientów, nadal znajduje się w osobnym programie.Oto przykład działania M. Pape'a
fnord
wrun
skrypcie:systemd
systemd
, nowy system nadzoru usług i inicjalizacji, który można znaleźć w niektórych dystrybucjach Linuksa, ma na celu robienie tego, coinetd
można . Jednak nie używa pakietu małych samodzielnych programów.systemd
Niestety, należy przeprowadzić audyt w całości.Z
systemd
jednym tworzy pliki konfiguracyjne, aby określić, które gniazdosystemd
nasłuchuje i usługi, któresystemd
rozpoczyna. Plik „jednostki” usługi ma ustawienia, które pozwalają na dużą kontrolę nad procesem obsługi, w tym nad tym, jak użytkownik działa.Gdy ten użytkownik jest ustawiony jako użytkownik niebędący superużytkownikiem,
systemd
wykonuje całą pracę polegającą na otwarciu gniazda, powiązaniu go z portem i wywołaniulisten()
(oraz, w razie potrzeby,accept()
) w procesie nr 1 jako superużytkownik oraz procesie obsługi spawn działa bez uprawnień administratora.źródło
Mam raczej inne podejście. Chciałem użyć portu 80 dla serwera node.js. Nie mogłem tego zrobić, ponieważ Node.js został zainstalowany dla użytkownika innego niż sudo. Próbowałem użyć dowiązań symbolicznych, ale to nie działało dla mnie.
Potem dowiedziałem się, że mogę przekierowywać połączenia z jednego portu do drugiego. Więc uruchomiłem serwer na porcie 3000 i skonfigurowałem port przekierowania z portu 80 na port 3000.
Ten link zawiera rzeczywiste polecenia, których można użyć do tego celu. Oto polecenia -
Użyłem drugiego polecenia i zadziałało to dla mnie. Myślę więc, że jest to środek, dla którego proces użytkownika nie może bezpośrednio uzyskiwać dostępu do niższych portów, ale umożliwia im dostęp za pomocą przekierowania portów.
źródło
Twoje instynkty są całkowicie poprawne: źle jest uruchamiać duży złożony program jako root, ponieważ ich złożoność sprawia, że trudno jest im ufać.
Ale złym pomysłem jest również zezwolenie zwykłym użytkownikom na łączenie się z uprzywilejowanymi portami, ponieważ takie porty zwykle reprezentują ważne usługi systemowe.
Standardowym podejściem do rozwiązania tej pozornej sprzeczności jest rozdział przywilejów . Podstawową ideą jest podzielenie programu na dwie (lub więcej) części, z których każda stanowi dobrze zdefiniowaną część ogólnej aplikacji i które komunikują się za pomocą prostych ograniczonych interfejsów.
W podanym przykładzie chcesz podzielić swój program na dwie części. Ten, który działa jako root i otwiera się i łączy z uprzywilejowanym gniazdem, a następnie przekazuje go jakoś innej części, która działa jako zwykły użytkownik.
Te dwa główne sposoby osiągnięcia tego rozdziału.
Pojedynczy program uruchamiany jako root. Pierwszą rzeczą, jaką robi, jest stworzenie niezbędnego gniazda, w możliwie najprostszy i ograniczony sposób. Następnie upuszcza uprawnienia, czyli przekształca się w zwykły proces w trybie użytkownika i wykonuje wszystkie inne czynności. Poprawne usuwanie uprawnień jest trudne, więc poświęć trochę czasu na studiowanie właściwego sposobu, aby to zrobić.
Para programów komunikujących się za pośrednictwem pary gniazd utworzonej przez proces nadrzędny. Nieuprzywilejowany program sterownika odbiera początkowe argumenty i być może wykonuje pewne podstawowe sprawdzenie poprawności argumentów. Tworzy parę połączonych gniazd za pomocą socketpair (), a następnie rozwidla i wykonuje dwa inne programy, które wykonają prawdziwą pracę i komunikują się za pośrednictwem pary gniazd. Jedna z nich jest uprzywilejowana i stworzy gniazdo serwera oraz wszelkie inne operacje uprzywilejowane, a druga wykona bardziej złożone, a zatem mniej godne zaufania wykonanie aplikacji.
[1] http://en.m.wikipedia.org/wiki/Privilege_separation
źródło
Najprostsze rozwiązanie: usuń wszystkie uprzywilejowane porty w systemie Linux
Działa na Ubuntu / Debian:
(działa dobrze dla VirtualBox z kontem innym niż root)
Teraz uważaj na bezpieczeństwo, ponieważ wszyscy użytkownicy mogą powiązać wszystkie porty!
źródło