Linux: Prüfen, ob ein Port offen ist
Prüfen Sie mit ss, welcher Dienst lauscht, und testen Sie den Port extern mit nc oder nmap. Ein blockierter Port hängt, ein geschlossener lehnt sofort ab.
Prüfen, ob ein Port unter Linux offen ist: Zuerst die richtige Frage auswählen
Um zu prüfen, ob ein Port unter Linux offen ist, müssen Sie zuerst festlegen, welche Frage Sie stellen. „Offen“ bedeutet je nach Prüfpunkt etwas anderes. Auf dem Server selbst bedeutet es, dass ein Prozess an diesen Port gebunden ist und auf Verbindungen wartet. Von einem anderen Rechner aus bedeutet es, dass ein Paket diesen Prozess erreicht und eine Antwort zurückkommt. Wenn keine Antwort zurückkommt, lautet die eigentliche Frage, welches Gerät das Paket verworfen hat. sudo ss -ltnp beantwortet die erste Frage. nc -z oder nmap beantwortet die zweite. Firewall-Zähler und tcpdump beantworten die dritte.
Eine falsche Prüfung kostet Sie schnell einen ganzen Nachmittag. Ein Test auf dem Server selbst erreicht niemals die Netzwerk-Firewall Ihres Providers, weil diese Filterung außerhalb des Servers erfolgt. Wenn Portnummern für Sie noch neu sind, erklärt wie Ports und Sockets unter Linux funktionieren das Modell, das dieser Leitfaden voraussetzt.
Was lauscht auf diesem System? Die Ausgabe von ss lesen
ss wird mit iproute2 ausgeliefert und ist daher in jeder aktuellen Distribution vorhanden. netstat stammt aus net-tools, das Ubuntu seit Jahren nicht mehr standardmäßig installiert. Daher beantwortet netstat -tulpn die Frage netstat: command not found häufig. Lernen Sie ss und vermeiden Sie diese Enttäuschung.
sudo ss -ltnp-l zeigt nur lauschende Sockets. -t beschränkt die Liste auf TCP. -n gibt Zahlen aus, statt Namen aufzulösen. Dadurch liefert der Befehl sofort ein Ergebnis. -p nennt den Prozess, dem der Socket gehört, und benötigt root: Ohne sudo bleibt die Spalte Process bei allen Prozessen leer, die nicht Ihnen gehören. Ersetzen Sie -t durch -u, um UDP anzuzeigen.
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=921,fd=3))
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("node",pid=1442,fd=19))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=921,fd=4))Die Spalte Local Address entscheidet alles. Sie wird jedoch häufig übergangen.
0.0.0.0:22bedeutet jede IPv4-Adresse auf dem System. Der Dienst ist daher von außen erreichbar, wenn die Firewall dies zulässt.[::]:22bedeutet dasselbe für IPv6.127.0.0.1:8080bedeutet nur Loopback. Nichts außerhalb dieses Systems kann den Dienst erreichen.10.20.0.5:5432bedeutet genau diese Schnittstellenadresse und keine andere. Das ist bei privaten Netzwerkkonfigurationen häufig.- Eine leere Spalte Process weist normalerweise auf ein fehlendes
sudohin, nicht auf einen fehlenden Prozess.
Um einen einzelnen Port abzufragen, filtern Sie innerhalb von ss, statt die gesamte Liste mit grep zu durchsuchen:
sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcpEine leere Ausgabe bei allen drei Befehlen bedeutet, dass kein Prozess diesen Port verwendet. Der Dienst ist beendet, konnte nicht gestartet werden oder lauscht an einer anderen Stelle. Lesen Sie systemctl status <unit> und journalctl -u <unit> -n 50, bevor Sie eine einzige Firewall-Regel ändern.
Warum 127.0.0.1 unter „Local Address“ einen ganzen Nachmittag kosten kann
Ein Socket, der an 127.0.0.1 gebunden ist, kann von keinem anderen Host erreicht werden. Keine Firewall-Regel ändert daran etwas. Der Kernel leitet 127.0.0.0/8 ausschließlich an das Loopback-Interface weiter. Ein Paket mit dieser Zieladresse, das an einer echten Netzwerkkarte eintrifft, wird als Martian-Paket verworfen. Der Prozess läuft also, ss zeigt den Socket als Listening an, ufw allow 8080 meldet Erfolg, und die Verbindung von Ihrem Laptop schlägt trotzdem fehl. Sie schlägt mit einem sofortigen Connection refused fehl. Das Paket erreicht Ihre öffentliche Adresse, findet dort keinen gebundenen Socket, und der Kernel antwortet mit einem TCP-Reset.
Viele Programme binden absichtlich an das Loopback-Interface. Für eine Datenbank oder eine Administrationsschnittstelle ist das der richtige Standard. Sie haben zwei sinnvolle Möglichkeiten. Ändern Sie die Bind-Adresse in der programminternen Konfiguration (listen_addresses in postgresql.conf, bind in redis.conf oder das Host-Argument Ihrer Anwendung) und öffnen Sie anschließend die Firewall. Oder lassen Sie den Dienst am Loopback-Interface und greifen Sie über eine andere Komponente darauf zu, beispielsweise über einen nginx-Reverse-Proxy oder einen SSH-Tunnel von Ihrem Laptop:
ssh -L 8080:127.0.0.1:8080 user@203.0.113.10Docker verwendet in seinem Publish-Flag dieselbe Unterscheidung. -p 8080:8080 bindet an 0.0.0.0 und macht den Container aus dem Internet erreichbar. -p 127.0.0.1:8080:8080 bindet an das Loopback-Interface und hält den Container lokal.
So prüfen Sie von einem anderen Rechner aus, ob ein Port unter Linux offen ist
Führen Sie diesen Test aus einem anderen Netzwerk aus. Ein Test auf dem Server beweist nur, dass der Loopback-Pfad funktioniert. Selbst eine Verbindung zur eigenen öffentlichen IP-Adresse vom Server aus umgeht die Netzwerk-Firewall Ihres Providers, weil dieser Filter außerhalb des VPS ausgeführt wird.
nc -zv -w 3 203.0.113.10 443-z stellt eine Verbindung her und beendet sie, ohne Daten zu senden. -w 3 bricht nach drei Sekunden ab. Dieses Flag ist wichtig: Ohne Timeout versucht der Client bei einem verworfenen Paket länger als zwei Minuten, das SYN erneut zu senden, bevor der Kernel den Versuch beendet. Bei Erfolg sieht die Ausgabe so aus:
Connection to 203.0.113.10 443 port [tcp/https] succeeded!Wenn das Tool fehlt (nc: command not found), installieren Sie netcat-openbsd unter Debian oder Ubuntu. Alternativ können Sie die integrierte Netzwerkumleitung von bash verwenden. Dafür ist kein Paket erforderlich:
timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"Diese Syntax ist eine Funktion von bash. Führen Sie den Befehl daher mit bash aus. /bin/sh ist unter Debian und Ubuntu dash. Diese Shell unterstützt /dev/tcp nicht und meldet, dass der Pfad nicht existiert. Für einen Portbereich oder wenn der Status ausdrücklich benannt werden soll, verwenden Sie nmap für Hosts, für die Sie verantwortlich sind:
sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10-Pn überspringt die Host-Erkennung. Die meisten VPS-Anbieter verwerfen ICMP-Echo-Anfragen. Ohne -Pn entscheidet nmap daher, dass der Host nicht erreichbar ist, und führt keinen Scan aus. nmap gibt open aus, wenn eine Antwort eingegangen und die Verbindung akzeptiert wurde, closed, wenn eine Antwort mit einem Reset eingegangen ist, und filtered, wenn überhaupt keine Antwort eingegangen ist. Bei einem Webdienst trennt curl -sS -o /dev/null -w '%{http_code}\n' https://example.com einen Netzwerkfehler von einem Anwendungsfehler, weil ein Statuscode beweist, dass der gesamte Pfad funktioniert hat.
Warum ein blockierter Port hängt und ein geschlossener Port sofort ablehnt
Eine sofortige Ablehnung. Das Paket hat den Rechner erreicht, und etwas hat darauf geantwortet.
nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refusedZwei verschiedene Ursachen erzeugen genau diese Meldung. Entweder ist kein Prozess an diese Adresse und diesen Port gebunden, sodass der Kernel mit einem TCP-Reset geantwortet hat, oder eine Firewall-Regel hat das Paket mit einem Reset oder einer ICMP-Meldung port unreachable abgelehnt. Eine Ablehnung ist eine eindeutige Antwort und kommt innerhalb eines Roundtrips zurück.
Eine Pause, dann ein Timeout. Etwas hat das Paket verworfen und keine Antwort gesendet.
nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progressDas bewirkt eine DROP-Regel. Dasselbe gilt für eine Provider-Firewall oder eine Cloud-Sicherheitsgruppe. Stille ist das typische Merkmal eines Drops, weil der Absender einen Drop nicht von einem nicht erreichbaren Host unterscheiden kann.
Das Symptom zeigt Ihnen, wo Sie als Nächstes suchen sollten. Eine Ablehnung bedeutet, dass die Pakete das Netzwerk problemlos durchqueren. Gehen Sie daher zurück zu ss -ltnp und prüfen Sie die Bind-Adresse sowie die Portnummer. Ein Timeout bedeutet, dass Pakete verworfen werden. Lesen Sie die Firewalls daher von außen nach innen. Abgelehnt oder Timeout bei SSH erläutert diese Unterscheidung für Port 22, woran die meisten Benutzer sie zuerst erkennen.
ufw bietet beide Verhaltensweisen absichtlich an: ufw deny 8080 verwirft Pakete, und ufw reject 8080 sendet eine Ablehnung. In nftables lauten die beiden Ziele drop und reject, in iptables -j DROP und -j REJECT. Standardrichtlinien sind fast immer auf Drop gesetzt. Deshalb führt eine fehlende Regel zu einem Hänger statt zu einer Fehlermeldung.
Wer blockiert den Port? Arbeiten Sie sich von außen nach innen vor
sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list rulesetDie Zähler in -v sind der entscheidende Teil. Führen Sie den nc-Test von außen aus, führen Sie den iptables-Befehl erneut aus und suchen Sie nach dem Zähler, der sich verändert hat: Die Regel, deren Paketanzahl steigt, verarbeitet Ihren Netzwerkverkehr. Dadurch ersetzen Sie Vermutungen durch Belege.
Der entscheidende Test wird auf dem Server ausgeführt. Dabei wird der Netzwerkverkehr überwacht, während Sie von außen eine Verbindung herstellen:
sudo tcpdump -ni any tcp port 8080Ein eingehendes SYN ohne ausgehendes SYN-ACK bedeutet, dass das Paket Ihren VPS erreicht hat und vom Host verworfen wurde. Die Firewall des Providers funktioniert dann, aber Ihre lokalen Regeln nicht. Keine Ausgabe bedeutet, dass das Paket nicht angekommen ist. Ursache sind dann die Firewall des Providers, eine Security Group oder eine falsche IP-Adresse. Diese eine Unterscheidung erspart den größten Teil der Fehlersuche.
Zwei Ebenen können Ergebnisse verursachen, die unmöglich erscheinen. Erstens IPv6: Wenn der Hostname einen AAAA-Record besitzt, stellt Ihr Client möglicherweise eine Verbindung über IPv6 her, während Ihre Regel nur IPv4 abdeckt. Testen Sie daher beide Adressfamilien mit nc -4 und nc -6, bevor Sie einem der Ergebnisse vertrauen. ufw-Regeln und IPv6-Ports auf einem VPS behandelt diese Abweichung. Zweitens Docker: Ein veröffentlichter Container-Port ist aus dem Internet erreichbar, obwohl ufw status diesen Port als verweigert auflistet, weil diese Pakete verarbeitet werden, bevor sie die ufw-Kette erreichen. warum Docker Ports direkt an ufw vorbei veröffentlicht erklärt den Mechanismus und die Lösung. die ufw-Regeln für einen neuen VPS enthält den grundlegenden Regelsatz, den Sie zuerst einrichten sollten.
Warum UDP-Antworten konstruktionsbedingt nicht eindeutig sind
UDP verwendet keinen Handshake. Daher gibt es für eine Probe keinen Zustand, den sie erfolgreich erreichen kann. nc -zu 203.0.113.10 53 wird mit Exit-Code 0 beendet, sobald das Paket den Rechner verlässt. Das belegt nur, dass Ihr eigener Rechner das Paket gesendet hat. Über das entfernte Ende sagt es nichts aus. Wenn ein UDP-Port geschlossen ist, antwortet der Host normalerweise mit einer ICMP-Meldung port unreachable. Der Kernel meldet diesen Fehler einem verbundenen Socket jedoch erst beim nächsten Schreibvorgang. Eine Probe mit nur einem Paket erkennt ihn daher nicht. Firewalls verwerfen ICMP routinemäßig. Dadurch geht auch dieser Hinweis verloren. Deshalb gibt nmap für die meisten UDP-Ports open|filtered aus: Keine Antwort erzeugen sowohl ein offener, stummer Dienst als auch ein gefilterter Port.
Testen Sie UDP, indem Sie das betreffende Protokoll verwenden. Ein DNS-Server beantwortet dig +short @203.0.113.10 example.com mit einer Adresse oder gar nicht. Ein WireGuard-Peer zeigt in sudo wg show eine aktuelle Zeile mit latest handshake. Prüfen Sie anschließend den Eingang auf der Serverseite:
sudo tcpdump -ni any udp port 51820Wenn Pakete erscheinen, während der Client sendet, kommen sie an. Dann liegt das Problem beim Dienst oder in der Eingangskette. Wenn überhaupt keine Pakete erscheinen, sind sie nicht angekommen.
Eine Checkliste in der Reihenfolge, mit der Sie den Fehler am schnellsten finden
- Führen Sie auf dem Server
sudo ss -ltnp 'sport = :8080'aus. Keine Ausgabe bedeutet, dass kein Prozess auf einem Port lauscht. Beheben Sie zuerst den Dienst. - Lesen Sie bei vorhandener Ausgabe die Spalte „Local Address“.
127.0.0.1bedeutet, dass ein Zugriff von außen nicht möglich ist, bis Sie die Bind-Adresse ändern oder einen Proxy vorschalten. - Führen Sie
nc -zv -w 3 <public ip> 8080aus einem anderen Netzwerk aus. - Eine Ablehnung führt Sie zurück zu Schritt 1. Die Adresse, der Port oder der Rechner entspricht nicht Ihren Annahmen.
- Ein Timeout bedeutet, dass Pakete verworfen werden. Starten Sie auf dem Server
sudo tcpdump -ni any tcp port 8080und wiederholen Sie den Test. - Das SYN-Paket kommt an, aber es geht nichts zurück: Die Host-Firewall ist die Ursache. Suchen Sie die Regel, deren Zähler in
sudo iptables -L INPUT -n -vsteigt. - Das SYN-Paket kommt nicht an: Die Provider-Firewall, eine Security Group oder die falsche IP-Adresse ist die Ursache.
FAQ
Wie prüfe ich, welche Ports auf meinem eigenen Linux-Server geöffnet sind?
Führen Sie sudo ss -ltnp für TCP und sudo ss -lunp für UDP aus. Jede Zeile steht für einen Listening-Socket. Die Spalte Local Address zeigt, wer ihn erreichen kann: 0.0.0.0 und [::] akzeptieren Verbindungen von überall, sofern die Firewall sie zulässt. 127.0.0.1 akzeptiert nur Verbindungen vom Server selbst. Für die Spalte Process sind root-Rechte erforderlich. Führen Sie den Befehl daher mit sudo aus, andernfalls bleibt die Spalte leer. ss ist Bestandteil von iproute2 und immer installiert. netstat ist Bestandteil von net-tools und normalerweise nicht installiert.
Warum zeigt ss, dass mein Dienst auf Verbindungen wartet, obwohl ich keine Verbindung herstellen kann?
Dafür gibt es zwei häufige Ursachen. Ein Befehl unterscheidet zwischen ihnen. Wenn Local Address 127.0.0.1 lautet, ist der Dienst an loopback gebunden und von keinem anderen Host erreichbar, weil der Kernel diesen Bereich nur über das loopback-Interface routet. Wenn dort 0.0.0.0 steht und Verbindungen trotzdem fehlschlagen, führen Sie sudo tcpdump -ni any tcp port <port> auf dem Server aus und stellen Sie die Verbindung von außerhalb her. Trifft ein SYN ohne Antwort ein, verwirft eine lokale Firewall-Regel das Paket. Trifft nichts ein, wird das Paket vor Ihrem VPS angehalten, meistens durch eine Provider-Firewall oder eine Security Group.
Was ist der Unterschied zwischen einer abgelehnten Verbindung und einem Timeout?
Eine Ablehnung ist eine Antwort. Das Paket hat den Host erreicht und ein TCP-Reset oder eine ICMP-Meldung für einen nicht erreichbaren Port kam zurück. Das bedeutet, dass an dieser Adresse und diesem Port nichts lauscht oder dass eine Regel die Verbindung abgewiesen hat. Ein Timeout bedeutet Stille: Eine Regel hat das Paket verworfen und keine Antwort gesendet. Ihr Client versucht es weiter, bis er aufgibt. Bei einer Ablehnung sollten Sie den Dienst und seine Bind-Adresse prüfen. Bei einem Timeout sollten Sie die Firewall prüfen. Beginnen Sie mit der Firewall, die dem externen Netzwerk am nächsten ist.
Wie prüfe ich, ob ein UDP-Port geöffnet ist?
Mit einer allgemeinen Prüfung können Sie keine verlässliche Aussage erhalten, weil UDP keinen Handshake verwendet und ein stummer Dienst genauso aussieht wie ein verworfenes Paket. nc -zu meldet Erfolg, sobald das Paket gesendet wurde. Aus demselben Grund meldet nmap open|filtered. Testen Sie stattdessen das Protokoll selbst: dig +short @<host> example.com für DNS oder sudo wg show für einen WireGuard-Peer mit einem aktuellen Handshake. Um nachzuweisen, dass Pakete eintreffen, führen Sie sudo tcpdump -ni any udp port <port> auf dem Server aus, während der Client sendet.
Kann ich weiterhin telnet host port zum Testen eines Ports verwenden?
Für TCP funktioniert das. Escape character is '^]' bedeutet, dass die Verbindung angenommen wurde. Beenden Sie die Verbindung mit Ctrl+] und führen Sie anschließend quit aus. Zwei Gründe sprechen dafür, nc -z zu verwenden: telnet ist auf den meisten aktuellen Server-Images nicht installiert, und nc akzeptiert mit -w einen Timeout und setzt einen Exit-Status, den Sie in einem Skript prüfen können. Wenn keiner der beiden Befehle verfügbar ist, benötigen Sie für timeout 3 bash -c '</dev/tcp/<host>/<port>' kein zusätzliches Paket.