Obwohl 80 und 443 Systemports sind, wie können sich die meisten Webserver überhaupt an sie binden?

18

Das Ausführen eines Webdienstes, der an Port 80 gebunden ist, erfordert normalerweise keine sudoer-Berechtigungen. Da es sich bei den Ports 80/443 um Systemports handelt, das heißt, sie können nur von privilegierten Benutzern verwendet werden. Warum können diese Dienste noch eine Bindung an diese Ports herstellen?

Adaml
quelle
1
"erfordert normalerweise keine Sudoer-Rechte" ist falsch.
Tedder42

Antworten:

29

Grundsätzlich gibt es zwei verschiedene Ansätze:

  1. Beginnen Sie zunächst mit der Ausführung als root, binden Sie sich an den privilegierten Port und geben Sie ihn dann an einen nicht privilegierten Benutzer weiter.

  2. inetd oder xinetd wird privilegiert ausgeführt und leitet die Anforderungen an einen nicht privilegierten Webserver weiter.

Joe Sniderman
quelle
3
Unter Linux können Sie auch die CAP_NET_BIND_SERVICE-Funktion auf das Programm anwenden oder iptables verwenden, um einen Systemport auf einen regulären Port umzuleiten.
Zan Lynx,
10
und nur zur Verdeutlichung für OP: Der Grund, warum Option 1 funktioniert, besteht darin, dass Prozesse, die Berechtigungen löschen, geöffnete Dateideskriptoren beibehalten dürfen - auch wenn sie diese nicht ein zweites Mal öffnen dürfen.
Strugee
Es gibt auch Authbind .
Boris die Spinne
5

Da Port 80/443 Systemports sind, können sie nur von privilegierten Benutzern verwendet werden

Ich denke du hast es falsch gemacht. Jeder kann diese Ports nutzen. Das Binden an sie ist eine privilegierte Operation.

Das Grundprinzip hier ist, dass ein Benutzer Joe keinen bösartigen Webserver schreiben und dann einen Host erstellen kann, auf dem er keine Administratorrechte hat. Natürlich ist dies ein ziemlich schwaches Modell. Normalerweise hindert nichts Joe daran, seinen eigenen Computer in das Netzwerk einzubinden, und er könnte Administratorrechte für jeden Computer haben, auf den er physischen Zugriff hat.

Ich werde eine Demonstration mit Netcat machen.

Als normaler Benutzer kann ich mich nicht an Port 80 binden:

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

Ich kann an Port 8080 binden:

$ nc -l -p 8080

Währenddessen kann ich in einem anderen Terminal eine Verbindung zu Port 80 herstellen und einige Daten senden. Diese werden auf dem gerade gestarteten Server angezeigt:

$ nc 127.0.0.1 8080 <<<"Hello world"

Wenn ich mich an Port 80 binden möchte, muss ich root sein:

$ sudo nc -l -p 80

Oder ich kann die CAP_NET_BIND_SERVICEFähigkeit der ncBinärdatei zuweisen :

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

Eine andere Möglichkeit besteht darin, das Serverprogramm so zu schreiben, dass es nach dem Aufruf listen()die Root-Rechte aufhebt. Dies ist eine ziemlich verbreitete Lösung, und Sie werden es bei den meisten Daemons sehen. Apache wird beispielsweise von init als root gestartet und löscht dann die Root-Rechte und wird zum Benutzer www-dataoder zu etwas Ähnlichem, sobald es an Port 80 gebunden ist. Versuchen Sie, /etc/init.d/apache startals nicht root auszuführen, und Apache wird wahrscheinlich nicht gestartet.

Phil Frost
quelle
Die Frage lautet "An diese Ports binden". Warum glaubst du, hat er es falsch gemacht?
Barmar