Was sind Ports und wie lauschen Linux-Dienste?
Ports leiten Netzwerkverkehr an den richtigen Dienst. Lesen Sie mit ss, was lauscht, und unterscheiden Sie lokale Ports von öffentlich erreichbaren Ports.
Was ein Port tatsächlich ist
Ein Port ist eine Zahl. Sie ermöglicht es einem Server, mehrere Dienste gleichzeitig auszuführen, ohne dass sich deren Netzwerkverkehr vermischt. Ihr VPS hat eine IP-Adresse. Darauf können jedoch gleichzeitig ein Webserver, ein SSH-Server und eine Datenbank laufen. Wenn ein Paket eintrifft, muss das Betriebssystem wissen, für welchen dieser Dienste es bestimmt ist. Die Portnummer liefert diese Information. Webverkehr geht an Port 443, SSH an Port 22. Die IP-Adresse bringt das Paket zu Ihrem Server. Der Port leitet es an das richtige Programm auf diesem Server weiter.
Ein Port ist eine 16-Bit-Zahl. 16 Bit ergeben den Bereich von 0 bis 65535. Da 0 reserviert ist, werden Ports in der Praxis von 1 bis 65535 verwendet. Ports unter 1024 sind die „well-known“-Ports. Zum Öffnen dieser Ports ist root erforderlich. Deshalb verwenden Standarddienste diese Ports: 22 für SSH, 80 für HTTP, 443 für HTTPS und 53 für DNS. Ports über 1024 können von gewöhnlichen Programmen frei verwendet werden.
Es gibt zwei Arten: TCP und UDP. Eine Portnummer in TCP ist unabhängig von derselben Nummer in UDP. TCP ist das verbindungsorientierte Protokoll, das die meisten Dienste verwenden, etwa SSH, HTTP und Datenbanken. UDP ist verbindungslos und wird beispielsweise für DNS und einige VPNs verwendet. Wenn Sie eine Firewall-Regel erstellen, geben Sie normalerweise an, welches Protokoll gemeint ist, zum Beispiel 22/tcp.
Listening bezeichnet einen Prozess, der auf einem Port wartet
Ein Programm, das Verbindungen empfangen soll, bittet den Kernel, auf einem Port zu „listen“. Ab diesem Zeitpunkt ist der Port auf dem Rechner geöffnet, und das Programm beantwortet alle dort eintreffenden Verbindungen, sofern die Firewall sie zulässt. Ein Port, auf dem kein Prozess lauscht, weist Verbindungen einfach zurück. Die erste Frage bei jeder Sicherheitsprüfung lautet daher: Was lauscht auf welchem Port?
Der entsprechende Befehl lautet ss:
sudo ss -tlnpDie Flags stehen für TCP (t), ausschließlich lauschende Sockets (l), numerische Ports (n, sodass 22 statt ssh angezeigt wird) und den Prozess, dem der Socket gehört (p). Ein typisches Ergebnis:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxDie Spalte Process zeigt, welchem Programm die einzelnen Ports gehören. Damit lässt sich ermitteln, welcher Prozess unbeabsichtigt weiterläuft.
Die Spalte „Local Address“ ist der entscheidende Teil
Prüfen Sie die Adresse vor jedem Port sorgfältig. Sie legt fest, wer den Dienst erreichen kann. Es gibt drei Fälle, die Sie ständig sehen werden.
0.0.0.0:22 bedeutet: „Auf jeder IPv4-Adresse dieses Rechners lauschen“, einschließlich der öffentlichen Adresse. Der Dienst ist über IPv4 aus dem Internet erreichbar, sofern die Firewall dies zulässt.
[::]:80 bedeutet dasselbe für IPv6: Auf jeder IPv6-Adresse lauschen, einschließlich der öffentlichen Adressen. Viele Programme binden standardmäßig an diese Adresse. Unter Linux akzeptiert ein ::-Socket häufig auch IPv4.
127.0.0.1:5432 bedeutet: „Nur auf Loopback lauschen.“ 127.0.0.1 ist die Adresse, über die ein Rechner mit sich selbst kommuniziert. Sie ist von keinem anderen Ort aus routbar. Ein Dienst, der an diese Adresse gebunden ist, ist nur auf demselben Server erreichbar, niemals aus dem Internet, unabhängig von der Firewall-Konfiguration. Die oben gezeigte Postgres-Zeile ist konstruktionsbedingt sicher.
Daraus folgt direkt die praktische Regel: Eine Datenbank, ein Cache oder ein Administrationspanel, das nur von Ihren eigenen Anwendungen verwendet wird, sollte an 127.0.0.1 und nicht an 0.0.0.0 gebunden werden. Wenn der Dienst nie auf einer öffentlichen Adresse lauscht, gibt es für einen Angreifer nichts zu erreichen.
Listening bedeutet nicht Erreichbarkeit
Eine weitere Unterscheidung verhindert viel Verwirrung. Ein auf dem Rechner geöffneter Port, an dem also ein Programm Verbindungen entgegennimmt, ist etwas anderes als ein Port, der von außen erreichbar ist, weil die Firewall ihn zulässt. Beides muss erfüllt sein, damit sich ein entfernter Client verbinden kann. Die beiden Fehler sehen auch auf der Client-Seite unterschiedlich aus: Wird eine Verbindung abgelehnt, hat nichts auf dem Port Verbindungen entgegengenommen. Hängt die Verbindung dagegen und läuft schließlich in einen Timeout, hat die Firewall das Paket meist verworfen. Genau das sagen diese beiden SSH-Fehler aus.
Es gibt also zwei Kontrollebenen. Sie legen über die Bind-Adresse jedes Dienstes fest, an welchen Adressen Verbindungen entgegengenommen werden. Mit einer Firewall legen Sie fest, was die Außenwelt erreichen kann. Ein gut betriebener Server verwendet beides: Dienste binden nur an die benötigten Adressen, und eine Firewall verweigert alles, was Sie nicht ausdrücklich erlaubt haben. Mit ss zu prüfen, welche Ports Verbindungen entgegennehmen, ist der erste Schritt. Im zweiten Schritt legen Sie fest, was die Firewall zulässt. Das wird in Firewalls 101 mit UFW behandelt.
Dabei gibt es eine wichtige Besonderheit. IPv4 und IPv6 sind getrennt. Eine Firewall, die nur IPv4 abdeckt, lässt die [::]-Dienste über IPv6 offen. Für diese konkrete Falle gibt es einen eigenen Beitrag: die IPv6-Firewall-Falle.
FAQ
Wie sehe ich, welche Ports auf meinem Linux-Server offen sind?
Führen Sie sudo ss -tlnp für TCP oder sudo ss -ulnp für UDP aus. Der Befehl listet jeden lauschenden Socket, den Port, die lokale Adresse, an die er gebunden ist, und den Prozess auf, dem er gehört. Sehen Sie sich die Spalte Local Address an: 0.0.0.0 oder [::] bedeutet, dass der Dienst im Netzwerk erreichbar ist, während 127.0.0.1 bedeutet, dass er nur auf dem Server selbst lauscht.
Was ist der Unterschied zwischen 0.0.0.0 und 127.0.0.1?
0.0.0.0 bedeutet „auf allen IPv4-Adressen lauschen“, einschließlich der öffentlichen Adresse. Der Dienst kann dadurch aus dem Netzwerk erreicht werden. 127.0.0.1 ist die Loopback-Adresse. Der Server verwendet sie für die Kommunikation mit sich selbst. Sie ist von keiner anderen Stelle aus routbar. Ein Dienst, der daran gebunden ist, ist daher nur lokal erreichbar. Binden Sie interne Dienste an 127.0.0.1, damit sie niemals nach außen erreichbar sind.
Muss ich einen Port in der Firewall öffnen, damit ein Dienst funktioniert?
Nur bei Diensten, die von anderen Servern aus erreichbar sein müssen. Ein Dienst, der an 127.0.0.1 gebunden ist, benötigt keine Firewall-Regel, weil ihn von außen ohnehin niemand erreichen kann. Für einen Dienst auf 0.0.0.0 oder [::] benötigen Sie eine Firewall-Regel, die den Netzwerkverkehr erlaubt. Standardmäßig sollte der Verkehr abgewiesen werden, bis Sie eine solche Regel hinzufügen.
Was ist der Unterschied zwischen einem TCP-Port und einem UDP-Port?
TCP ist verbindungsorientiert und wird von den meisten Diensten verwendet, beispielsweise von SSH, Webservern und Datenbanken. UDP ist verbindungslos und wird von DNS sowie einigen VPNs verwendet. Dieselbe Nummer bezeichnet bei TCP und UDP jeweils einen eigenen Port. Daher sind 53/tcp und 53/udp unterschiedlich. Beim Schreiben von Firewall-Regeln geben Sie das Protokoll an, zum Beispiel 22/tcp.