Cách SMTP Hoạt Động Thực Sự
Hướng dẫn đầy đủ về giao dịch SMTP — từ tra cứu DNS đến giao hàng cuối cùng. Nếu bạn gửi email theo chương trình, đây là mô hình tinh thần bạn cần.
Bức tranh lớn
SMTP — Giao thức truyền thư đơn giản — là giao thức di chuyển email trên internet. Được định nghĩa trong RFC 5321, nó đã là xương sống của email kể từ năm 1982 (RFC 821 gốc). Mặc dù có hàng chục phần mở rộng, giao dịch cốt lõi vẫn là một cuộc trò chuyện văn bản ngắn, đồng bộ giữa hai máy chủ qua cổng TCP 25.
Mọi giao hàng email đều tuân theo cùng một chuỗi:
- Tra cứu DNS — tìm máy chủ thư của người nhận
- Kết nối TCP — kết nối đến cổng 25 (hoặc 465/587 để gửi)
- Banner & EHLO — trao đổi danh tính và khả năng
- STARTTLS — nâng cấp lên kết nối mã hóa (thường)
- AUTH — xác thực nếu gửi (cổng 587)
- Envelope — MAIL FROM và RCPT TO
- DATA — truyền đầu thư và nội dung tin nhắn
- QUIT — đóng kết nối
Bước 1: DNS — Tìm kiếm máy chủ thư
Trước khi bất kỳ cuộc trò chuyện SMTP nào bắt đầu, máy chủ gửi phải khám phá nơi giao hàng tin nhắn. Nó truy vấn DNS về các bản ghi MX trên miền của người nhận.
10 mx1.example.com.
20 mx2.example.com.
Số này là ưu tiên (thấp hơn = ưa thích). Người gửi thử mx1.example.com trước. Nếu nó không thể tiếp cận hoặc trả về lỗi tạm thời, người gửi quay lại mx2.example.com.
Nếu không có bản ghi MX nào tồn tại, người gửi quay lại bản ghi A hoặc AAAA của miền — nhưng đây là giải pháp cuối cùng. Nếu bản ghi Null MX rõ ràng tồn tại (0 .), miền không chấp nhận thư chút nào. Xem DNS và Định tuyến thư để biết thuật toán đầy đủ.
Bước 2: Kết nối TCP và Banner
Người gửi mở một kết nối TCP đến cổng 25 của máy chủ MX. Máy chủ nhận nói trước tiên bằng banner 220:
220 mx1.example.com ESMTP sẵn sàng
Mã trạng thái 220 có nghĩa là "dịch vụ sẵn sàng." Nếu máy chủ bị quá tải, nó có thể phản hồi bằng 421 (dịch vụ không khả dụng) và đóng kết nối. Người gửi nên thử lại sau.
Để gửi thư (máy khách thư của người dùng gửi qua nhà cung cấp của họ), kết nối được đặt tới cổng 587 (RFC 6409) hoặc cổng 465 (TLS tiềm ẩn, RFC 8314) thay vì cổng 25.
Bước 3: EHLO — Thông báo Khả năng
Người gửi giới thiệu bản thân bằng EHLO (Extended HELO), cung cấp tên máy chủ của riêng mình. Máy chủ phản hồi với các phần mở rộng được hỗ trợ:
250-mx1.example.com Hello sender.mailertogo.com
250-SIZE 52428800
250-8BITMIME
250-STARTTLS
250-AUTH PLAIN LOGIN
250-PIPELINING
250-ENHANCEDSTATUSCODES
250 SMTPUTF8
Mỗi dòng 250- quảng cáo một phần mở rộng. Dòng cuối cùng sử dụng 250 (dấu cách, không có dấu gạch) để báo hiệu kết thúc. Các tiện ích mở rộng chính:
- SIZE — kích thước tối đa của tin nhắn theo byte
- STARTTLS — máy chủ hỗ trợ nâng cấp lên TLS (RFC 3207)
- AUTH — cơ chế xác thực được hỗ trợ (RFC 4954)
- PIPELINING — người gửi có thể hàng loạt các lệnh mà không chờ đợi (RFC 2920)
- ENHANCEDSTATUSCODES — mã trạng thái mở rộng như 5.1.1 (RFC 3463)
- 8BITMIME — truyền nội dung 8-bit được hỗ trợ
- SMTPUTF8 — địa chỉ email quốc tế hóa (RFC 6531)
Lệnh HELO kế thừa (không có "E") bỏ qua các phần mở rộng hoàn toàn. Nó hầu như không bao giờ được sử dụng trong thực tế ngày nay.
Bước 4: STARTTLS — Nâng cấp lên Mã hóa
Nếu máy chủ quảng cáo STARTTLS, người gửi phát hành lệnh để nâng cấp kết nối:
220 2.0.0 Sẵn sàng bắt đầu TLS
# Bắt tay TLS xảy ra ở đây
# Kết nối hiện được mã hóa
# Người gửi phải EHLO lại qua kênh mã hóa
EHLO sender.mailertogo.com
250-mx1.example.com Hello sender.mailertogo.com
250-SIZE 52428800
250 ENHANCEDSTATUSCODES
Sau STARTTLS, người gửi phải gửi EHLO lại. Máy chủ có thể quảng cáo các phần mở rộng khác nhau qua kết nối mã hóa (ví dụ: AUTH thường chỉ được quảng cáo sau khi TLS được thiết lập).
Trên cổng 465, TLS là tiềm ẩn — kết nối được mã hóa từ byte đầu tiên, và không cần bước STARTTLS.
Không có TLS, toàn bộ cuộc trò chuyện SMTP — bao gồm mật khẩu và nội dung tin nhắn — được gửi ở dạng văn bản thuần túy. Thực tiễn tốt nhất hiện đại là luôn sử dụng TLS. Xem MTA-STS và DANE để có cơ chế thực thi nó.
Bước 5: AUTH — Xác thực (Chỉ gửi)
Khi máy khách thư gửi tin nhắn qua cổng 587, nó xác thực bằng SMTP AUTH (RFC 4954):
235 2.7.0 Xác thực thành công
Chuỗi Base64 mã hóa \0tên_người_dùng\0mật_khẩu. Đây là lý do tại sao TLS rất quan trọng — nếu không, thông tin xác thực sẽ chuyển trong suốt.
Giao hàng máy chủ thành máy chủ trên cổng 25 không sử dụng AUTH. Thay vào đó, máy chủ nhận dựa vào địa chỉ IP của người gửi, bản ghi SPF, chữ ký DKIM và các cơ chế xác thực khác để xác minh tin nhắn. Xem Email Authentication Explained (Giải thích Xác thực Email).
Bước 6: Envelope — MAIL FROM và RCPT TO
Envelope tách biệt với đầu thư. Nó cho máy chủ nhận biết ai đang gửi tin nhắn và ai sẽ nhận nó:
250 2.1.0 OK
RCPT TO:<bob@example.net>
250 2.1.5 OK
RCPT TO:<carol@example.net>
250 2.1.5 OK
Chi tiết chính:
-
MAIL FROM chỉ định đường dẫn trả về (còn gọi là người gửi envelope hoặc địa chỉ bounce). Đây là nơi các DSN (tin nhắn bounce) đi. Nó có thể khác với đầu đề
From:. - RCPT TO chỉ định mỗi người nhận. Bạn có thể có nhiều lệnh RCPT TO cho một tin nhắn.
- Tham số
SIZE=tùy chọn cho phép máy chủ từ chối các tin nhắn quá lớn sớm. -
MAIL FROM:<>(đường dẫn ngược trống) được sử dụng cho các tin nhắn bounce, để ngăn vòng lặp bounce vô hạn.
Mỗi lệnh nhận được phản hồi riêng lẻ. 250 có nghĩa là được chấp nhận. 550 trên RCPT TO có nghĩa là hộp thư không tồn tại. 452 có nghĩa là máy chủ tạm thời không thể chấp nhận người nhận đó. Người gửi phải xử lý từng phản hồi riêng lẻ — một số người nhận có thể được chấp nhận trong khi những người khác bị từ chối.
Bước 7: DATA — Gửi Tin nhắn
Lệnh DATA bắt đầu truyền tin nhắn:
354 Bắt đầu đầu vào thư; kết thúc bằng <CRLF>.<CRLF>
From: Alice <alice@example.com>
To: Bob <bob@example.net>
Subject: Cuộc họp ngày mai
Date: Tue, 11 Mar 2026 10:30:00 -0400
Message-ID: <abc123@example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Hi Bob,
Chúng tôi vẫn còn lúc 2 gichiều chứ?
- Alice
.
250 2.0.0 OK: xếp hàng đợi thành 4F3A21C8
Tin nhắn bao gồm cả đầu thư và nội dung, được phân tách bằng một dòng trống. Tin nhắn được kết thúc bằng một dòng chứa chỉ một dấu chấm (.) — quy ước "dot-stuffing". Bất kỳ dòng nào trong nội dung tin nhắn bắt đầu bằng dấu chấm đều có thêm một dấu chấm được thêm vào khi truyền và được loại bỏ khi nhận.
Phản hồi 250 sau DATA có nghĩa là tin nhắn đã được chấp nhận để giao hàng. Nó không có nghĩa là tin nhắn đã được giao tới hộp thư của người nhận. Máy chủ nhận vẫn có thể từ chối nó trong quá trình lọc nội dung, hoặc tạo bounce sau đó.
ID hàng đợi (ví dụ: 4F3A21C8) là vô giá cho việc gỡ lỗi. Ghi lại nó.
Bước 8: QUIT
221 2.0.0 Tạm biệt
Người gửi đóng phiên. Kết nối TCP bị phá vỡ. Nếu người gửi có nhiều tin nhắn cho cùng một máy chủ, nó có thể phát hành MAIL FROM khác thay vì QUIT để tái sử dụng kết nối.
Mã phản hồi SMTP
Mỗi phản hồi SMTP bắt đầu bằng mã ba chữ số. Chữ số đầu tiên cho bạn biết danh mục:
| Mã | Ý nghĩa | Hành động |
|---|---|---|
| 2xx | Thành công | Lệnh hoàn tất; tiếp tục |
| 3xx | Trung gian | Máy chủ đang chờ dữ liệu thêm (ví dụ: sau DATA) |
| 4xx | Lỗi tạm thời | Thử lại sau. Máy chủ có thể chấp nhận tin nhắn khi cố gắng tiếp theo |
| 5xx | Lỗi vĩnh viễn | Không thử lại. Tin nhắn sẽ không bao giờ được chấp nhận nguyên trạng |
Các mã phổ biến bạn sẽ gặp:
-
220— Dịch vụ sẵn sàng (banner) -
250— Hành động yêu cầu hoàn tất -
354— Bắt đầu đầu vào tin nhắn -
421— Dịch vụ không khả dụng, đóng kết nối (thử lại sau) -
450— Hộp thư tạm thời không khả dụng (greylisting, giới hạn tốc độ) -
451— Hành động yêu cầu bị hủy do lỗi cục bộ -
452— Dung lượng lưu trữ không đủ -
550— Hộp thư không tìm thấy / hành động không được thực hiện -
551— Người dùng không phải là cục bộ; vui lòng thử địa chỉ chuyển tiếp -
552— Kích thước tin nhắn vượt quá giới hạn -
553— Tên hộp thư không được phép -
554— Giao dịch không thành công (thường được sử dụng để từ chối chính sách)
Với ENHANCEDSTATUSCODES, máy chủ nối thêm mã cụ thể hơn như 5.1.1 (hộp thư đích xấu). Xem Understanding Email Bounces (Hiểu Bounces Email) để biết tờ rơi đầy đủ.
Một giao dịch hoàn chỉnh
Đây là toàn bộ phiên SMTP từ kết nối đến đóng, có chú thích:
220 mx1.example.net ESMTP Postfix
# 2. Máy khách giới thiệu bản thân
EHLO sender.mailertogo.com
250-mx1.example.net
250-STARTTLS
250-SIZE 26214400
250-PIPELINING
250-ENHANCEDSTATUSCODES
250 8BITMIME
# 3. Nâng cấp lên TLS
STARTTLS
220 2.0.0 Sẵn sàng bắt đầu TLS
# (Bắt tay TLS hoàn tất)
# 4. Giới thiệu lại qua kênh mã hóa
EHLO sender.mailertogo.com
250-mx1.example.net
250-SIZE 26214400
250-PIPELINING
250-ENHANCEDSTATUSCODES
250 8BITMIME
# 5. Envelope
MAIL FROM:<notifications@app.example.com>
250 2.1.0 OK
RCPT TO:<bob@example.net>
250 2.1.5 OK
# 6. Nội dung tin nhắn
DATA
354 Kết thúc dữ liệu bằng <CR><LF>.<CR><LF>
From: App Notifications <notifications@app.example.com>
To: bob@example.net
Subject: Hóa đơn của bạn đã sẵn sàng
Date: Tue, 11 Mar 2026 14:00:00 +0000
Message-ID: <inv-7842@app.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Hóa đơn tháng 3 của bạn đã sẵn sàng. Đăng nhập để xem nó.
.
250 2.0.0 OK: xếp hàng đợi thành B9C4E1A3F
# 7. Xong
QUIT
221 2.0.0 Tạm biệt
Gửi so với Relay
SMTP đóng hai vai trò riêng biệt:
- Gửi (cổng 587 hoặc 465): Máy khách thư gửi tin nhắn mới đến máy chủ thư của nó. Cần xác thực. Máy chủ chịu trách nhiệm giao hàng nó.
- Relay (cổng 25): Một máy chủ thư giao hàng tin nhắn đến máy chủ khác. Không xác thực — ủy quyền đến từ DNS (bản ghi MX) và xác thực người gửi (SPF, DKIM).
Một mở relay — máy chủ chấp nhận thư từ bất kỳ ai tới bất kỳ ai — là tội lỗi then chốt của cấu hình email. Những kẻ spammer khai thác các relay mở ngay lập tức. Mỗi máy chủ thư hiện đại phải hạn chế relay cho người dùng được xác thực hoặc người gửi đã biết.
Có thể sai được gì
Kết nối bị từ chối hoặc hết thời gian
Máy chủ MX bị hỏng hoặc được bảo vệ bởi tường lửa. Hàng đợi của người gửi thử lại với backoff theo cấp số nhân, xoay vòng qua các bản ghi MX có ưu tiên thấp hơn. Sau thời gian thử lại (thường là 4-5 ngày), tin nhắn bounce.
Greylisting
Máy chủ nhận trả về 450 cho lần cố gắng đầu tiên từ một người gửi không xác định. Các máy chủ hợp pháp thử lại; những kẻ spammer thường không. Tin nhắn của bạn sẽ bị trễ vài phút nhưng cuối cùng sẽ giao hàng.
Bị từ chối tại RCPT TO
Phản hồi 550 5.1.1 User unknown có nghĩa là hộp thư không tồn tại. Đây là một bounce cứng. Xóa ngay địa chỉ khỏi danh sách của bạn.
Bị từ chối tại DATA
Máy chủ có thể chấp nhận envelope nhưng từ chối nội dung. Lý do phổ biến: tin nhắn quá lớn, nội dung được gắn cờ là spam hoặc kiểm tra xác thực không thành công (SPF/DKIM/DMARC). Phản hồi đến sau dấu chấm kết thúc.
Được chấp nhận rồi bounce
Máy chủ trả về 250 cho DATA nhưng sau đó tạo DSN (tin nhắn bounce) vì hộp thư đã đầy, lọc nội dung từ chối nó hoặc xảy ra lỗi bên trong. Đây là trường hợp khó nhất để xử lý — bạn chỉ tìm hiểu thông qua tin nhắn bounce được gửi đến địa chỉ MAIL FROM.
Lỗi TLS
Nếu thương lượng STARTTLS không thành công, hầu hết các máy chủ sẽ quay lại văn bản thuần túy. Đây là rủi ro bảo mật — kẻ tấn công chủ động có thể tước TLS. MTA-STS và DANE ngăn chặn hạ cấp này.
Các điểm chính
- SMTP là giao thức đồng bộ, dựa trên văn bản. Mỗi lệnh nhận được mã phản hồi.
- Envelope (MAIL FROM / RCPT TO) tách biệt với các đầu thư tin nhắn (From: / To:). Chúng có thể khác nhau.
-
250sau DATA có nghĩa là "được chấp nhận để giao hàng," không phải "được giao tới hộp thư." - Lỗi 4xx là tạm thời — thử lại. Lỗi 5xx là vĩnh viễn — không thử lại.
- Luôn sử dụng TLS. Thực thi nó bằng MTA-STS hoặc DANE.
- Ghi lại ID hàng đợi từ phản hồi máy chủ để gỡ lỗi.