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 Nummer, über die ein Server mehrere Dienste gleichzeitig betreiben kann, ohne dass sich deren Netzwerkverkehr vermischt. Ihr VPS hat eine IP-Adresse, kann aber gleichzeitig einen Webserver, einen SSH-Server und eine Datenbank ausführen. Wenn ein Paket eintrifft, muss das Betriebssystem wissen, für welchen dieser Dienste es bestimmt ist. Die Portnummer liefert diese Information. HTTPS-Verkehr wird normalerweise an Port 443 geleitet, 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-Nummer: 16 Bit ergeben den Bereich von 0 bis 65535, und 0 ist reserviert. In der Praxis reichen Ports daher von 1 bis 65535. Ports unter 1024 sind die „well-known“-Ports. Standardmäßig erlaubt Linux nur root oder einem Programm mit der CAP_NET_BIND_SERVICE-Capability, diese Ports zu öffnen. Deshalb verwenden Standarddienste diese Ports: 22 für SSH, 80 für HTTP, 443 für HTTPS und 53 für DNS. Das net.ipv4.ip_unprivileged_port_start-sysctl kann diese Grenze verschieben. Standardmäßig ist sie auf 1024 gesetzt. Ports ab 1024 können gewöhnliche Programme frei verwenden.
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 einen Port in der Firewall öffnen, geben Sie normalerweise auch das Protokoll an, 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 entscheidend
Prüfen Sie die Adresse vor jedem Port genau. Sie bestimmt, wer den Dienst erreichen kann. Es gibt drei Fälle, die Ihnen ständig begegnen werden.
0.0.0.0:22 bedeutet: Der Dienst lauscht auf jeder IPv4-Adresse dieses Rechners, einschließlich der öffentlichen Adresse. Der Dienst ist über IPv4 aus dem Internet erreichbar, sofern die Firewall dies erlaubt.
[::]:80 bedeutet dasselbe für IPv6: Der Dienst lauscht auf jeder IPv6-Adresse, einschließlich öffentlicher Adressen. Viele Programme binden standardmäßig an diese Adresse. Unter Linux akzeptiert ein ::-Socket häufig auch IPv4-Verbindungen.
127.0.0.1:5432 bedeutet: Der Dienst lauscht nur auf dem Loopback-Interface. 127.0.0.1 ist die Adresse, über die ein Rechner mit sich selbst kommuniziert. Unter den Standardeinstellungen des Kernels ist sie von keinem anderen Ort aus routbar. Ein Dienst, der daran gebunden ist, ist daher nur von demselben Server aus erreichbar, nicht aus dem Internet. Das gilt auch dann, wenn Ihre Firewall den Port erlauben würde. Die oben gezeigte Postgres-Zeile ist standardmäßig sicher. Eine Ausnahme ist die Kernel-Einstellung route_localnet. Sie ist standardmäßig deaktiviert, wird aber von einigen Tools aktiviert, darunter kube-proxy von Kubernetes. Zusammen mit den passenden Routing- oder NAT-Regeln kann Loopback-Verkehr dann von außen eintreffen. sysctl -a | grep route_localnet sollte in jeder Zeile = 0 anzeigen.
Die praktische Regel ergibt sich direkt daraus: 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 sein. Wenn der Dienst nie auf einer öffentlichen Adresse lauscht, gibt es für einen Angreifer nichts zu erreichen.
Lauschen bedeutet nicht, dass ein Dienst erreichbar ist
Eine weitere Unterscheidung verhindert viele Missverständnisse. Ein Port kann auf dem Rechner offen sein, weil ein Programm darauf lauscht. Das bedeutet jedoch nicht automatisch, dass der Port von außen erreichbar ist, weil die Firewall den Zugriff erlauben muss. Für eine Verbindung von einem entfernten Client müssen beide Bedingungen erfüllt sein. Die beiden Fehler sehen auf der Client-Seite außerdem unterschiedlich aus: Eine abgelehnte Verbindung bedeutet normalerweise, dass kein Programm auf dem Port lauschte. Wenn die Verbindung dagegen hängen bleibt und schließlich wegen eines Timeouts abbricht, hat die Firewall das Paket normalerweise verworfen. Genau das sagen diese beiden SSH-Fehler aus.
Es gibt also zwei Kontrollschichten. Sie bestimmen durch die Bind-Adresse jedes Dienstes, worauf der Dienst lauscht. Mit einer Firewall bestimmen Sie, was die Außenwelt erreichen kann. Ein ordnungsgemäß betriebener Server verwendet beides: Dienste lauschen nur dort, wo sie benötigt werden, und eine Firewall verweigert alles, was Sie nicht ausdrücklich erlaubt haben. Mit ss sehen Sie zunächst, worauf Dienste lauschen. Anschließend legen Sie fest, was die Firewall erlaubt. 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. Diese konkrete Falle wird in einem eigenen Beitrag behandelt: 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 der Socket gehört. Prüfen Sie die Spalte Local Address: 0.0.0.0 oder [::] bedeutet, dass der Dienst für das Netzwerk erreichbar ist. 127.0.0.1 bedeutet, dass er nur auf dem Rechner selbst lauscht.
Was ist der Unterschied zwischen 0.0.0.0 und 127.0.0.1?
0.0.0.0 bedeutet: Der Dienst lauscht auf allen IPv4-Adressen, einschließlich der öffentlichen Adresse. Er kann daher aus dem Netzwerk erreicht werden. 127.0.0.1 ist die Loopback-Adresse, über die ein Rechner mit sich selbst kommuniziert. Unter den Standardeinstellungen des Kernels ist sie von keinem anderen Ort aus routbar. Ein daran gebundener Dienst ist daher nur lokal erreichbar. Binden Sie interne Dienste an 127.0.0.1, damit sie nicht über das Netzwerk erreichbar sind.
Muss ich einen Port in der Firewall öffnen, damit ein Dienst funktioniert?
Nur für Dienste, die von anderen Rechnern aus erreichbar sein müssen. Ein an 127.0.0.1 gebundener Dienst benötigt keine Allow-Regel, weil ihn unter den Standardeinstellungen des Kernels ohnehin nichts von außen erreichen kann. Ein Dienst auf 0.0.0.0 oder [::] benötigt eine Allow-Regel, sobald Ihre Firewall eingehenden Datenverkehr standardmäßig verweigert, was sie sollte. Wenn keine Firewall aktiv ist oder ihre Richtlinie alles akzeptiert, ist der Dienst auch ohne Regel bereits erreichbar.
Was ist der Unterschied zwischen einem TCP-Port und einem UDP-Port?
TCP ist verbindungsorientiert und wird von den meisten Diensten verwendet, etwa von SSH, Webservern und Datenbanken. UDP ist verbindungslos und wird für DNS und einige VPNs verwendet. Dieselbe Nummer bezeichnet in TCP und UDP jeweils einen separaten Port. Daher sind 53/tcp und 53/udp verschieden. Wenn Sie Firewall-Regeln schreiben, geben Sie das Protokoll an, zum Beispiel 22/tcp.