Azure 本身並不提供傳統意義上的「開放式 SMTP 伺服器」,但有三種主要方式可以達成 SMTP 寄信需求:
Azure Communication Services (ACS)
這是目前 Azure 原生的推薦方案。它提供 Email 服務,且支援 SMTP Relay 功能。
- 特點:按量計費,整合在 Azure 資源管理內,安全性高。
- 認證方式:支援透過 Entra ID (原 Azure AD) 的應用程式註冊與 Service Principal 進行認證。
- 連線資訊:伺服器通常為
smtp.azurecomm.net,使用連接埠 587。
Twilio SendGrid
長期以來 Azure 官方合作的第三方服務,在 Azure 市集中可以直接購買與整合。
- 特點:功能最成熟,有豐富的報表、開信追蹤與行銷工具。
- 適用場景:除了簡單的系統通知,還需要處理電子報或進階郵件管理時的首選。
- 連線資訊:伺服器為
smtp.sendgrid.net,使用 API Key 作為認證密碼。
Microsoft 365 (Exchange Online)
如果你公司本身有在使用 Microsoft 365,也可以透過 Exchange Online 寄信。
- 注意事項:微軟正在全面停用 SMTP 的「基本驗證」(Basic Auth),到 2026 年底後,傳統的帳號密碼登入將失效,必須改用 OAuth 2.0。
- 限制:有每日寄信限額,且不適合發送大量行銷郵件,較適合內部系統或小量自動化腳本。
關鍵技術限制與建議
- 封鎖 Port 25:Azure 所有的虛擬主機 (VM) 預設都會封鎖對外的 Port 25,以防垃圾郵件。請務必改用 Port 587 (TLS)。
- 固定 IP 信用度:不建議在 VM 內自建 SMTP 伺服器直接對外寄信,因為雲端 IP 很容易被列入黑名單,寄達率極低。
- 首選建議:如果你追求純 Azure 環境與簡單的系統通知,優先考慮 Azure Communication Services;如果需要強大的退信分析與行銷功能,選擇 SendGrid。
要在 Exchange Online 使用 SMTP 寄信,由於微軟已經全面停用基本驗證,目前的標準做法是透過 Azure 註冊應用程式並使用 OAuth 2.0。以下是開發者最常用的用戶端憑證流程步驟:
1. 在 Microsoft Entra ID 註冊應用程式
首先要在 Azure 入口網站建立一個身份,讓系統允許你的程式存取 Exchange Online。
- 進入 Azure Portal,搜尋並進入 Microsoft Entra ID。
- 點選 應用程式註冊,新增一個註冊。
- 記下 應用程式 (用戶端) 識別碼 以及 目錄 (租戶) 識別碼,稍後程式碼會用到。
- 在 憑證與密碼 中,新增一個 用戶端密碼,產生的數值請立即複製儲存,離開頁面後就看不到了。
2. 設定 API 權限
賦予這個應用程式寄信的權利。
- 在應用程式註冊頁面點選 API 權限。
- 點選 新增權限,選擇 Microsoft Graph。
- 選擇 應用程式權限 (不是委派權限)。
- 搜尋並勾選
Mail.Send。 - 儲存後,務必點選 代表 [你的組織名稱] 授與管理員同意,狀態變為綠色勾勾才算生效。
3. 配置 Exchange Online 服務主體
這是一個純指令步驟,目的是在 Exchange 系統內建立一個對應的服務主體,並賦予它寄件者權限。你需要安裝 PowerShell 的 ExchangeOnlineManagement 模組。
- 連線到 Exchange Online:
Connect-ExchangeOnline。 - 執行以下指令建立連結:
PowerShell
New-ServicePrincipal -AppId <你的應用程式ID> -ServiceId <你的應用程式物件ID>
- 賦予特定信箱的寄信權限:
PowerShell
Add-MailboxPermission -Identity "[email protected]" -User <你的應用程式ID> -AccessRights FullAccess
4. 撰寫程式碼獲取 Token 並寄信
不能再像以前只輸入帳號密碼,程式邏輯需要改為:
- 向 Microsoft Entra ID 請求 Token。
- 將 Token 放入 SMTP 連線的認證標頭中。
如果使用 Python,可以使用 msal 函式庫來處理認證。
Python
import msal
app = msal.ConfidentialClientApplication(
client_id, authority=f"https://login.microsoftonline.com/{tenant_id}",
client_credential=client_secret
)
result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
access_token = result['access_token']
5. SMTP 連線設定
連線資訊維持不變,但認證方式必須支援 XOAUTH2。
- SMTP 伺服器:
smtp.office365.com - 連接埠:587
- 加密方式:STARTTLS
- 使用者名稱:你的完整 Email 地址
- 密碼:剛才取得的
access_token長字串
常見問題提醒
- 安全性限制:如果你的租戶啟用了「安全性預設值」(Security Defaults),可能會強制要求 MFA,這會導致傳統 SMTP 連線失敗。使用 OAuth 2.0 應用程式權限可以繞過此限制。
- 寄件人一致性:你在程式碼中
From欄位填寫的地址,必須與步驟 3 授權的信箱一致,否則會被 Exchange 拒絕寄送。 - 權限生效時間:在 Azure 修改權限後,有時需要等待 5 到 15 分鐘才會完全同步到 Exchange 伺服器。
在 Azure VNet 內部的後端服務向 Entra ID 請求 Token 是標準做法,但為了符合企業級的安全與效能規範,建議不要直接走公網連線,而是透過以下兩種技術進行優化:
1. 使用受控識別 (Managed Identities)
這是最推薦的方案。如果你是將後端服務部署在 Azure VM、App Service 或 Azure Container Apps 上,不應該在程式碼中寫死 Client ID 或 Secret。
- 安全性:你不需要管理憑證或金鑰,Azure 會自動處理身份認證。
- 運作機制:程式碼向本地端的一個特定 Endpoint 請求 Token,Azure 基礎設施會負責與 Entra ID 對接並回傳 Token。
- 網路路徑:這類請求通常走 Azure 內部的管理平面,不會暴露在公網。
2. 使用受控識別 (Managed Identity) 結合 Private Link
如果你的 VNet 有嚴格的資安限制(封鎖所有對外 443 流量),連 Entra ID 的公用端點都不想連,可以考慮使用 Microsoft Entra Private Link。
- 原理:在 VNet 內部建立一個 Private Endpoint,讓請求 Entra ID 的流量完全限制在私有網路內。
- 缺點:設定較為複雜,且這項功能目前主要針對特定資源存取,對於純粹的 Token 請求,通常只要確保 VNet 允許 HTTPS (443) 傳出至
login.microsoftonline.com即可。
為什麼這對後端服務是安全的
- Service-to-Service 認證:Entra ID 產生的 Token 是基於應用程式身份(App Role),而不是特定使用者。這非常適合後端無人值守(Headless)的環境。
- 範圍縮小 (Scoped):你可以限制該 Token 僅能用於發送郵件(Mail.Send),無法存取其他資料。
- 加密傳輸:所有的 Token 請求都必須強制使用 TLS 1.2 以上加密。
潛在的效能疑慮與對策
如果你擔心後端服務頻繁請求 Token 會造成延遲:
- 快取機制:不應每次寄信都請求新 Token。Token 通常有一小時的有效期,程式碼中應該實作快取邏輯,只有在
expires_in快到期時才重新獲取。如果你使用官方的MSALSDK,它會自動幫你處理快取。 - 網路開銷:Token 請求只是極小的 JSON 資料,對 VNet 頻寬幾乎沒有影響。
總結建議
對於 VNet 內部的後端服務,請求 Token 是完全適合的。最佳實踐是:優先使用 System-assigned Managed Identity,並在程式中透過 DefaultAzureCredential 來獲取 Token。這樣既不需要在設定檔存密碼,也能確保認證過程符合 Azure 最新的安全規範。
對於寄信這種非高併發的任務,這點認證開銷是可以忽略不計的。你目前比較需要擔心的反而是 VNet 的 NSG 是否有開啟 587 連接埠對外連線至 Office 365 的權限。
這是一個關於雲端架構安全性的好問題。簡單來說,Microsoft Graph 的確是一個外網端點(https://graph.microsoft.com),但這並不代表它不安全。
以下從網路層級、認證機制與最佳實踐來分析:
Microsoft Graph 的網路位置
Microsoft Graph 是微軟雲端服務的統一入口,本質上是一個公用端點 (Public Endpoint)。這意味著你的 VNet 內部服務需要透過 HTTPS (Port 443) 才能存取它。
Backend 存取外網的安全考量
雖然它是「外網」端點,但實務上它是安全的,原因如下:
- 傳輸層加密 (TLS):所有與 Graph API 的通訊都強制使用 TLS 1.2 或更高版本,資料在傳輸過程中是加密的。
- 身分驗證強制性:沒有有效的 OAuth 2.0 Token,任何人(即使連得上網址)都無法存取任何資料。
- 微軟骨幹網路:如果你的 Backend 服務是在 Azure VNet 內,發往 Microsoft Graph 的流量通常會留在 Microsoft 骨幹網路 (Global Network) 內部路由,而不會真的繞到公眾網際網路 (Public Internet) 的路由器。
如何讓存取過程更安全?
如果你的 VNet 是嚴格隔離的環境(封鎖所有 Outbound 流量),你可以採用以下對策:
1. 使用受控識別 (Managed Identity)
這是最重要的安全措施。
- 優點:你的 Backend 服務不需要儲存任何 Client Secret(金鑰)。身份辨識由 Azure 平台自動處理。
- 安全性:即使程式碼外洩,也沒有金鑰可以被盜用。
2. 設定網路安全組 (NSG) 或是服務標記 (Service Tags)
你不需要開放「所有外網」權限。
- 在 VNet 的 NSG 中,將輸出規則目的地設定為 Service Tag:
AzureActiveDirectory。 - 這樣你的後端服務就只能存取身份驗證相關的微軟服務,而不能隨便連到其他的惡意網站。
3. 透過 Private Link (私密連結)
雖然 Microsoft Graph 目前還不像 Storage 或 SQL 提供完全的「私有端點」來收發郵件(它主要是針對資料整合),但你可以透過 Azure API Management (APIM) 作為代理。
- 架構:VNet -> Private Endpoint -> APIM -> Microsoft Graph。
- 優點:你的後端服務完全不需要開啟任何對外網的存取權限。
總結建議
對於一般公司內部的後端服務,直接存取 Microsoft Graph 是符合業界標準的。只要你:
- 使用 HTTPS 連線。
- 採用 Managed Identity (受控識別) 取代金鑰。
- 在 NSG 中限制僅允許存取 AzureActiveDirectory 的 Service Tag。
這樣的安全強度對於 MIS 與資安稽核來說通常是足夠的。
根據 2026 年最新的官方公告與限制說明,Exchange Online 的寄信限額如下:
核心寄送限制
- 每日收件者上限:每個人員信箱每天最多可寄送給 10,000 個收件者。
- 計算方式:這是一個 24 小時的滑動視窗(Rolling Window),而不是每天凌晨重置。
- 外部收件者限額 (ERR):微軟原本計畫在 2026 年 4 月將「外部收件者」限制在每日 2,000 人,但因客戶反饋激烈,該計畫已於 2026 年 1 月正式取消。目前外部收件者依然併入總量 10,000 人的額度內,沒有獨立的較低上限。
其他關鍵節流限制
除了總量,還有以下技術限制會影響你的後端程式:
- 每分鐘傳送速率:每分鐘最多寄送 30 封郵件。如果超過此速度,Exchange 會回傳重試代碼(Throttling)。
- 單封郵件收件者人數:單封 Email 最多只能包含 500 個收件者(可由管理者調高至 1,000 個)。
- 並行連線數:使用 SMTP AUTH 時,最多支援 3 個並行連線。
租戶層級總額 (TERRL)
除了單一信箱的限制,整個組織(Tenant)也有一個總對外寄信額度,通常是根據你購買的授權數量來計算:
- 公式大致為:
500 x (授權數量 ^ 0.7) + 9,500。 - 這意味著如果你的公司只有 1 個授權,總額就是 10,000 封;如果有 1,000 個授權,總額約為每日 7.2 萬封。
專家提醒
如果你的後端服務需要發送大量的系統通知或電子報(例如一天超過一萬封),Exchange Online 並不是合適的選擇。它被定位為「人員商務通訊」,過量發信容易被系統標記為垃圾郵件發送者。建議若需求量大,應轉向使用 Azure Communication Services (ACS) 或 SendGrid,這類服務才有專門的信用額度管理與更高的寄送上限。