Bài viết này sẽ giới thiệu cách cấu hình email server trên Ubuntu với sendmail.

Bài viết bao gồm: cài đặt, cấu hình SSL, cấu hình spf (trên domain), gửi mail test, cấu hình với ghost server (nodemailer), kiểm tra log file, debug với test email.

Ngoài ra cuối bài có bổ sung về cách cấu hình cho MX record khi nhận email.

Bước 1: cài đặt sendmail qua lệnh apt install sendmail

Bước 2: cấu hình ssl

  • Thêm dòng sau vào cuối của file /etc/mail/sendmail.mc
include(`/etc/mail/tls/starttls.m4')dnl
  • Trong file /etc/mail/tls/starttls.m4, nội dung mặc định là
divert(-1)dnl
####################################################################
##### This file is automagically generated -- edit at your own risk
#####
##### Copyright (c) 2002-2010 Richard Nelson.  All Rights Reserved.
#####
##### file: /etc/mail/tls/starttls.m4
#####		STARTTLS Configuration for Debian Sendmail
##### generated via: (/usr/bin/perl v5>26.1)
#####		/usr/share/sendmail/update_tlsm4
#####		version: 8.15.2 2018-01-13 23:43:05 cowboy
##### by: transang@nakata-tsuzukiku
##### on: Tue Jan 15 11:28:13 2019
##### in: /
##### input files: /etc/mail/databases
#####
##### Usage:
#####	1) To get *ANY* STARTTLS support for sendmail you
#####		A) *MUST* Add this line to /etc/mail/sendmail.mc
#####		   `include(`/etc/mail/tls/starttls.m4')dnl'
#####		B) *MAY* Add the same line to /etc/mail/submit.mc
#####		   to get MSP<->MTA authentication/encryption
#####	2) You may modify the marked portions of this file, those
#####	   deal with the cert/key filenames and TLS options.
#####	   If you need finer control of TLS options, use the access
#####	   database.
#####
####################################################################
divert(0)dnl
VERSIONID(`$Id: starttls.m4,v 8.15.2-10 2018-01-13 23:43:05 cowboy Exp $')
dnl #
dnl #---------------------------------------------------------------------
dnl # Bring in Autoconf results
dnl #---------------------------------------------------------------------
ifdef(`sm_version', `dnl',
`include(`/usr/share/sendmail/cf/debian/autoconf.m4')dnl')
dnl #
dnl # Check to see if inclusion is valid (version >= 8.11.0, tls enabled)
ifelse(eval(sm_version_math >= 527104), `1', `dnl
ifelse(sm_enable_tls, `yes', `dnl
dnl #
dnl # To support shared keyfiles, we need them to be group readable
dnl #
define(`confDONT_BLAME_SENDMAIL',dnl
	defn(`confDONT_BLAME_SENDMAIL')`,GroupReadableKeyFile')dnl
dnl #
dnl #             ...Do not touch anything above this line...
dnl #
dnl # Set a more reasonable timeout on negotiation
dnl #
define(`confTO_STARTTLS',     `2m')dnl   # <= EDIT
dnl #
dnl # CA directory - CA certs should be herein
define(`confCACERT_PATH',     `/etc/ssl/certs')dnl   # <= EDIT
dnl #
dnl # CA file (may be the same as client/server certificate)
define(`confCACERT',           `/etc/mail/tls/sendmail-server.crt')dnl   # <= EDIT
dnl #
dnl # Certificate Revocation List
define(`confCRL',              `')dnl   # <= EDIT
dnl # CRL not found...  do not issue warnings on it!
undefine(`confCRL')dnl
dnl #
dnl # Server certificate/key (can be in the same file, and shared w/client)
dnl # NOTE: The key must *NOT* be encrypted !!!
define(`confSERVER_CERT',     `/etc/mail/tls/sendmail-server.crt')dnl   # <= EDIT
define(`confSERVER_KEY',      `/etc/mail/tls/sendmail-common.key')dnl   # <= EDIT
dnl #
dnl # Client certificate/key (can be in the same file, and shared w/server)
dnl # NOTE: The key must *NOT* be encrypted !!!
define(`confCLIENT_CERT',     `/etc/mail/tls/sendmail-client.crt')dnl   # <= EDIT
define(`confCLIENT_KEY',      `/etc/mail/tls/sendmail-common.key')dnl   # <= EDIT
dnl #
dnl # DH parameters
define(`confDH_PARAMETERS',   `/etc/mail/tls/sendmail-common.prm')dnl # <= EDIT
dnl #
dnl # Optional settings
define(`confTLS_SRV_OPTIONS', `V')dnl   # <= EDIT
dnl #
')')dnl

Để ý các dòng có # <= EDIT ở cuối, thay thế các cấu hình ở dòng đó bằng các đường dẫn tương ứng.

Với SSL certificate tạo bằng letsencrypt, các đường dẫn tương ứng như sau

confCACERT_Path=/etc/letsencrypt/live/example.com
confCACERT=/etc/letsencrypt/live/example.com/chain.pem
confSERVER_CERT=/etc/letsencrypt/live/example.com/cert.pem
confSERVER_KEY=/etc/letsencrypt/live/example.com/privatekey.pem
confCLIENT_CERT and confCLIENT_KEY are same as server
confDH_PARAMETERS = dhparams.pem file

Tham khảo cách thiết lập SSL certificate trong bài này.

Thảm khảo cách tạo file dhparams.pemtrong bài viết này.

Bước 3: yêu cầu sendmail đọc lại cấu hình qua lệnh sendmailconfig

Bước 4: khởi động lại service qua lệnh systemctl restart sendmail

Bước 5: cấu hình spf record

spf record là một cấu hình trên DNS setting của domain, để đảm bảo email không bị làm giả và gửi từ 1 máy chủ khác. Ví dụ máy chủ của server example.com có địa chỉ là 1.2.3.4, gmail server nhận được 1 request (email) có nội dung là "gửi từ info@example.com đến abc@gmail.com". Bất kì máy chủ nào cũng có thể gửi được yêu cầu này đến gmail server.

Để phân biệt được email này không bị làm giả và gửi từ 1 server nào khác. Gmail sẽ truy vấn vào DNS setting của example.com, kiểm tra spf record, trong đó đã được cấu hình cho IP 1.2.3.4. Dựa trên đó gmail server sẽ lọc những request được gửi từ địa chỉ IP khác.

Tuy nhiên, nếu cố tình một người nào đó cũng có thể làm giả được địa chỉ IP của gói dữ liệu. Lúc đó phải cần đến cấu hình DKIM. Tham khảo về DKIM ở cuối bài viết, cách cấu hình cụ thể cho DKIM sẽ được bổ sung xong.

Cách cấu hình spf record: Trên DNS setting của domain, thêm vào một record như sau

  • Type: TXT Record
  • Host: @
  • Value: v=spf1 ip4:<ip v4 address> ip6:<ip v6 address> ~all

Trong đó ở trường value, thay thế <ip v4 address><ip v6 address> bằng địa chỉ IP (v4, v6) của server.

Ngoài ra cần đảm bảo chỉ có 1 record spf duy nhất trrong cấu hình của domain.

IP v6 AAA record trên domain cũng cần được thiết lập vì một số mail agent server yêu cầu bắt buộc dùng IP v6 khi nhận mail (VD gmail)

Bước 6: kiểm tra lại cấu hình bằng cách gửi thử 1 email qua dòng lệnh

sendmail -t -i -f info@transang.me <<EOF
From: support center<info@transang.me>
To: tranvansangk41@gmail.com
Subject: test email

This is a test email
EOF
  • -t: đọc thông tin địa chỉ gửi và địa chỉ nhận từ nội dung nhập
  • -i: Do  not  strip  a leading dot from lines in incoming messages, and do not treat a dot on a line by itself as the end of an incoming message.  This should be set if you are reading data from a file. Thường dùng khi nhập nội dung từ file
  • -f: địa chỉ gửi

Bước 7: cấu hình cho server. Ví dụ cho ghost server (ghost server sử dụng nodemailer)

Trong config.production.js

{
	"mail": {
		"from": "info@transang.me",
		"transport": "SMTP",
		"options": {
			"service": "sendmail"
		}
	}
}

Trường hợp cấu hình có lỗi, hoặc email không được gửi đến địa chỉ nhận. Kiểm tra log file tại đường dẫn /var/log/mail.log

Để gửi email và debug thông tin, chạy

sendmail -Am -i -v -f info@transang.me <<EOF
From: support center<info@transang.me>
To: tranvansangk41@gmail.com
Subject: test email

This is a test email
EOF

Dòng in ra ở console có định dạng bắt đầu bằng 1 số và thông tin.  Các số thường là 220, 250, ...

Các số này được gọi là SMTP code, tham khảo ý nghĩa của các số tại https://www.greenend.org.uk/rjk/tech/smtpreplies.html


MX record là gì?

MX record là 1 cấu hình trên domain (VD example.com), được dùng khi các mail agent khác gửi email đến địa chỉ của domain này (VD info@example.com)

Trong bài này, MX record hoàn toàn không được sử dụng do sendmail chỉ là công cụ dùng để gửi email đi.

Tuy nhiên do nội dung cũng có chút liên quan. Mình xin phép giới thiệu luôn về cách thiết lập luôn trong bài này.

Ví dụ khi cấu hình MX record cho email @example.com.

  • Thiết lập domain để nhận email. VD mail.example.com. Domain này được lựa chọn bất kì và không được hiển thị tới người dùng thông thường khi gửi mail. Chỉ có mail agent sử dụng nó. VD domain nhận email của gmail là mx.google.com
  • Trường hợp domain nhận email là subdomain của domain hiện tại, ví dụ mail.example.com, cấu hình cho subdomain đó trỏ đến địa chỉ của mail agent mà xử lý khi nhận email bằng cách thêm 1 A record, tại địa chỉ mail, gía trị là địa chỉ IP của server

Tạo 1 MX record, gía trị là 10 mail. Trong đó 10 là số ưu tiên được đặt là 1 số tự nhiên bất kì (khi có nhiều email agent, server gửi email sẽ dựa trên thứ tự ưu tiên này để lựa chọn server nhận email)

  • Trường hợp domain nhận email không phải là subdomain mà là 1 domain khác, VD other-example.com. Thì cần thêm dấu chấm vào gía trị của MX record, ví dụ 10 other-example.com.

DKIM là gì?

DKIM là một dạng chữ ký công khai để đảm bảo email không bị làm giả và gửi từ đúng máy chủ được xác nhận.

Ở trong bước 5 của bài viết mình đã giới thiệu về cách thiết lập spf record để chặn những IP khác gửi và làm giả email dưới tên miền của mình. Tuy nhiên IP có thể bị làm giả.

Thiết lập DKIM cần phải có public key, và private key. Trong đó public key được đặt trên cấu hình DNS của domain trên 1 record khác. Khi gửi email, mail server mã hóa email bằng private key, server nhận mail giải mã email bằng public key được ghi trên DNS setting của domain.

Việc thiết lập DKIM sẽ làm giảm khả năng email bị đánh dấu là thư rác hoặc bị từ chối bởi email agent.

Trong bài viết này mình không giới thiệu việc cài đặt tích hợp DKIM.