← RFC Reference

Cách SMTP Hoạt Động Thực Sự

Email Concepts Encyclopedia Published March 2026
ELI5: Gửi email giống như gửi thư bảo đảm. Trước tiên bạn tra cứu địa chỉ (DNS), rồi đi đến bưu điện và giới thiệu bản thân (EHLO). Nhân viên kiểm tra ID của bạn (AUTH), bạn giao thông tin phong bì (MAIL FROM, RCPT TO), rồi nội dung thư (DATA). Nhân viên dấu đó là được chấp nhận hoặc cho bạn biết có gì sai với mã số. Toàn bộ quá trình diễn ra dưới dạng văn bản thuần túy qua kết nối TCP.

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:

  1. Tra cứu DNS — tìm máy chủ thư của người nhận
  2. Kết nối TCP — kết nối đến cổng 25 (hoặc 465/587 để gửi)
  3. Banner & EHLO — trao đổi danh tính và khả năng
  4. STARTTLS — nâng cấp lên kết nối mã hóa (thường)
  5. AUTH — xác thực nếu gửi (cổng 587)
  6. Envelope — MAIL FROM và RCPT TO
  7. DATA — truyền đầu thư và nội dung tin nhắn
  8. 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.

$ dig +short MX example.com
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:

# Máy chủ nói trước tiên
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ợ:

EHLO sender.mailertogo.com
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:

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:

STARTTLS
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-STSDANE để 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):

AUTH PLAIN AGFsaWNlQGV4YW1wbGUuY29tAHMzY3IzdA==
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ó:

MAIL FROM:<alice@example.com> SIZE=1024
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:

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:

DATA
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

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:

Ý 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:

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:

# 1. Kết nối TCP được thiết lập với mx1.example.net:25
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:

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-STSDANE ngăn chặn hạ cấp này.

Các điểm chính

Đọc thêm

Related RFCs