網(wǎng)郵件服務(wù)器部署與收發(fā)驗(yàn)證)
簡介Foxmail Server For Windows v2.0 公測版面向需要搭建內(nèi)部郵件系統(tǒng)或驗(yàn)證郵件服務(wù)功能的技術(shù)人員提供SMTP、POP3、LDAP及MIME郵件擴(kuò)展支持既可通過Foxmail、Outlook Express等客戶端收發(fā)郵件也能在全中文Web界面中登錄處理郵件管理員還可基于瀏覽器完成日常維護(hù)。該測試包共2個(gè)文件包含1個(gè)exe安裝程序和1個(gè)htm說明文檔壓縮包約7.9MB安裝與配置門檻較低。已有286人學(xué)習(xí)或下載適合用于單機(jī)郵件服務(wù)實(shí)驗(yàn)、局域網(wǎng)內(nèi)部郵件傳輸驗(yàn)證以及Web郵件界面體驗(yàn)。其描述中提到的多線程、異步Socket、緩存與快速隊(duì)列機(jī)制可幫助讀者觀察郵件投遞和內(nèi)部大文件傳輸?shù)谋憩F(xiàn)產(chǎn)品號ST-TEST、8用戶限制及不提供注冊與技術(shù)支持等說明也便于在測試前明確授權(quán)邊界。整體上適合作為郵件服務(wù)器入門實(shí)踐和功能核驗(yàn)的參考材料。1. 一臺斷網(wǎng)舊機(jī)器上的郵件服務(wù)器Foxmail Server v2.0 公測版值不值得拆手里有業(yè)務(wù)系統(tǒng)要發(fā)通知郵件又不想把測試流量打到公網(wǎng)郵箱上最省事的做法是在一臺 Windows 機(jī)器上架個(gè)郵件服務(wù)器。Foxmail Server for Windows v2.0 公測版就是這種老物件純 Windows 服務(wù)形態(tài)自帶 SMTP、POP3 和 Webmail支持多域名、多賬號和圖形化管理臺裝完能在內(nèi)網(wǎng)跑出一套完整的收發(fā)閉環(huán)。它扛不住公網(wǎng)生產(chǎn)流量也缺少現(xiàn)代反垃圾和 TLS 能力但拿來做內(nèi)網(wǎng)郵件中繼、業(yè)務(wù)系統(tǒng)發(fā)信沙箱、老客戶端兼容驗(yàn)證是成本最低的一檔選擇。下面按部署順序拆從端口規(guī)劃一路寫到腳本驗(yàn)證能照著復(fù)現(xiàn)。2. 裝之前先探地基25/110/143 端口、域名與目錄規(guī)劃郵件服務(wù)器這類軟件最怕的不是裝不上而是裝上了、服務(wù)也起來了結(jié)果端口被別的程序先占了或者域名解析沒配對客戶端連上去提示“無法連接服務(wù)器”然后開始懷疑人生。這一章把安裝前必須確認(rèn)的三件事說清楚端口歸誰、域名怎么解析、文件落到哪個(gè)盤。順序不能反反了就要返工。2.1 端口清單與占用排查先把 25 和 110 搶回來這套服務(wù)端是典型的“一進(jìn)程多端口”結(jié)構(gòu)安裝完成后會(huì)常駐監(jiān)聽幾個(gè)固定端口。常見做法是先跑一遍端口體檢再動(dòng)手安裝。Windows 上最順手的是netstat配findstr不用裝任何額外工具。echo off REM 逐個(gè)檢查郵件服務(wù)要用的端口是否已被占用 for %%P in (25 110 143 80) do ( netstat -ano | findstr /R /C::%%P .*LISTENING nul if errorlevel 1 ( echo PORT %%P FREE ) else ( echo PORT %%P BUSY REM 打印占用該端口的進(jìn)程 PID方便后面 tasklist 定位 netstat -ano | findstr /R /C::%%P .*LISTENING ) )這段批處理只做一件事對每個(gè)端口判斷netstat輸出里有沒有LISTENING行有就說明被占用并把 PID 打出來接著用tasklist /FI PID eq 1234查是誰。邏輯說明兩句findstr /R /C:是把整段當(dāng)正則匹配冒號加端口號能避免 2510、1100 這類端口被誤判nul只是屏蔽輸出errorlevel仍然有效。參數(shù)上要注意的是端口用途本身端口協(xié)議用途常見沖突對象25SMTP投遞與接收郵件Windows 自帶 SMTP 服務(wù)、殺毒軟件郵件防護(hù)110POP3客戶端收信其他郵件服務(wù)端、部分備份軟件143IMAP客戶端同步若啟用極少?zèng)_突但要注意防火墻80HTTPWebmail 與管理臺IIS、Apache、各類本地調(diào)試服務(wù)如果 25 被占用優(yōu)先去“服務(wù)”里把 Windows 自帶的 SMTP 關(guān)掉而不是改 Foxmail Server 的端口。原因很實(shí)際改端口之后任何往這臺機(jī)器投遞的第三方系統(tǒng)都得跟著改配置一旦有系統(tǒng)寫死了 25你就得回頭去改對方成本翻倍。反過來80 端口沖突可以放心改管理臺端口因?yàn)?Webmail 只影響人不影響機(jī)器之間的投遞。2.2 域名與解析內(nèi)網(wǎng)自建不必碰公網(wǎng) DNS單機(jī)自建最容易翻車的地方是域名。很多教程默認(rèn)你有一個(gè)公網(wǎng)域名配 MX 記錄指向本機(jī)公網(wǎng) IP。內(nèi)網(wǎng)測試場景完全不需要這么干常見做法是造一個(gè)僅內(nèi)網(wǎng)可見的域名比如test.local、corp.internal然后靠內(nèi)網(wǎng) DNS 或 hosts 文件解析。判斷標(biāo)準(zhǔn)很簡單如果收件人只在本機(jī)或內(nèi)網(wǎng)走 hosts 就夠了如果內(nèi)網(wǎng)有多臺機(jī)器要訪問就交給內(nèi)網(wǎng) DNS 服務(wù)器加一條 A 記錄和一條 MX 記錄。hosts 方案在 Windows 上的路徑是C:\Windows\System32\drivers\etc\hosts加一行# 內(nèi)網(wǎng)郵件域名解析IP 換成你機(jī)器的實(shí)際內(nèi)網(wǎng)地址 192.168.10.21 mail.test.local加完之后用ping mail.test.local驗(yàn)證回顯里的 IP 必須是 192.168.10.21不是 127.0.0.1。為什么強(qiáng)調(diào)這一點(diǎn)如果客戶端解析到 127.0.0.1而客戶端本身在另一臺機(jī)器上那它連的是自己本機(jī)的回環(huán)地址永遠(yuǎn)連不上服務(wù)端報(bào)錯(cuò)卻是“連接被拒絕”很容易誤判成服務(wù)沒啟動(dòng)。多域名是這套服務(wù)端的一個(gè)實(shí)用點(diǎn)可以同時(shí)托管test.local和dev.internal賬號按“用戶名域名”隔離。配多域名時(shí)每個(gè)域名都要單獨(dú)加解析記錄別指望一條泛解析通吃——MX 記錄不支持通配符這是很多人第一次配置就卡住的原因。提示內(nèi)網(wǎng)自建不要給這個(gè)域名配公網(wǎng) MX否則一旦有郵件誤投到公網(wǎng)退信會(huì)繞一大圈才回到你手上排查成本極高。2.3 安裝路徑與服務(wù)啟動(dòng)避開中文和空格安裝路徑這條是老生慈悲的血淚經(jīng)驗(yàn)一定不要放在帶中文或空格的目錄下。這類 2000 年代前后的 Windows 程序內(nèi)部大量拼字符串路徑遇到空格就斷遇到中文就亂碼表現(xiàn)出來是“服務(wù)能啟動(dòng)但郵件存不進(jìn)去”或者“附件下載 0 字節(jié)”。我一般會(huì)固定成D:\MailSrv\這種短路徑并把三塊內(nèi)容分開規(guī)劃目錄內(nèi)容規(guī)劃建議程序目錄可執(zhí)行文件、DLL、配置單獨(dú)盤符或系統(tǒng)盤固定路徑重裝時(shí)保留配置郵件存儲(chǔ)用戶郵箱、附件獨(dú)立數(shù)據(jù)盤預(yù)留 2 倍于預(yù)估容量的空間日志目錄SMTP/POP3 會(huì)話日志單獨(dú)目錄方便按天清理裝完之后不要急著開客戶端先在“服務(wù)”里確認(rèn)服務(wù)狀態(tài)。命令行方式REM 列出所有服務(wù)名里帶 mail 的項(xiàng)確認(rèn)安裝后的真實(shí)服務(wù)名 sc query type service state all | findstr /I mail REM 啟動(dòng)并設(shè)為自啟服務(wù)名以實(shí)際顯示為準(zhǔn) sc config 你的服務(wù)名 start auto net start 你的服務(wù)名sc config里start后面必須有一個(gè)空格這是sc命令的語法要求寫成startauto會(huì)直接報(bào)參數(shù)錯(cuò)誤。把服務(wù)設(shè)成自啟這一步別省否則機(jī)器重啟一次、郵件鏈路就斷一次等到業(yè)務(wù)系統(tǒng)告警說發(fā)不出郵件你才會(huì)想起來。3. 域、賬號與郵箱存儲(chǔ)把用戶體系一次搭對裝好能跑只是及格線真正決定這套東西好不好用的是賬號體系。郵箱賬號一旦建錯(cuò)命名規(guī)則后面遷移、備份、批量導(dǎo)入全是連鎖反應(yīng)。這一章講三件事域和賬號怎么命名、存儲(chǔ)和配額怎么留余量、批量建號怎么不靠手抖。3.1 域名與賬號命名保留名、大小寫與地址規(guī)范第一步是在管理臺里建域域名的寫法要和 DNS 解析完全一致大小寫不敏感但建議統(tǒng)一小寫避免日志里一會(huì)兒Test.Local一會(huì)兒test.localgrep 的時(shí)候抓不全。第二步是建賬號。這里有幾條硬規(guī)則值得先說清楚postmaster域名和admin域名屬于保留地址幾乎所有郵件系統(tǒng)都會(huì)往這兩個(gè)地址投遞退信和濫用報(bào)告必須建出來并且定期看。用戶名只保留小寫字母、數(shù)字、點(diǎn)、下劃線、短橫線別用中文、別用空格。中文用戶名在 SMTP 信封里需要編碼這套老服務(wù)端的處理不一定完整容易在某個(gè)客戶端上炸開。用戶名長度控制在 32 字符以內(nèi)太長的地址在部分老客戶端里會(huì)被截?cái)啾憩F(xiàn)出來的現(xiàn)象是“收件人地址無效”但你在管理臺里看地址明明是對的。很多人的習(xí)慣是用工號或者姓名拼音做賬號前者穩(wěn)定但沒人記得住后者好記但重名率高。我的做法是“姓名拼音 序號”同時(shí)把真實(shí)姓名寫進(jìn)賬號的顯示名和描述字段這樣管理臺里搜中文也能搜到人。3.2 存儲(chǔ)、配額與磁盤余量別讓一個(gè)附件撐爆整臺機(jī)器郵箱存儲(chǔ)這塊最容易埋雷。這套服務(wù)端的郵件基本是按用戶目錄或單文件落盤的形態(tài)單個(gè)大附件進(jìn)來磁盤曲線是陡的。上生產(chǎn)前至少算一遍容量預(yù)估容量 賬號數(shù) × 平均配額 × 1.5冗余系數(shù) 日志日增量 × 保留天數(shù)舉個(gè)具體的50 個(gè)賬號、平均配額 200MB主體就是 10GB乘 1.5 是 15GB加上日志按每天 200MB、保留 30 天算 6GB總共 21GB那就給它劃 40GB 的獨(dú)立分區(qū)留出一倍余量。配額設(shè)置上有兩個(gè)參數(shù)值得關(guān)注單賬號郵箱上限和單封郵件大小上限。后者常被忽略但如果業(yè)務(wù)系統(tǒng)會(huì)發(fā)帶報(bào)表的郵件附件很容易到 10MB、20MB超限之后 SMTP 會(huì)話會(huì)在DATA階段直接被拒返回 552 之類的錯(cuò)誤碼。這個(gè)報(bào)錯(cuò)在業(yè)務(wù)系統(tǒng)那邊通常只顯示“發(fā)送失敗”不會(huì)有細(xì)節(jié)所以上線前一定要把單封上限調(diào)到業(yè)務(wù)峰值之上或者干脆讓業(yè)務(wù)系統(tǒng)改成發(fā)下載鏈接。注意配額不是設(shè)完就完事要定期看存儲(chǔ)目錄的實(shí)際增長。老服務(wù)端不一定有容量告警功能磁盤滿了之后最先壞的是收信發(fā)信可能還能撐一陣等你發(fā)現(xiàn)的時(shí)候已經(jīng)丟了一批郵件。3.3 批量建號先校驗(yàn) CSV再進(jìn)管理臺賬號一多手工錄入必然出錯(cuò)。穩(wěn)妥的流程是維護(hù)一份 CSV 賬號表先用腳本做規(guī)則校驗(yàn)校驗(yàn)通過再按表錄入或?qū)?。CSV 的字段就四個(gè)賬號、域名、顯示名、配額MB。# check_accounts.py 賬號表規(guī)則校驗(yàn)跑完再進(jìn)管理臺錄入 import csv import re # 賬號規(guī)則小寫字母或數(shù)字開頭允許 . _ -長度 2~32 RULE re.compile(r^[a-z0-9][a-z0-9._-]{1,31}$) seen set() with open(accounts.csv, newline, encodingutf-8-sig) as f: for line_no, row in enumerate(csv.DictReader(f), start2): name (row.get(account) or ).strip().lower() domain (row.get(domain) or ).strip().lower() quota int((row.get(quota_mb) or 100).strip()) if not RULE.match(name): print(f[行{line_no}] 賬號非法{name}) continue if not domain or in domain: print(f[行{line_no}] 域名非法{domain}) continue if name in (admin, postmaster, root): print(f[行{line_no}] 保留名需人工確認(rèn){name}) continue if quota 0 or quota 2048: print(f[行{line_no}] 配額越界{quota}MB) continue key f{name}{domain} if key in seen: print(f[行{line_no}] 重復(fù)賬號{key}) continue seen.add(key) print(f校驗(yàn)完成有效賬號 {len(seen)} 個(gè))邏輯說明分三層。第一層是正則^[a-z0-9]強(qiáng)制首字符不能是點(diǎn)或短橫線這是 RFC 里地址本地部分的基本約束很多客戶端不校驗(yàn)但服務(wù)端會(huì)拒。第二層是保留名判定遇到admin、postmaster不直接判錯(cuò)而是提示人工確認(rèn)因?yàn)榇_實(shí)可能出現(xiàn)admintest.local這種有意為之的地址。第三層是去重key 用完整地址而不是用戶名因?yàn)槎嘤蛎麍鼍跋聑hangsantest.local和zhangsandev.internal是兩個(gè)合法賬號。參數(shù)上encodingutf-8-sig是為了兼容 Excel 另存的帶 BOM 的 CSV不帶 sig 的話第一列字段名前面會(huì)多一個(gè)不可見字符row[account]直接 KeyError這個(gè)坑我踩過一次排查了半小時(shí)。newline是 csv 模塊的官方建議不加的話在 Windows 上可能出現(xiàn)空行錯(cuò)位。校驗(yàn)跑完沒問題再拿著 CSV 去管理臺錄入或走導(dǎo)入功能。錄完記得抽查三個(gè)賬號發(fā)一封帶中文附件的郵件、發(fā)一封超過 5MB 的郵件、發(fā)一封收件人填錯(cuò)的郵件看退信有沒有回到 postmaster。4. 收發(fā)閉環(huán)驗(yàn)證telnet 手工握手與 smtplib/poplib 腳本客戶端彈窗說“無法連接”時(shí)你無法判斷是網(wǎng)絡(luò)問題、端口問題、認(rèn)證問題還是服務(wù)端根本沒起來。分層驗(yàn)證的價(jià)值就在這里先用 telnet 打通 TCP 和 SMTP 協(xié)議層再用腳本驗(yàn)證應(yīng)用層的編碼和投遞最后才輪到客戶端。這個(gè)順序能把 80% 的問題定位在某一段而不是全靠猜。4.1 telnet 手工握手一條命令一個(gè)返回碼Windows 默認(rèn)可能沒裝 telnet 客戶端在“啟用或關(guān)閉 Windows 功能”里勾上就行或者直接用 PowerShell 的Test-NetConnection先探端口。# 第一步只探端口通不通 Test-NetConnection 192.168.10.21 -Port 25 # 第二步進(jìn) SMTP 會(huì)話逐行敲看返回碼 telnet 192.168.10.21 25進(jìn)去之后按這個(gè)順序敲每一行的返回碼都要對上220 mail.test.local ESMTP Service ready EHLO test.local 250-mail.test.local 250-SIZE 20971520 250 8BITMIME MAIL FROM:sendertest.local 250 OK RCPT TO:receivertest.local 250 OK DATA 354 Start mail input; end with CRLF.CRLF Subject: telnet test From: sendertest.local To: receivertest.local hello from telnet . 250 OK: queued QUIT 221 Bye關(guān)鍵判斷點(diǎn)有三個(gè)。220是服務(wù)端的歡迎橫幅收不到說明端口沒通或服務(wù)沒起。EHLO的返回里如果列出了SIZE和8BITMIME說明服務(wù)端聲明了自己的能力邊界后面發(fā)大附件和中文內(nèi)容就有依據(jù)。最后DATA結(jié)束必須是一個(gè)單獨(dú)成行的英文句點(diǎn)很多人手敲時(shí)在句點(diǎn)后面多打了空格服務(wù)端會(huì)認(rèn)為正文沒結(jié)束會(huì)話就那么卡著表象是“telnet 定住了”。如果MAIL FROM返回 550 或 553通常是發(fā)件地址的域名不在服務(wù)端托管的域列表里需要回管理臺加域而不是去改客戶端。如果RCPT TO返回 550多半是賬號不存在或者被禁用先確認(rèn)賬號拼寫。4.2 Python 腳本驗(yàn)證把發(fā)信和收信都寫成可重跑的用例telnet 適合定位不適合回歸。每次改完配置都要重敲一遍命令效率太低。寫兩個(gè)小腳本一個(gè)發(fā)一個(gè)收出問題直接看 debug 輸出。# send_test.py SMTP 發(fā)信驗(yàn)證打開 debuglevel 能看到完整會(huì)話 import smtplib from email.mime.text import MIMEText from email.header import Header HOST, PORT 192.168.10.21, 25 msg MIMEText(這是一封來自內(nèi)網(wǎng)測試的中文正文用于驗(yàn)證 8bit 編碼。, plain, utf-8) msg[Subject] Header(SMTP 連通性驗(yàn)證, utf-8) msg[From] sendertest.local msg[To] receivertest.local try: with smtplib.SMTP(HOST, PORT, timeout10) as s: s.set_debuglevel(1) # 打印 C/S 全部交互排錯(cuò)時(shí)開日常關(guān)掉 code, resp s.ehlo(test.local) print(EHLO:, code, resp.decode(utf-8, ignore)) s.sendmail(msg[From], [msg[To]], msg.as_string()) print(send ok) except smtplib.SMTPException as e: print(SMTP 失敗:, type(e).__name__, e)逐行說明。MIMEText(..., utf-8)指定字符集Header(..., utf-8)保證主題里的中文按 RFC 2047 編碼成?utf-8?b?...?不寫這一句收件端看到的主題就是一串亂碼。set_debuglevel(1)是這套腳本的核心它會(huì)把send:和reply:兩個(gè)方向的內(nèi)容全部打到標(biāo)準(zhǔn)輸出服務(wù)端返回的每一個(gè)錯(cuò)誤碼都能看見比看客戶端彈窗有用得多。timeout10必須給否則網(wǎng)絡(luò)不通時(shí)會(huì)卡到系統(tǒng)默認(rèn)超時(shí)腳本看起來像死掉。sendmail的第一個(gè)參數(shù)是信封發(fā)件人和msg[From]是兩回事。老服務(wù)端上這兩個(gè)不一致時(shí)可能被拒所以腳本里保持一致最省事。收信腳本用 POP3重點(diǎn)是解碼附件名和正文編碼# recv_test.py POP3 收信驗(yàn)證檢查主題與正文是否正確解碼 import poplib from email.parser import Parser from email.header import decode_header HOST, PORT 192.168.10.21, 110 USER, PWD receivertest.local, your-password p poplib.POP3(HOST, PORT, timeout10) p.user(USER) p.pass_(PWD) count, total_size p.stat() print(f共 {count} 封占用 {total_size} 字節(jié)) if count: resp, lines, octets p.retr(count) # 取最新一封 raw b\r\n.join(lines) msg Parser().parsestr(raw.decode(utf-8, ignore)) subject_parts decode_header(msg[Subject] or ) subject .join( part.decode(enc or utf-8, ignore) if isinstance(part, bytes) else part for part, enc in subject_parts ) print(主題:, subject) print(正文前 100 字:, msg.get_payload()[:100]) p.quit()retr(count)取最后一封因?yàn)?POP3 的序號是按投遞順序遞增的。decode_header返回的是(內(nèi)容, 編碼)元組列表混合編碼的郵件會(huì)拆成多段所以要循環(huán)拼接不能只取第一段。p.quit()不能少POP3 會(huì)話里QUIT才真正提交刪除標(biāo)記直接斷開會(huì)話可能導(dǎo)致郵件被鎖住一段時(shí)間。這兩個(gè)腳本跑通說明 SMTP 投遞、POP3 取信、中文編碼三條鏈路都是通的剩下的問題基本只在客戶端配置和網(wǎng)絡(luò)策略層面。4.3 客戶端參數(shù)表老服務(wù)端的認(rèn)證和加密要手動(dòng)關(guān)最后一步是客戶端。這類 2000 年代前后的 Windows 郵件服務(wù)端普遍不帶 SSL/TLS也不支持 STARTTLS客戶端要顯式關(guān)掉加密否則會(huì)卡在“正在連接”然后超時(shí)。配置項(xiàng)填寫值說明收件服務(wù)器類型POP3若啟用 IMAP 則選 IMAP收件服務(wù)器mail.test.local 或內(nèi)網(wǎng) IP與 hosts / DNS 解析一致收件端口110不帶加密發(fā)件服務(wù)器同上與收件服務(wù)器一致發(fā)件端口25不帶加密用戶名完整郵箱地址部分客戶端只填前綴會(huì)認(rèn)證失敗密碼賬號密碼—身份驗(yàn)證勾選“我的發(fā)送服務(wù)器要求驗(yàn)證”不勾會(huì)被當(dāng)開放中繼拒掉加密連接無 / 關(guān)閉老版本無 TLS 支持配置完先發(fā)一封給自己再發(fā)一封給同域另一個(gè)賬號最后從外部系統(tǒng)發(fā)一封進(jìn)來。三個(gè)方向都通才算真正跑完閉環(huán)。5. 避坑與排查五條裝完才發(fā)現(xiàn)的坑5.1 現(xiàn)象服務(wù)顯示運(yùn)行中客戶端連不上原因通常是監(jiān)聽地址綁定問題。部分老版本默認(rèn)只監(jiān)聽某一個(gè)網(wǎng)卡地址機(jī)器換了網(wǎng)段或者加了第二塊網(wǎng)卡之后綁定的還是舊地址服務(wù)狀態(tài)是“正在運(yùn)行”但新地址上根本沒監(jiān)聽。解決方式是回到配置里確認(rèn)監(jiān)聽地址改成0.0.0.0或明確指定當(dāng)前內(nèi)網(wǎng) IP改完重啟服務(wù)再用netstat -ano | findstr :25確認(rèn)真實(shí)監(jiān)聽的是哪個(gè)地址。判斷依據(jù)很直接0.0.0.0:25是全接口192.168.10.21:25是單接口127.0.0.1:25就只本機(jī)能連。5.2 現(xiàn)象中文附件變成一串亂碼文件名原因是編碼聲明不完整。發(fā)信端用了 UTF-8 正文但附件名按 GBK 編碼收信端按聲明的字符集解碼就對不上。老服務(wù)端在轉(zhuǎn)存時(shí)可能還會(huì)二次處理問題更明顯。解決方式是統(tǒng)一編碼口徑發(fā)信端腳本里顯式指定charsetutf-8主題用Header(..., utf-8)附件名也用Header包一層客戶端如果支持編碼設(shè)置把默認(rèn)編碼固定成 UTF-8。驗(yàn)證方法就是 4.2 節(jié)的收信腳本看解碼出來的主題和文件名是否正常不看客戶端因?yàn)椴煌蛻舳巳蒎e(cuò)能力不一樣會(huì)掩蓋問題。5.3 現(xiàn)象內(nèi)網(wǎng)互發(fā)正常發(fā)到外部郵箱全部退信原因是公網(wǎng)投遞需要反向解析和發(fā)信域授權(quán)而內(nèi)網(wǎng)自建這套東西根本沒有。對方郵件系統(tǒng)收到一封來自無 PTR 記錄 IP 的郵件直接判定為可疑來源拒收返回 550 或 554。解決方式不是去補(bǔ) PTR而是壓根別讓這臺機(jī)器直接往公網(wǎng)發(fā)。正確做法是把它配成中繼模式所有出站郵件轉(zhuǎn)發(fā)給一個(gè)可信的上游 SMTP 服務(wù)由上游完成公網(wǎng)投遞。如果確實(shí)需要直發(fā)那就要有固定公網(wǎng) IP、PTR 記錄和 SPF 記錄成本比中繼高得多。提示測試階段如果一定要驗(yàn)證外發(fā)先拿自己的外部郵箱試別拿客戶郵箱試退信多了會(huì)影響域聲譽(yù)。5.4 現(xiàn)象跑一段時(shí)間后磁盤告警收信開始報(bào)錯(cuò)原因是日志和隊(duì)列堆積。SMTP 會(huì)話日志默認(rèn)可能不做輪轉(zhuǎn)一天幾百 MB幾個(gè)月就是幾十 GB隊(duì)列目錄里如果有投遞失敗的郵件會(huì)一直重試一直占空間。解決方式是三件事同時(shí)做日志目錄按天切分并設(shè)置保留天數(shù)隊(duì)列目錄定期檢查有沒有長期滯留的文件監(jiān)控磁盤使用率設(shè) 80% 告警。別等爆了才清理磁盤滿了之后服務(wù)端的表現(xiàn)通常不是優(yōu)雅報(bào)錯(cuò)而是寫文件失敗、郵件丟失。5.5 現(xiàn)象重啟機(jī)器后服務(wù)不自啟業(yè)務(wù)方第二天才發(fā)現(xiàn)原因是服務(wù)啟動(dòng)類型是“手動(dòng)”或者服務(wù)依賴項(xiàng)沒起來導(dǎo)致啟動(dòng)失敗。這類老服務(wù)有時(shí)候依賴 Winsock 或某個(gè)系統(tǒng)組件啟動(dòng)順序不對就會(huì)失敗一次。解決方式是把啟動(dòng)類型設(shè)為自動(dòng)同時(shí)在服務(wù)屬性里配好失敗恢復(fù)策略第一次失敗重啟服務(wù)第二次失敗重啟服務(wù)后續(xù)失敗就發(fā)告警。命令行配置見 2.3 節(jié)的sc config。另外建議加一條定時(shí)探測每分鐘連一次 25 端口連不上就告警別依賴用戶反饋。6. 進(jìn)階用法當(dāng)中繼、做冷備與上線前自檢這套服務(wù)端真正的價(jià)值不在“給人收發(fā)郵件”而在“給機(jī)器收發(fā)郵件”。把它降級成一個(gè)內(nèi)網(wǎng) SMTP 中繼業(yè)務(wù)系統(tǒng)只認(rèn)這一個(gè)出口后面換郵件網(wǎng)關(guān)、加審計(jì)、做灰度都只需要改一處。具體配置思路是服務(wù)端只托管內(nèi)網(wǎng)域所有非本地域的收件人地址統(tǒng)一轉(zhuǎn)發(fā)到一個(gè)上游 SMTP同時(shí)把“允許中繼”的網(wǎng)段限制成業(yè)務(wù)系統(tǒng)的 IP 段別開成全網(wǎng)段否則就是給自己造了個(gè)開放中繼內(nèi)網(wǎng)里隨便一臺機(jī)器都能借你發(fā)垃圾郵件很快就會(huì)被上游封掉。判斷中繼有沒有配對不看配置文件看會(huì)話日志。業(yè)務(wù)系統(tǒng)發(fā)一封到外部地址日志里應(yīng)該出現(xiàn)兩條記錄一條是接收一條是轉(zhuǎn)發(fā)兩條的 Message-ID 一致。只有一條說明轉(zhuǎn)發(fā)沒生效郵件還在本地隊(duì)列里排隊(duì)重試。6.1 冷備與遷移整目錄搬 賬號表對照備份這件事我的做法是“冷備整目錄 單獨(dú)存賬號表”。停服務(wù)、拷貝程序目錄和郵件存儲(chǔ)目錄、拷一份賬號 CSV、啟動(dòng)服務(wù)四步。不停服務(wù)直接拷文件在這種老程序上風(fēng)險(xiǎn)很高因?yàn)閷懕P過程中拷貝出來的郵件文件可能只有半個(gè)恢復(fù)時(shí)那封信就是損壞的而且不會(huì)報(bào)錯(cuò)只會(huì)在客戶端點(diǎn)開時(shí)顯示空白。遷移到新機(jī)器時(shí)賬號表是唯一的對照依據(jù)。新機(jī)器裝完、建好域、把賬號表導(dǎo)進(jìn)去再把郵件目錄按相同路徑放回去最后抽查五個(gè)賬號一個(gè)空郵箱、一個(gè)有大量郵件的、一個(gè)有超大附件的、一個(gè)禁用狀態(tài)的、一個(gè) postmaster。五個(gè)都對上遷移才算完成。6.2 上線前的六條自檢檢查項(xiàng)判定標(biāo)準(zhǔn)端口25/110 處于 LISTENING且綁定地址正確服務(wù)自啟重啟一次機(jī)器服務(wù)自動(dòng)起來DNS 解析客戶端機(jī)器上 ping 域名返回內(nèi)網(wǎng) IP反向路徑從業(yè)務(wù)系統(tǒng)發(fā)一封到本地賬號能收到編碼中文主題、中文正文、中文附件名三項(xiàng)都正常容量磁盤剩余空間大于預(yù)估容量的一倍這張表我每次部署都會(huì)過一遍把它貼在部署文檔第一頁。血淚經(jīng)驗(yàn)是編碼和容量這兩項(xiàng)最容易被跳過也最容易在上線一周后集中爆發(fā)。從那以后我每次動(dòng)這類老郵件服務(wù)都強(qiáng)制先跑一遍 telnet 手工握手再動(dòng)客戶端配置——先確認(rèn)協(xié)議層是活的再去懷疑應(yīng)用層這個(gè)順序救過我很多次。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取