ByteScope

25

連接埠 25 · SMTP

TCPIANA 有指派郵件

伺服器對伺服器的郵件轉送連接埠——你的應用程式幾乎永遠不該撥它,而它在雲端 VM 上逾時,是供應商擋掉了,不是郵件伺服器掛了。

查出是誰占用連接埠 25

照你的系統挑一行貼上去執行。它會直接印出占著這個連接埠的行程,以及它綁在哪個位址上——通常看到這兩件事答案就出來了。

從機器外面確認一次

`nmap -Pn -p 25 mx.example.com` 告訴你,從你現在站的地方看,這個連接埠是什麼狀態。`open` 代表交握完成,`closed` 代表主機送回 reset,所以它連得到但沒有人在聽,`filtered` 代表什麼都沒回來。而在 25 這個連接埠上,`filtered` 非常常見的意思是你自己的網路擋掉了出站封包,而不是對方的郵件伺服器拒絕你——換一個網路再掃一次,再去怪對方。加 `--reason` 可以看到實際觀察到的是三者中的哪一個,加 `-sV` 會讀 SMTP banner,那通常會報出伺服器軟體,還有它自認的主機名稱。只掃你自己負責的主機。

連不上 25 的時候怎麼讀

你看到的訊息代表什麼
The send hangs, then: Connection timed out / ETIMEDOUT connecting to mx.example.com:25沒有任何東西回應那個 SYN。在雲端 VM 或家用網路上,這幾乎一定是連接埠 25 的出站封鎖,而不是目的地有問題——Google Cloud 預設就擋,消費性 ISP 也普遍在擋。驗證方法是對同一台主機試 587:如果 587 通而 25 不通,問題就在你這一側。改用 587 或 465 的認證投遞。
Connection refused connecting to mail.example.com:25主機連得到,而且它的核心主動拒絕了這條連線,所以你撥的那個位址上沒有任何 MTA 在聽。先確認你查的是網域的 MX 記錄而不是 A 記錄——網頁伺服器和郵件伺服器通常是不同主機——然後在郵件伺服器本機上跑一次探測指令。
550 5.7.1 Relaying denied / 554 5.7.1 <you@example.net>: Relay access denied這完全不是連接埠的問題。連線成功了,伺服器讀完你的信封之後才拒絕:它只收自己網域的信,不幫你轉。要嘛你找錯伺服器,要嘛你其實該用有認證的投遞連接埠。一台會這樣回答你的伺服器,正是一台沒有開放轉送的伺服器。
bind: Address already in use when starting Postfix, Exim or a test SMTP server已經有另一個郵件 daemon 占著 25 了——非常常見的情況是發行版當成相依套件裝進來、綁在回送位址上的 Postfix 或 Exim。跑探測指令,記下它的綁定位址,然後把原本那個停掉,不要硬碰硬:綁在 `0.0.0.0:25` 的監聽者會擋掉任何對特定位址的第二次綁定。
bind: Permission denied on port 25 as a normal user1024 以下是特權連接埠,所以核心在考慮任何跟郵件有關的事情之前就先回 EACCES。請用 init 系統啟動 daemon;如果只是要在本機測試一個監聽者,用 2525 這種高位連接埠,然後把用戶端指過去。
Mail is delivered but arrives unencrypted, or a STARTTLS negotiation fails mid-session25 上的 STARTTLS 天生就是機會性的:連線從明文開始,只有在伺服器宣告支援這個擴充時才升級。宣告不存在、被中途拔掉,或是憑證寄件端不接受,結果就會依寄件方的政策落在「明文送出去」或「連線中斷」兩者之一。如果保密是必要的,就用 465 的隱式 TLS——那裡在送出任何一個 SMTP 指令之前,連線就已經是加密的。

連接埠 25 上跑的是什麼

