Chociaż 80 i 443 to porty systemowe, w jaki sposób większość serwerów WWW może się z nimi połączyć?

18

Uruchomienie usługi internetowej, która łączy się z portem 80, zwykle nie wymaga uprawnień sudoer. Ponieważ porty 80/443 są portami systemowymi, co oznacza, że ​​mogą z nich korzystać tylko uprzywilejowani użytkownicy, dlaczego więc te usługi mogą nadal łączyć się z tymi portami?

adaml
źródło
1
„zwykle nie wymaga uprawnień sudoer” jest niepoprawne.
tedder42

Odpowiedzi:

29

Istnieją zasadniczo dwa różne podejścia:

  1. Początkowo zacznij działać jako root, powiąż z uprzywilejowanym portem, a następnie zejdź do nieuprzywilejowanego użytkownika.

  2. inetd lub xinetd działa uprzywilejowane i przekazuje żądania do serwera WWW działającego nieuprzywilejowanego.

Joe Sniderman
źródło
3
W systemie Linux możesz także zastosować do programu funkcję CAP_NET_BIND_SERVICE lub możesz użyć iptables do przekierowania portu systemowego na zwykły.
Zan Lynx,
10
i tylko dla wyjaśnienia dla OP: powodem, dla którego opcja nr 1 działa, jest to, że gdy procesy upuszczają uprawnienia, mogą zachować otwarte deskryptory plików - nawet jeśli nie będą mogły otworzyć ich po raz drugi.
strugee,
Istnieje również Authbind .
Boris the Spider
5

Ponieważ port 80/443 to porty systemowe, co oznacza, że ​​mogą z niego korzystać tylko uprzywilejowani użytkownicy

Myślę, że źle to rozumiesz. Każdy może korzystać z tych portów. Powiązanie z nimi jest operacją uprzywilejowaną.

Uzasadnieniem jest to, że jakiś użytkownik Joe nie powinien mieć możliwości napisania złośliwego serwera WWW, a następnie utworzenia hosta, na którym nie ma żadnych uprawnień administracyjnych. Oczywiście jest to dość słaby model, zwykle nie ma nic, co powstrzymałoby Joe przed podłączeniem własnego komputera do sieci i mógłby mieć uprawnienia administracyjne do każdej maszyny, do której ma fizyczny dostęp.

Zrobię demonstrację z netcat.

Jako zwykły użytkownik nie mogę powiązać z portem 80:

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

Mogę powiązać z portem 8080:

$ nc -l -p 8080

Tymczasem w innym terminalu mogę połączyć się z portem 80 i wysłać trochę danych i zobaczyć, jak pojawiają się na końcu serwera, który właśnie uruchomiłem:

$ nc 127.0.0.1 8080 <<<"Hello world"

Jeśli chcę się połączyć z portem 80, muszę być rootem:

$ sudo nc -l -p 80

Lub mogę przypisać CAP_NET_BIND_SERVICEzdolność do ncpliku binarnego:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

Inną opcją jest napisanie programu serwera tak, aby po jego wywołaniu listen()upuścił uprawnienia administratora. Jest to dość powszechne rozwiązanie i zobaczysz je w przypadku większości demonów. Na przykład Apache zaczyna się od init jako root, a następnie upuszcza uprawnienia roota i staje się użytkownikiem www-datalub czymś podobnym, gdy jest związany z portem 80. Spróbuj uruchomić /etc/init.d/apache startjako root, a Apache prawdopodobnie się nie uruchomi.

Phil Frost
źródło
Pytanie brzmi „powiąż z tymi portami”. Jak myślisz, dlaczego się myli?
Barmar