THÊM TÍNH NĂNG DKIM
cho Postfix với dkim-milter trên nền FreeBSD
1. DKIM là gì
DKIM (DomainKeys Identified Mail) là một phương pháp xác thực e-mail bằng chữ ký số
của miền gửi thư, trong đó khóa công khai thường được công bố trên DNS dưới dạng một TXT record.
Khi gửi thư, bộ ký thư sẽ chèn lên đầu thư một trường
DKIM-Signature [1] có nội dung đại khái như sau:
Code: DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mycompany.com; s=sitec; t=1250425543;
bh=qQxSOEYYHCCISqVJ6pi/vUuNCr0EqMNkRSnD0B0TNFQ=;
h=Message-ID:From:To:Subject: Date:MIME-Version:Content-Type;
b=aiL+F+rqOdVxmR1V0bdfwsVOvMpwv1eMcCrX5I2C6U9CX+mkyepL3t0PwkW8pLSFc
CpJ5NvsBGqgOK4f2h89IubyYMFU0BkqZmtlBFlL+wyximVXLtHxO95WOxJX380tCet
XwofYIOK7tx45K41hG4T7+5ylNSuO1HHMpM/WfOM=
Trong đó có mọi thông tin cần thiết như phiên bản DKIM (
v), thuật toán ký (
a), thuật toán chuẩn hóa xâu ký tự đưa đi ký (
c ), tên miền ký (
d), tên cặp khóa, hay còn gọi là selector (
s), dấu ấn thời gian (
t), thời hạn hiệu lực của chữ ký (
x), phương thức truy vấn để lấy khóa công khai (
q), danh sách các trường của phần đầu thư được ký (
h), độ dài phần thân thư được ký (
l), giá trị hash của nội dung được ký (
bh), và chữ ký (
b).
Khi nhận thư, bộ kiểm thư sẽ xác định khóa công khai theo phương pháp
q (trong ví dụ trên, vốn dĩ không chỉ rõ
q, phương pháp mặc định là truy vấn DNS tìm TXT record có tên là
sitec._domainkey.mycompany.com.), dựa vào đó kiểm tra chữ ký rồi chèn kết quả kiểm tra vào trường
Authentication-Results [2] của thư. Chẳng hạn, kết quả tốt được viết như sau:
Code: Authentication-Results: ... dkim=pass header.i=@mycompany.com
Kết quả này xác thực các trường của phần đầu thư đã kể trong mục
h (tức Message-ID, From, To, Subject, Date, MIME-Version và Content-Type trong ví dụ trên) cùng với phần thân thư có độ dài kể trong mục
l (tức toàn bộ phần thân thư trong ví dụ trên, vốn dĩ với mục
l mặc định).
Trong dây chuyền nộp – chuyển – phát thư, bộ ký thư thường đặt tại sending MTA và bộ kiểm thư thường đặt tại receiving MTA. Khi đó DKIM thực chất chỉ xác nhận thư được bảo toàn trên suốt chặng đường
chuyển thư. Việc đảm bảo một lá thư From:alice@mycompany.com chắc chắn thuộc về Alice nằm ngoài trách nhiệm của DKIM.
Ngoài ra, tùy theo chính sách kiểm tra chữ ký DKIM của mình, bộ kiểm thư có thể tìm hiểu chính sách ký DKIM (tức ADSP, Author Domain Signing Practices [3]) của mycompany.com bằng cách truy vấn DNS tìm TXT record tên là
_adsp._domainkey.mycompany.com., căn cứ vào đó (và tùy theo kết quả kiểm tra chữ ký) để quyết định có chấp nhận lá thư hay không.
2. Vì sao, khi nào dùng DKIM
Nói một cách vắn tắt, nên dùng DKIM bởi vì một lá thư không có chữ ký DKIM dễ bị hiểu là spam.
DKIM là một phương pháp xác thực chứ không phải là một phương pháp chống spam. Nhưng nó hỗ trợ việc chống spam bởi vì nó đảm bảo thư là thật (địa chỉ người gửi, hay ít nhất tên miền gửi thư là thật) trong khi thực tế đa số spam đều là thư giả mạo (mạo tên người khác, tên miền khác). Với DKIM,
ai muốn spam thì cứ thoải mái, nhưng phải spam một cách quang minh chính đại; bạn không thể gửi thư từ một tên miền không thuộc sở hữu của mình được.
Phát triển từ phương pháp
DK của Yahoo và phương pháp
IM của Cisco, với việc được cơ quan IETF cấp tư cách
Standards Track, DKIM đã từ một phương pháp xác thực email trẻ nhất trở thành phương pháp có tiềm năng nhất.
Với việc xác thực nội dung hơn là xác thực phong bì, trong các tình huống mà phong bì thay đổi, chẳng hạn, thư được forward qua một đường chuyển thư phức tạp, DKIM cho những lá thư cơ hội sống sót cao hơn so với các phương pháp xác thực địa chỉ server như là
SPF hay
SIDF. (Nhưng tất nhiên, trong những tình huống nội dung thay đổi, chẳng hạn qua bộ quét virus, các phương pháp kia có thể cho cơ hội sống sót cao hơn.)
Với việc triển khai trên server hơn là trên client, và không đòi hỏi một hạ tầng khóa công khai phức tạp, DKIM gọn nhẹ hơn so với các phương pháp xác thực từ đầu đến cuối như là S/MIME hay PGP. (Nhưng tất nhiên, ý nghĩa xác thực cũng nhẹ hơn, DKIM không thể thay thế hoàn toàn cho các phương pháp kia.)
Hiện nay DKIM chưa được dùng phổ biến. Thư có chữ ký DKIM chỉ mới thấy chủ yếu từ các ngân hàng, tổ chức tài chính (Paypal, eBay,...) và một số nhà cung cấp email (Google, Yahoo, Hotmail,...).
Vì thế, chính sách dùng DKIM tốt nhất hiện nay là
ký triệt để mọi lá thư gửi đi từ miền mình và chỉ từ chối những lá thư không hợp lệ đến từ những miền khác có chính sách ký thư triệt để.
Cơ chế an ninh nào cũng có giá của nó. Việc tạo ra một chữ ký hay kiểm tra một chữ ký tiêu tốn hàng triệu clock cycle. Với DKIM, một server có xung nhịp cỡ GHz sẽ tiêu tốn thêm chừng 1 ms cho mỗi lá thư đến hay đi.
3. Phần mềm
Các thành phần chính của mail server gồm
- FreeBSD operating system v.7.2 – GENERIC kernel.
- Postfix SMTP server v.2.6.
- Gói milter của sendmail, mặc định được cài đặt sẵn (cùng với sendmail) trong FreeBSD.
- Dkim milter v. 2.8.3 với libdkim 1.0.17.
4. Môi trường và cấu hình tổng thể
Trên cùng một máy với Postfix đã cài đặt và hoạt động như một sending MTA đồng thời như một receiving MTA, ta sẽ cài đặt dkim-milter và cấu hình nó thành bộ ký thư đồng thời thành bộ kiểm thư, nghĩa là có nhiệm vụ ký các lá thư gửi đi, kiểm tra chữ ký những lá thư nhận được và chặn chúng nếu không hợp lệ.
Trước khi cài đặt dkim-milter, cần có các điều kiện sau.
- FreeBSD đã cài đặt và cập nhật những miếng vá mới nhất.
- Ports collection đã cập nhật bản mới nhất.
- Postfix đã cài đặt và hoạt động.
- Firewall cục bộ phải mở một cổng trên lookback interface để qua đó Postfix liên lạc với dkim-milter. Chúng ta sẽ giả sử là cổng 8891 TCP.
5. Cài đặt và cấu hình chi tiết
1. Cài đặt libdkim và dkim-milter
Code: cd /usr/ports/mail/libdkim
make install clean
cd /usr/ports/mail/dkim-milter
make install clean
Các chương trình đã cài vào gồm có
Code: /usr/local/bin/dkim-genkey #chương trình tạo khóa
/usr/local/bin/dkim-testkey #chương trình thử khóa
/usr/local/bin/dkim-testssp
/usr/local/libexec/dkim-filter #chương trình chính
/usr/local/etc/rc.d/milter-dkim #script chạy chương trình chính
/usr/local/share/doc/dkim-milter #tài liệu
2. Tạo account dịch vụ, tức là một account không có home và shell, thuộc một group tương ứng cùng tên, chúng ta sẽ đặt tên account này là
dkim. Chi tiết của việc này được bỏ qua.
3. Tạo các thư mục để chứa khóa. Nên đặt tên theo tên miền mail cần xác thực. Chúng ta sẽ giả sử rằng ta có một miền mail cần xác thực là
mycompany.com.
Code: mkdir /etc/mail/dkim
mkdir /etc/mail/dkim/keys
mkdir /etc/mail/dkim/keys/mycompany.com
cd /etc/mail/dkim/keys/mycompany.com
4. Tạo một cặp khóa công khai/bí mật cho miền này.
Code: dkim-genkey -d mycompany.com -s sitec -t
Trong đó -d (domain) là tên miền mail, -s (selector) là một từ bất kỳ tùy ý, chúng ta đặt là
sitec, có tác dụng báo danh cặp khóa, nhờ nó mà có thể tạo ra và dùng đồng thời nhiều cặp khóa cho một miền mail, và -t nói rằng cặp khoá tạo ra dùng để test thử nghiệm; khi làm chính thức thì tạo cặp khoá mới cũng bằng lệnh này nhưng không có tham số -t. Lệnh này sẽ tạo ra trong thư mục hiện thời hai file
Code:
File thứ nhất,
sitec.private, chứa khóa bí mật. Ta hãy đổi chủ và phân quyền truy cập nó.
Code: chown dkim:dkim sitec.private
chmod 600 sitec.private
chown dkim:dkim /etc/mail/dkim/keys/mycompany.com
chmod 700 /etc/mail/dkim/keys/mycompany.com
File thứ hai,
sitec.txt, chứa khóa công khai. File này có nội dung đại khái như sau.
Code: sitec._domainkey IN TXT "v=DKIM1; g=*; k=rsa;
p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/tmJXY+kdhPLEIzy8C6Etl+PXlr3zJ8ElX
DUIyT7bBHE9z69igqffuIZ42eXTeJJBXNdrWlO4QBQ6H0knnpIvZid+VwG2GVfO98FT1F4YZGx4Np
plZqebT6YCQLF/T9JGctjsAN197KrCT0ilChgVmekyeT5g8f1iXBWUE4kFXwIDAQAB" ; ----- DKIM sitec for mycompany.com
5. Công bố khoá công khai lên DNS bằng cách tạo trong DNS forward lookup zone
mycompany.com một TXT record có tên là
sitec._domainkey.mycompany.com. và có giá trị là đoạn văn bản
v=DKIM1; g=*; k=rsa; p=MIGfM...IDAQAB trong file nói trên. Nếu DNS server của chúng ta là BIND, việc này thực hiện đơn giản bằng cách copy paste toàn bộ nội dung của file trên vào forward lookup zone file; còn nếu là DJBDNS, việc này có thể thực hiện bằng cách copy paste từng phần của file trên vào một trang web có sẵn trên mạng Internet tên là
djbdns / tinydns Record Builder (người đọc tự tìm), sau đó copy paste dòng kết quả từ trang web này vào file dữ liệu của DJBDNS.
Ngoài ra, ta hãy công bố chính sách ký lên DNS. Hãy tạo tương tự như trên một TXT record có tên là
_adsp._domainkey.mycompany.com. và có giá trị là
dkim=all hoặc
dkim=discardable;
all tuyên bố rằng mọi lá thư của mycompany.com đều được ký,
discardable tuyên bố rằng mọi lá thư từ mycompany.com không có chữ ký hợp lệ đều đáng vứt đi.
6. Sửa file cấu hình của Postfix. Trong file
/etc/postfix/main.cf (hoặc /usr/local/etc/postfix/main.cf), viết thêm vài dòng như sau.
Code: milter_default_action = accept
milter_protocol = 2 # hoặc 3
smtpd_milters = inet:localhost:8891
nonsmtpd_milters = inet:localhost:8891
7. Tạo file cấu hình
/etc/mail/dkim-filter.conf. Ta có thể sao chép từ cấu hình mẫu /usr/local/etc/mail/dkim-filter.conf.sample rồi sửa đổi vài tham số như sau.
Code: KeyFile /etc/mail/dkim/keys/mycompany.com/sitec.private
Socket inet:8891@localhost
Domain mycompany.com
Selector sitec
8. Sửa file cấu hình boot
/etc/rc.cf, viết thêm vài dòng như sau.
Code: milterdkim_enable="YES"
milterdkim_uid="dkim"
milterdkim_profiles=""
milterdkim_cfgfile="/etc/mail/dkim-filter.conf"
9. Khởi động dkim-milter.
Code: /usr/local/etc/rc.d/milter-dkim start
10. Khởi động lại Postfix và DNS server.
Nếu mọi bước trên đều làm chính xác, DKIM sẽ hoạt động. Ta có thể thử kiểm tra bằng cách gửi thư đến một địa chỉ chuyên dùng để thử nghiệm DKIM (người đọc tự tìm), hoặc đến một account của bản thân ở gmail.com hay yahoo.com.
6. Các việc nên làm thêm
Chúng ta đã cấu hình dkim-milter để ký và kiểm tra chữ ký, nhưng không cản lọc. Ta có thể chỉnh sửa file cấu hình dkim-filter.conf để lọc và cản các thư không có chữ ký DKIM hợp lệ đến từ những miền nhất định (chẳng hạn, những miền có chính sách
discardable).
7. Tài liệu tham khảo
[1] Allman E. và một số tác giả khác: DomainKeys Identified Mail (DKIM) Signatures. RFC 4871. IETF Standards Track. 2007.
[2] Kucherawy M.: Message Header Field for Indicating Message Authentication Status. RFC 5451. IETF Standards Track. 2009.
[3] Allman E. và một số tác giả khác: DomainKeys Identified Mail (DKIM) Author Domain Signing Practices (ADSP) . RFC 5617. IETF Standards Track. 2009.
[4] Sendmail: FreeBSD man pages: dkim-filter(8), dkim-filter.conf(5), dkim-genkey(8).
[5] Postfix: Postfix before-queue Milter support.