IANA 依 RFC 5321 系列把 25 指派給 `smtp`,TCP 和 UDP 都有,實際只用 TCP。RFC 5321 要求收信的郵件伺服器「隨時」在這個由 IANA 指定為 25 的連接埠上監聽。幾乎每一個串接失敗的案子都搞錯的一個分野是:25 是給誰用的。它負責的是 MTA 之間的信件傳遞,一個組織的伺服器把訊息交給另一個組織的伺服器,而不是應用程式透過供應商寄信時該用的連接埠。那件事屬於投遞連接埠——RFC 6409 登記為 `submission` 的 587,以及 RFC 8314 登記為 `submissions`、一連上就是 TLS 的 465。投遞連接埠會驗證你的身分;25 通常不會,因為寄件的那台伺服器對它來說是陌生人。25 上的加密是機會性的:RFC 3207 定義的 STARTTLS 擴充是把一條已經開著的明文連線升級上去,所以只要對方沒有宣告支援,或路徑上有裝置把那個宣告拔掉,信就以明文送出去,而且不會有任何一個地方大聲報錯。在本機這邊,占著 25 的行程通常是 Postfix 的 `master`、`exim4` 或 `sendmail`,而且很多 Linux 映像檔預設就會起一個綁在回送位址上的,純粹是為了讓 `cron` 能把輸出寄出來——那個監聽者無害,也是 `netstat` 裡那行讓人嚇一跳的常見來源。

連接埠 25 該不該對外開

這裡其實有兩個各自獨立的問題。進來的方向:除非你真的是某個網域的郵件伺服器,否則不要在 25 上開監聽。一台設定錯誤、幫任何人轉信的伺服器,幾個小時內就會被掃描器找到,接著被拿去大量發垃圾信,然後你的位址會進到那種進去很容易、出來很難的黑名單。真的要跑一台,就確認它只幫自己的網域和通過認證的使用者轉送,加上流量限制,並且發佈 SPF、DKIM 和 DMARC,讓偽造成你網域的信在別人那邊就被擋掉。出去的方向:直接假設 25 是被擋的,然後照這個前提設計。Google Cloud 白紙黑字寫著它會封鎖送往外部 IP 位址 TCP 連接埠 25 的出站封包,並註明這道封鎖不適用於內部目的地,也不適用於 465 和 587;家用 ISP 出於同樣的反垃圾信理由,擋出站 25 也擋了很多年。這就是為什麼同一支寄信程式在筆電上好好的,搬到 VM 上就永遠卡住。改用 587 或 465,帶著帳密和 TLS 走供應商出去,不要自己去撥收件方的伺服器——順便你也繼承了對方的信譽,而那才是真正決定你的信會不會被收下的東西。

服務
SMTP
傳輸協定
TCP
登記狀態
IANA 有指派
分類
郵件

站上可以搭配的工具

這些全都在你的瀏覽器裡跑,不會上傳任何東西。

相關連接埠

查 25 的時候,通常也會順手看一下這幾個。

常見問題

明明就有東西在用,指令卻什麼都沒印出來?

幾乎都是權限問題。lsofss 會列出 socket,但別人的行程它不會顯示所有者,所以由系統帳號、容器執行環境或 launchd 啟動的服務,在你補上 sudo 之前就只是一個沒有主人的監聽項。Windows 則是反過來:netstat 什麼都沒有,綁定卻還是失敗,那代表這個號碼落在 Hyper-V、WSL2 或 Docker Desktop 開機時預留的範圍裡。

占著連接埠的那個行程可以直接砍掉嗎?

先看清楚它是什麼。沒收乾淨的開發伺服器砍掉沒事;正在寫入的資料庫不行,其他東西依賴的系統服務也不行。如果持有者是容器,請停容器,不要砍主機看到的那個行程——砍了執行環境只會把它拉起來。遇到真的不能動的,把自己的服務換一個連接埠反而更快。

為什麼本機連得到,別台機器就連不到?

因為它綁在 127.0.0.1 而不是 0.0.0.0。每一頁的指令之所以會把綁定位址跟行程名一起印出來,就是為了這件事:綁在回送位址上的服務,不管防火牆怎麼設,都只有這台機器自己連得到。現在不少框架是刻意這樣預設的,所以通常是一個參數的問題,不是 bug。如果已經是 0.0.0.0 還是不通,下一個要懷疑的就是主機防火牆或雲端的安全群組。

把服務換到冷門的連接埠會比較安全嗎?

幾乎沒有幫助。掃全網的機器持續在掃整段範圍,換號碼買到的是幾個小時,不是安全,代價卻是每個同事都得記住它。它確實能讓針對預設埠的無差別掃描少污染一點日誌,這算是實際但有限的好處。真正會改變結果的是認證、限制來源位址的防火牆,以及一開始就不要讓它對外。

連接埠 25 還是卡住嗎?看完整的連接埠對照表,或是回到上面,從你實際看到的那行錯誤往回追。