443
HTTPS 的連接埠——而且自從 HTTP/3 之後它也是一個 UDP 連接埠,所以只查 TCP 會讓你以為沒人在聽,實際上一半的流量正被好好服務著。
照你的系統挑一行貼上去執行。它會直接印出占著這個連接埠的行程,以及它綁在哪個位址上——通常看到這兩件事答案就出來了。
sudo lsof -nP -i :443這裡刻意寫 `-i :443` 而不指定協定,好讓 TCP 和 UDP 的 socket 都出現,你才看得到 HTTP/3 的監聽者。`-n` 和 `-P` 讓主機和連接埠維持數字。協定寫在 NODE 那一欄,會是 `TCP` 或 `UDP`;TYPE 只是位址族(`IPv4` / `IPv6`),所以兩行 TYPE 都是 IPv4,仍然可以一行是 TCP 監聽、一行是 UDP 的 HTTP/3。NAME 那一欄放綁定位址——`127.0.0.1:443` 只服務本機,`*:443` 服務每一張介面。TCP 那幾行結尾是 `(LISTEN)`;UDP 那幾行沒有狀態,這是正常的。只有在你想排除已建立的用戶端連線時才加 `-sTCP:LISTEN`,而且要記得那樣也會把 UDP 整個藏起來。不加 `sudo` 的話,root 擁有的代理完全不會出現。
sudo ss -tulnp 'sport = :443'`-t` 和 `-u` 涵蓋 TCP 和 UDP,`-l` 只留監聽中的 socket,`-n` 讓連接埠維持數字,`-p` 點出持有者。同一個連接埠出現兩行,是開了 HTTP/3 的伺服器的正常樣子,不是衝突。其他事情就看位址那一欄決定:`0.0.0.0:443` 是每一張 IPv4 介面,`[::]:443` 是 IPv6 萬用位址、通常連 IPv4 也一起收,而 `127.0.0.1:443` 解釋了為什麼某個網站只有走 SSH 通道時才連得到。行程名稱長得像 `users:(("nginx",pid=1042,fd=8))`;不加 `sudo` 的話,不屬於你的那些這一欄會是空的。
sudo netstat -tulnp | grep ':443 '容器和舊映像檔用 net-tools 這個對應寫法。旗標意思相同,而最後那欄 PID/Program name 對不屬於你的 socket 需要超級使用者權限——它自己的 man page 還補了一句這個值不可信。樣式最後那個空格要留:少了它,`:443` 也會命中 `:4433`(很常見的本機 TLS 測試連接埠)和 `:44300`。
netstat -ano | findstr :443`-a` 會把監聽中的 TCP 和 UDP 連接埠都列進來,`-n` 讓它們維持數字,`-o` 在最後補上所屬 PID,再用 `tasklist /FI "PID eq 1234"` 換成名字。PID 是 4 代表核心的 HTTP.sys 驅動程式替 IIS 或其他已註冊的應用程式持有這個連接埠——用 `netsh http show servicestate` 去看,不要想辦法砍它。因為 `findstr` 比的是子字串,`:443` 也會命中 `:4433` 和 `:44300`,所以要確認 Local Address 剛好以 `:443` 結尾。
`nmap -Pn -p 443 --reason example.com` 涵蓋 TCP 那一側:`open` 代表交握完成,`closed` 代表 reset 回來了,所以主機連得到但沒有人在聽,`filtered` 代表封包消失在防火牆裡。`--reason` 會印出實際觀察到的是哪一種,而不是推論的;`-sV` 讓 nmap 談 TLS 並回報伺服器與憑證細節。要看 HTTP/3 就另外跑一次 `nmap -Pn -sU -p 443 example.com`,而且要有心理準備會拿到 `open|filtered`——UDP 的沉默天生就含糊,nmap 不會替你猜。當連接埠是開的、事情卻還是失敗,就別再掃了,改跑 `openssl s_client -connect example.com:443 -servername example.com`,它會顯示憑證鏈、談成的協定版本,以及交握到底斷在哪裡。只掃你自己負責的主機。
| 你看到的訊息 | 代表什麼 |
|---|---|
curl: (60) SSL certificate problem: unable to get local issuer certificate | 連線和交握都已經走到驗證憑證鏈那一步,所以連接埠和網路都沒問題。是伺服器沒有把它該送的中繼憑證送出來。瀏覽器常常會把這件事蓋掉,因為它從別的網站快取了中繼憑證,所以這個問題通常是先在 API 用戶端或 CI 工作裡冒出來。請去修伺服器出示的憑證鏈,不要加一個跳過驗證的旗標了事。 |
curl: (60) SSL: no alternative certificate subject name matches target host name 'example.com' | 你連到了 443 上的某台伺服器,而它回你一張別的名稱的憑證。通常是 SNI 的問題:用戶端沒有送出主機名稱,或者這個名稱根本沒設定,所以請求落到預設的虛擬主機上。用 `openssl s_client -connect <ip>:443 -servername example.com` 精確重現一次,再和不加 `-servername` 的同一個指令對照。 |
curl: (35) error:0A000410:SSL routines::sslv3 alert handshake failure | TCP 成功了,TLS 沒有。兩邊沒有任何一個可接受的協定版本或加密套件是共通的——典型情況是老用戶端碰上已經停用 TLS 1.0 和 1.1 的伺服器,或者伺服器要求用戶端憑證而對方沒有提供。連接埠不需要動,要動的是協商參數。 |
curl: (7) Failed to connect to example.com port 443: Connection refused | reset 立刻就回來了:主機活著,而且沒有東西占著連接埠 443。網頁伺服器或負載平衡器停了、只在聽連接埠 80,或是綁在回送位址上。在伺服器上跑探測指令、讀綁定位址,再去假設是防火牆的問題。 |
The browser hangs and finally shows ERR_CONNECTION_TIMED_OUT | 什麼都沒回應,所以是過濾器把封包丟掉而不是拒絕——雲端安全群組、主機防火牆,或某條網路 ACL。長時間等待就是它的特徵:被拒絕是瞬間的。請從用戶端這個方向去檢查規則,因為你這邊的一條出站規則,症狀和對方少了一條入站規則一模一樣。 |
listen EADDRINUSE :::443, or EACCES permission denied on 443 | 兩個不同的問題,訊息長得很像。EADDRINUSE 代表另一個行程占著這個連接埠——跑探測指令並讀綁定位址,因為萬用位址的監聽者會擋掉任何對特定位址的綁定。EACCES 代表這是特權連接埠:443 在 1024 以下,非特權行程在還沒檢查連接埠有沒有空著之前就被拒絕了。 |
The site loads but HTTP/3 never engages, or QUIC connections stall and fall back | TCP 443 通,UDP 443 不通。很多防火牆和安全群組是只針對 TCP 寫的,於是瀏覽器嘗試 QUIC、等待,然後退回 TCP,多出來的延遲看起來就像沒來由的變慢。在 Linux 上用 `-u` 探測,在 macOS 上不要加協定過濾條件,然後把放行或封鎖 UDP 443 當成一個刻意的決定。 |
IANA 把 `https` 登記在連接埠 443 上,TCP 和 UDP 都有,描述是「http protocol over TLS/SSL」,引用 RFC 9110。TCP 那筆是大家熟悉的:TLS 跑在 TCP 上,載著 HTTP/1.1 或 HTTP/2。UDP 那筆則是 HTTP/3 在用的,因為 QUIC 跑在 UDP 上,而且終結在同一個連接埠號上。這件事有一個大家一直踩的實際後果:一台伺服器可以在 443 上聽兩次,一種傳輸協定一次,而只過濾 TCP 的探測只看得到一半。如果瀏覽器拿得到 HTTP/3,而你的 `ss -tlnp` 輸出看起來卻不完整,加上 `-u`。傳輸層之上,443 是 TLS 發生的地方(TLS 1.3 見 RFC 8446),而讓現實世界最容易搞混的擴充是 SNI(RFC 6066):用戶端在交握裡指名它要的主機,所以一個 IP 位址、一個連接埠可以服務很多網站、很多張憑證。這就是為什麼連線在網路層成功了,拿到的卻是錯的憑證——你連對了 socket,走錯了虛擬主機。加密的 DNS 也住在這裡,也就是 DNS over HTTPS,而這是刻意的:它和一般網頁流量分不出來。這個連接埠上最好用的單一診斷工具不是掃描,而是 `openssl s_client -connect example.com:443 -servername example.com`,它會完成一次真正的交握,並印出伺服器實際送出的憑證鏈。
這是你本來就該對外開的連接埠,所以安全問題不是消失,而是往上層移動。入站這一側,風險在於它背後坐著什麼:一張過期或名稱對不上的憑證、跟正式站台共用同一個虛擬主機的管理介面、一台終結 TLS 之後把明文往你不完全信任的網段轉發的代理,或是一台同時還能從連接埠 80 碰到而且會回應的來源伺服器。憑證鏈要完整——少了中繼憑證,在會快取中繼憑證的瀏覽器上照樣能通,在每一個非瀏覽器的用戶端上卻會失敗,而那是弄壞一個 API 相當難查的方式。出站這一側則是多數政策做錯的地方:因為 443 到處都放行,它就成了通道、VPN 和 SSH-over-TLS 的預設逃生口,所以一條允許 443 到任意目的地的出站規則,實際上等於什麼都允許。在需要的地方依目的地限制出站 443;如果你的威脅模型要求,就檢查它的內容。最後,TCP 和 UDP 443 要嘛刻意都放行、要嘛刻意擋掉 UDP;把 UDP 443 留在半開狀態,會讓用戶端一再嘗試 HTTP/3、失敗、然後安靜地退回去,多出一段沒有人解釋得了的延遲。
這些全都在你的瀏覽器裡跑,不會上傳任何東西。
查 443 的時候,通常也會順手看一下這幾個。
幾乎都是權限問題。lsof 和 ss 會列出 socket,但別人的行程它不會顯示所有者,所以由系統帳號、容器執行環境或 launchd 啟動的服務,在你補上 sudo 之前就只是一個沒有主人的監聽項。Windows 則是反過來:netstat 什麼都沒有,綁定卻還是失敗,那代表這個號碼落在 Hyper-V、WSL2 或 Docker Desktop 開機時預留的範圍裡。
先看清楚它是什麼。沒收乾淨的開發伺服器砍掉沒事;正在寫入的資料庫不行,其他東西依賴的系統服務也不行。如果持有者是容器,請停容器,不要砍主機看到的那個行程——砍了執行環境只會把它拉起來。遇到真的不能動的,把自己的服務換一個連接埠反而更快。
因為它綁在 127.0.0.1 而不是 0.0.0.0。每一頁的指令之所以會把綁定位址跟行程名一起印出來,就是為了這件事:綁在回送位址上的服務,不管防火牆怎麼設,都只有這台機器自己連得到。現在不少框架是刻意這樣預設的,所以通常是一個參數的問題,不是 bug。如果已經是 0.0.0.0 還是不通,下一個要懷疑的就是主機防火牆或雲端的安全群組。
幾乎沒有幫助。掃全網的機器持續在掃整段範圍,換號碼買到的是幾個小時,不是安全,代價卻是每個同事都得記住它。它確實能讓針對預設埠的無差別掃描少污染一點日誌,這算是實際但有限的好處。真正會改變結果的是認證、限制來源位址的防火牆,以及一開始就不要讓它對外。
連接埠 443 還是卡住嗎?看完整的連接埠對照表,或是回到上面,從你實際看到的那行錯誤往回追。