30 April, 2020
#35: DKIM và SPF
Ở một bài viết trước đây, mình có nói tới giao thức trao đổi email SMTP. Tuy nhiên, giao thức này rất cổ xưa, và đúng là nó có những lỗi hổng về mặt bảo mật. Trong bài viết này, mình sẽ bàn đến 2 cơ chế phổ biến: DKIM và SPF, dùng để khắc phục những lỗ hổng đó. Cả hai kỹ thuật này hiện đã thành tiêu chuẩn giữa các server mail.
Nếu bạn chưa biết về SMTP, mình khuyên bạn hãy đọc bài viết này trước khi đọc tiếp: #30: Tìm hiểu giao thức truyền email
Để bắt đầu, mình sẽ thử viết một script ngắn để gửi email đi từ localhost, mà không phụ thuộc vào server trung gian nào:
Ở đây, mình sử dụng các lệnh SMTP như ở bài viết trước đây, để gửi email tới dropmail.me, vốn là một dịch vụ cho phép tạo email “tạm thời”
Và mình có nhận được. Vậy bây giờ không gửi cho dropmail.me nữa, gửi sang gmail thì sao nhỉ ?
Và mình ngay lập tức gặp lỗi, tại sao ?
Sender Policy Framework (SPF)
Ở bài viết trước, mình có nói tới “cuộc hội thoại” giữa 2 server để trao đổi email cho nhau. Tuy nhiên, điều này đặt ra vấn đề là khi server A đưa một “phong bì thư” cho server B, trên “phong bì” đó có thể ghi bất kỳ địa chỉ nào. Và khi server B nhận được, nó sẽ đành phải tin tưởng server A, rằng đây là phong bì thật, thông tin người nhận là thật.
Vậy thì dễ quá, B chỉ cần hỏi lại rằng địa chỉ trên phong bì có đúng là của A không. Nhưng vấn đề là, lúc nhận email, B chỉ “nhìn” được IP của người đang “nói chuyện” với mình.
Để kiểm tra IP này, B sẽ hỏi DNS xem địa chỉ server trên phong bì (ví dụ như @ngxson.com) cho phép email trao đổi từ những IP nào. Ví dụ ngxson.com cho phép email gửi từ sendgrid và yandex là hợp lệ
(Yep, thực tế mình dùng yandex để nhận email, sau đó nó sẽ được forward qua gmail. Chiều gửi thì mình dùng sendgrid, kết nối với gmail bằng SMTP)
DomainKeys Identified Mail (DKIM)
Như vậy SPF bảo vệ cái “phong bì” thư bên ngoài (hay như hình dưới đây, là SMTP envelope). Vậy còn nội dung thư ở bên trong thì sao ?
Hãy nhớ lại khi viết thư, bạn thường “ký tên” ở dưới cuối bức như. DKIM cũng vậy, nhưng thay vì ký ở cuối, chữ ký sẽ được lưu ở message header, với tên header là DKIM-Signature
Khi gửi email, server gửi sẽ tự động tạo chữ ký email bằng một private key, rồi lưu chữ ký này vào DKIM-Signature. Khi server còn lại nhận được, nó sẽ truy vấn DNS xem public key ứng với domain gốc của email này là gì, rồi dùng public key đó kiểm tra xem chữ ký có hợp lệ không.
Ví dụ về public key của ngxson.com
Hiện nay, các nhà cung cấp dịch vụ email lớn như Sendgrid, Mailgun, G Suite, Yandex,… đều có hướng dẫn đầy đủ về việc setup DKIM và SPF khi bạn muốn cài dịch vụ email lên domain cá nhân.
Việc cài DKIM và SPF, cộng với IP reputation tốt của các dịch vụ chuyên gửi mail, sẽ hạn chế rõ rệt việc email gửi từ domain của bạn bị vào mục spam.