Kurz gesagt: Port 80 ist der Standardport für reines HTTP und Port 443 der Standard für HTTPS, beide über TCP. Seit HTTP/3 wird Port 443 zusätzlich über UDP genutzt, für QUIC. Ein öffentlicher Webserver öffnet normalerweise TCP 80 (für die Weiterleitung und Let's-Encrypt-Prüfungen), TCP 443 für die Seite selbst und, falls er HTTP/3 anbietet, UDP 443.
| Port | Trägt | Hinweise |
|---|---|---|
| 80/TCP | HTTP, unverschlüsselt | Offen lassen für die Weiterleitung auf HTTPS und Let's-Encrypt-HTTP-01-Prüfungen |
| 443/TCP | HTTPS: HTTP/1.1 und HTTP/2 innerhalb von TLS | Die Seite selbst |
| 443/UDP | HTTP/3 über QUIC | Optional; Browser fallen bei Blockade auf TCP 443 zurück |
| 8080/TCP | HTTP-Alternative (IANA-Name http-alt) | App-Server und Proxys; Browser probieren ihn nie von selbst |
| 8443/TCP | HTTPS-Alternative, nach Konvention | Admin-Panels, Tomcat; ebenfalls kein Browser-Standard |
Eine URL ohne Port nutzt den Standard des Schemas: http://example.com bedeutet TCP 80, https://example.com bedeutet 443. Alles andere muss ausgeschrieben werden, wie in https://example.com:8443/.
Ist Port 443 TCP oder UDP?
Beides, für unterschiedliche HTTP-Versionen. HTTP/1.1 und HTTP/2 laufen über TLS auf TCP 443. HTTP/3 (RFC 9114) läuft über QUIC (RFC 9000), das auf UDP aufbaut, normalerweise auf UDP 443. Der Browser probiert UDP nicht blind aus: Erst wenn die Antwort über TCP HTTP/3 in einem Alt-Svc-Header ankündigt (oder die Domain einen HTTPS-Eintrag im DNS veröffentlicht), wechselt der Browser. Ist UDP irgendwo auf dem Weg blockiert, bleibt er bei TCP – ein geschlossenes UDP 443 kostet also nur Geschwindigkeit, nie Erreichbarkeit.
Die Ankündigung siehst du mit curl:
curl -sI https://one.one.one.oneHTTP/2 200
server: cloudflare
alt-svc: h3=":443"; ma=86400h3=":443" bedeutet „HTTP/3 ist auf UDP-Port 443 dieses Hosts verfügbar“, und ma=86400 lässt den Browser sich das einen Tag lang merken. Welche Version ein Browser tatsächlich nutzt, zeigen die Entwicklertools unter Netzwerk, Spalte Protokoll: h3 bedeutet QUIC über UDP 443, h2 bedeutet TLS über TCP 443. Ein mit HTTP/3 gebautes curl kann UDP 443 direkt auf deiner Domain testen; Debians 13 curl kann das, Debian 12 und Ubuntu 24.04 nicht – curl -V zeigt es: suche in der Features-Zeile nach HTTP3.
curl --http3-only -sI https://example.com--http3-only verbietet den Rückfall auf TCP, ein HTTP/3 200 beweist also, dass UDP 443 komplett offen ist. Ein Timeout, während dieselbe URL über TCP antwortet, heißt, etwas auf dem Weg blockiert UDP 443, oder der Server bietet es nicht an.
Was ist der Unterschied zwischen Port 80 und 443?
Das HTTP innen ist dasselbe. Auf Port 443 beginnt die Verbindung mit einem TLS-Handshake: Der Client nennt die gewünschte Seite (SNI), der Server zeigt ein Zertifikat für diesen Namen, und alles danach ist verschlüsselt. Auf Port 80 laufen Anfragen, Cookies und Formulardaten als Klartext über das Netzwerk, den jeder Router auf dem Weg lesen und ändern kann. Deshalb sollte Port 80 heute nur noch mit einer Weiterleitung auf HTTPS antworten.
Das Verwechseln erzeugt zwei gut erkennbare Fehler:
curl -s http://nginx.org:443/ | grep -o '<title>.*</title>'
curl -sS -o /dev/null https://nginx.org:80/<title>400 The plain HTTP request was sent to HTTPS port</title>
curl: (35) OpenSSL/3.0.22: error:0A00010B:SSL routines::wrong version number| Du siehst | Was passiert ist | Lösung |
|---|---|---|
400 The plain HTTP request was sent to HTTPS port | Eine http://-URL oder ein proxy_pass auf http:// zeigt auf einen TLS-Port | https:// nutzen, oder auf den reinen HTTP-Port des Backends proxyen |
SSL routines::wrong version number | Eine https://-URL zeigt auf einen Port, der reines HTTP spricht (80, oder eine App auf 3000) | http:// für diesen Port nutzen, oder TLS davor setzen |
| ERR_SSL_PROTOCOL_ERROR (engl.) | Die Browser-Version desselben Fehlers, oder ein kaputtes TLS-Setup | Port und die listen ... ssl-Zeile des Server-Blocks prüfen |
Warum Port 80 überhaupt offen lassen?
Port 80 zu schließen wirkt aufgeräumt, bricht aber zwei Dinge:
- Besucher, die über http:// ankommen. Alte Links, handgetippte Adressen und manche Clients und Bots starten noch auf Port 80. Mit geschlossenem 80 bekommen sie einen Verbindungsfehler statt einer Weiterleitung. Nach dem ersten HTTPS-Besuch überspringen Browser Port 80 wegen eines HSTS-Headers selbst.
- Die Zertifikatserneuerung. Let's Encrypts HTTP-01-Challenge, die certbot standardmäßig nutzt, verbindet sich ausschließlich über TCP-Port 80. Ein geschlossener Port 80 verhindert das.
Willst du Port 80 wirklich schließen, stelle Zertifikate über die DNS-01-Challenge aus (kein offener Port nötig; certbot hat DNS-Plugins für die großen Anbieter) oder über TLS-ALPN-01, das allein über Port 443 funktioniert, aber einen Client wie Caddy oder Traefik braucht. In jedem Fall sehen http://-Besucher dann einen Fehler.
Wie sehe ich, was auf Port 80 und 443 lauscht?
sudo ss -tlnp '( sport = :80 or sport = :443 )' # TCP
sudo ss -ulnp 'sport = :443' # UDP, für HTTP/30.0.0.0 und [::] bedeuten jede IPv4- und IPv6-Adresse, der Port ist also von außen erreichbar, wenn die Firewall es erlaubt. 127.0.0.1:443 würde nur lokale Verbindungen bedeuten. Keine Ausgabe bedeutet, es lauscht nichts, und der Browser bekommt ERR_CONNECTION_REFUSED. Dieselbe Frage mit lsof (auf einem minimalen Debian zuerst sudo apt install lsof):
sudo lsof -nP -iTCP:443 -sTCP:LISTENDie vollständigen Optionen stehen in offene Ports unter Linux prüfen (engl.).
Wie öffne ich Port 80 und 443 in der Firewall?
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp # nur wenn du HTTP/3 anbietest
sudo ufw status verboseDie Abkürzung sudo ufw allow 'Nginx Full' öffnet 80 und 443 nur über TCP. Debian 13s Nginx-Paket bringt zusätzlich ein Nginx QUIC-Profil mit, das auch UDP 443 öffnet; Debian 12 und Ubuntu 24.04 haben das nicht, füge die UDP-Regel dort von Hand hinzu.
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --permanent --add-port=443/udp # nur für HTTP/3
sudo firewall-cmd --reloadtcp dport { 80, 443 } accept
udp dport 443 acceptEine Firewall oder Security Group des Anbieters vor dem Server braucht dieselben Ports. Antwortet der Server lokal, aber nicht von außen, ist das der erste Ort zum Nachsehen.
Wie teste ich Port 80 und 443 von außen?
Führe das von deinem eigenen Rechner aus, nicht vom Server: Ein Test auf dem Server selbst läuft über das Loopback-Interface, das Firewalls durchlassen, und beweist also wenig.
curl -sI http://example.com
curl -sI https://example.comopenssl s_client -connect example.com:443 -servername example.com -brief </dev/nullTest-NetConnection example.com -Port 443Port 80 sollte mit einem 301 oder 308 auf die https://-Adresse antworten, Port 443 mit deiner Seite. Verification: OK bestätigt die Zertifikatskette, und unter Windows bestätigt TcpTestSucceeded : True, dass der Port erreichbar ist.
Ohne Terminal: Der Open-Port-Checker (engl.) testet, ob TCP 80 oder 443 auf der IP-Adresse deines Servers Verbindungen von unserem Server in Amsterdam annimmt, und der SSL-Checker (engl.) zeigt Zertifikat, Kette und TLS-Versionen auf Port 443. Keines davon kann UDP 443 testen; für HTTP/3 nutze die Protokoll-Spalte des Browsers oder curl --http3-only wie oben.
Port 80 auf 443 umleiten in Nginx
Ein Server-Block auf Port 80, der nur weiterleitet, einer auf 443, der die Seite ausliefert. Ersetze example.com durch deine Domain und die Zertifikatspfade durch deine eigenen:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# lässt certbot --webroot funktionieren, selbst wenn HTTPS kaputt ist
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
}sudo nginx -t && sudo systemctl reload nginxnginx -t prüft die Konfiguration und die Zertifikatsdateien vor dem Reload, ein Tippfehler legt die Seite also nie lahm. Für HTTP/2 auf 443 füge http2 on; zum HTTPS-Block hinzu, ab Nginx 1.25.1 (Debian 13); auf Debian 12 und Ubuntu 24.04 schreibe stattdessen listen 443 ssl http2;. Wie du das Zertifikat selbst mit certbot bekommst und zu einer App hinter Nginx proxyst, steht in der Anleitung zu Nginx als Reverse-Proxy mit SSL.
HTTP/3 auf UDP 443 mit Nginx ausliefern
Nginx unterstützt QUIC ab Version 1.25.0, wenn es mit dem Modul http_v3 gebaut ist. Debian 13 bringt 1.26 damit mit; Debian 12 (1.22) und Ubuntu 24.04 (1.24) sind zu alt dafür, die Pakete von nginx.org sind dort der übliche Weg. Füge zum HTTPS-Server-Block hinzu:
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400' always;Behalte die vorhandenen listen 443 ssl;-Zeilen: Die erste Antwort kommt immer noch über TCP und trägt den Alt-Svc-Header. Öffne danach UDP 443 wie oben gezeigt in der Firewall.
Warum kann meine App nicht an Port 80 oder 443 binden?
Unter Linux sind Ports unter 1024 privilegiert: Nur root, oder ein Prozess mit der Capability CAP_NET_BIND_SERVICE, darf sie binden. Die Grenze setzt der Sysctl-Wert net.ipv4.ip_unprivileged_port_start, standardmäßig 1024. Eine als normaler Benutzer gestartete App scheitert mit listen EACCES: permission denied 0.0.0.0:443 (Node.js) oder [Errno 13] Permission denied (Python). Nginx und Apache trifft das nicht, weil ihr Master-Prozess als root startet, die Ports bindet und seine Worker dann als unprivilegierter Benutzer laufen lässt (www-data auf Debian und Ubuntu).
Am saubersten ist, die App 443 gar nicht binden zu lassen: Lass sie auf 127.0.0.1:3000 laufen und TLS davor von Nginx beenden. Muss die App den Port selbst besitzen, gib ihrem systemd-Dienst genau diese eine Capability, statt sie als root laufen zu lassen:
[Service]
User=DEIN_APP_BENUTZER
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICEsudo systemctl restart DEINE_APP.serviceEin anderer Fehler, bind() to 0.0.0.0:80 failed (98: Address already in use), bedeutet, die Berechtigung stimmt, aber ein anderer Prozess hält den Port schon – typischerweise Apache und Nginx nebeneinander installiert, oder ein Container, der 80 veröffentlicht. Die Anleitung address already in use (engl.) findet und stoppt ihn.
Port 80 und 443 hinter Cloudflare
Ein proxyter (orange Wolke) Cloudflare-Eintrag nimmt Web-Traffic nur auf einer festen Liste von Ports an. Alles andere braucht einen DNS-only-Eintrag oder Cloudflare Spectrum.
| Traffic | Ports | Gecacht? |
|---|---|---|
| HTTP | 80, 8080, 8880, 2052, 2082, 2086, 2095 | 80 und 8080 ja; die anderen standardmäßig nicht |
| HTTPS | 443, 2053, 2083, 2087, 2096, 8443 | 443 ja; die anderen standardmäßig nicht |
- Dein Origin-Server braucht kein UDP 443. Cloudflare spricht HTTP/3 mit Besuchern, verbindet sich mit deinem Server aber über TCP; HTTP/3 zum Origin wird nicht unterstützt.
- Der SSL-Modus entscheidet den Origin-Port. Flexible verbindet sich über reines HTTP auf Port 80 mit deinem Server. Leitet dieser Server HTTP auf HTTPS weiter, läuft jede Anfrage im Kreis zu Cloudflare zurück, und der Browser gibt mit zu vielen Weiterleitungen auf. Full und Full (strict) nutzen das Schema des Besuchers.
- Erlaube Cloudflare in deiner Firewall. Blockiert die Origin-Firewall Cloudflare auf 80 oder 443, bekommen Besucher Cloudflare-Fehler 522 (engl.), einen Verbindungstimeout.
Jeder Ubuntu VPS bei VMHeaven kommt mit eigener IPv4-Adresse und vollem Root-Zugang, Port 80 und 443 sind also deine zum Öffnen; UFW ist standardmäßig aus, und die VNC-Konsole im Panel bringt dich zurück, falls eine Firewall-Regel danebengeht.
Häufige Fragen
Ist Port 443 TCP oder UDP?
Beides. HTTPS mit HTTP/1.1 und HTTP/2 läuft über TCP 443, während HTTP/3 über QUIC auf UDP 443 läuft. Der Browser probiert UDP nicht blind aus: Erst wenn der Server HTTP/3 über einen Alt-Svc-Header ankündigt, wechselt der Browser, und bei blockiertem UDP bleibt er einfach bei TCP.
Muss Port 80 offen bleiben, wenn meine Seite nur HTTPS nutzt?
In der Regel ja. Port 80 leitet Besucher weiter, die über einen http://-Link ankommen, und die HTTP-01-Challenge von Let's Encrypt verbindet sich ausschließlich über Port 80. Schließe ihn nur, wenn du Zertifikate über die DNS-01-Challenge ausstellst und akzeptierst, dass http://-Besucher einen Fehler bekommen.
Warum bekommt meine App „permission denied“, wenn sie Port 80 oder 443 öffnen will?
Unter Linux sind Ports unter 1024 privilegiert: Nur root oder ein Prozess mit der Capability CAP_NET_BIND_SERVICE darf sie binden. Starte die App auf einem hohen Port wie 3000 hinter Nginx, oder gib ihrem systemd-Dienst genau diese Capability über AmbientCapabilities=CAP_NET_BIND_SERVICE, statt sie als root laufen zu lassen.