在这个系列的文章中,我们将通过使用 Postfix、Dovecot 和 openssl 这三款工具来为你展示如何在 ubuntu 系统上搭建一个既可靠又易于配置的邮件服务器。

在这个容器和微服务技术日新月异的时代,值得庆幸的是有些事情并没有改变,例如搭建一个 Linux 下的邮件服务器,仍然需要许多步骤才能间隔各种服务器耦合在一起,而当你将这些配置好,放在一起,却又非常可靠稳定,不会像微服务那样一睁眼有了,一闭眼又没了。 在这个系列教程中我们将通过使用 Postfix、Dovecot 和 openssl 这三款工具在 ubuntu 系统上搭建一个既可靠又易于配置的邮件服务器。

Postfix 是一个古老又可靠的软件,它比原始的 Unix 系统的 MTA 软件 sendmail 更加容易配置和使用(还有人仍然在用sendmail 吗?)。 Exim 是 Debain 系统上的默认 MTA 软件,它比 Postfix 更加轻量而且超级容易配置,因此我们在将来的教程中会推出 Exim 的教程。

Dovecot(LCTT 译注:详情请阅读维基百科)和 Courier 是两个非常受欢迎的优秀的 IMAP/POP3 协议的服务器软件,Dovecot 更加的轻量并且易于配置。

你必须要保证你的邮件通讯是安全的,因此我们就需要使用到 OpenSSL 这个软件,OpenSSL 也提供了一些很好用的工具来测试你的邮件服务器。

为了简单起见,在这一系列的教程中,我们将指导大家安装一个在局域网上的邮件服务器,你应该拥有一个局域网内的域名服务,并确保它是启用且正常工作的,查看这篇“使用 dnsmasq 为局域网轻松提供 DNS 服务”会有些帮助,然后,你就可以通过注册域名并相应地配置防火墙,来将这台局域网服务器变成互联网可访问邮件服务器。这个过程网上已经有很多很详细的教程了,这里不再赘述,请大家继续跟着教程进行即可。

一些术语

让我们先来快速了解一些术语,因为当我们了解了这些术语的时候就能知道这些见鬼的东西到底是什么。 :D

  • MTA邮件传输代理Mail Transfer Agent,基于 SMTP 协议(简单邮件传输协议)的服务端,比如 Postfix、Exim、Sendmail 等。SMTP 服务端彼此之间进行相互通信(LCTT 译注 : 详情请阅读维基百科)。
  • MUA: 邮件用户代理Mail User Agent,你本地的邮件客户端,例如 : Evolution、KMail、Claws Mail 或者 Thunderbird(LCTT 译注 : 例如国内的 Foxmail)。
  • POP3邮局协议Post-Office Protocol版本 3,将邮件从 SMTP 服务器传输到你的邮件客户端的的最简单的协议。POP 服务端是非常简单小巧的,单一的一台机器可以为数以千计的用户提供服务。
  • IMAP: 交互式消息访问协议Interactive Message Access Protocol,许多企业使用这个协议因为邮件可以被保存在服务器上,而用户不必担心会丢失消息。IMAP 服务器需要大量的内存和存储空间。
  • TLS传输套接层Transport socket layer是 SSL(安全套接层Secure Sockets Layer)的改良版,为 SASL 身份认证提供了加密的传输服务层。
  • SASL简单身份认证与安全层Simple Authentication and Security Layer,用于认证用户。SASL进行身份认证,而上面说的 TLS 提供认证数据的加密传输。
  • StartTLS: 也被称为伺机 TLS 。如果服务器双方都支持 SSL/TLS,StartTLS 就会将纯文本连接升级为加密连接(TLS 或 SSL)。如果有一方不支持加密,则使用明文传输。StartTLS 会使用标准的未加密端口 25 (SMTP)、 110(POP3)和 143 (IMAP)而不是对应的加密端口 465(SMTP)、995(POP3) 和 993 (IMAP)。

啊,我们仍然有 sendmail

绝大多数的 Linux 版本仍然还保留着 /usr/sbin/sendmail 。 这是在那个 MTA 只有一个 sendmail 的古代遗留下来的痕迹。在大多数 Linux 发行版中,/usr/sbin/sendmail 会符号链接到你安装的 MTA 软件上。如果你的 Linux 中有它,不用管它,你的发行版会自己处理好的。

安装 Postfix

使用 apt-get install postfix 来做基本安装时要注意(图 1),安装程序会打开一个向导,询问你想要搭建的服务器类型,你要选择“Internet Server”,虽然这里是局域网服务器。它会让你输入完全限定的服务器域名(例如: myserver.mydomain.net)。对于局域网服务器,假设你的域名服务已经正确配置,(我多次提到这个是因为经常有人在这里出现错误),你也可以只使用主机名。

图 1:Postfix 的配置。

Ubuntu 系统会为 Postfix 创建一个配置文件,并启动三个守护进程 : masterqmgr 和 pickup,这里没用一个叫 Postfix 的命令或守护进程。(LCTT 译注:名为 postfix 的命令是管理命令。)

  1. $ ps ax
  2. 6494 ? Ss 0:00 /usr/lib/postfix/master
  3. 6497 ? S 0:00 pickup -l -t unix -u -c
  4. 6498 ? S 0:00 qmgr -l -t unix -u

你可以使用 Postfix 内置的配置语法检查来测试你的配置文件,如果没用发现语法错误,不会输出任何内容。

  1. $ sudo postfix check
  2. [sudo] password for carla:

使用 netstat 来验证 postfix 是否正在监听 25 端口。

  1. $ netstat -ant
  2. tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
  3. tcp6 0 0 :::25 :::* LISTEN

现在让我们再操起古老的 telnet 来进行测试 :

  1. $ telnet myserver 25
  2. Trying 127.0.1.1...
  3. Connected to myserver.
  4. Escape character is '^]'.
  5. 220 myserver ESMTP Postfix (Ubuntu)
  6. EHLO myserver
  7. 250-myserver
  8. 250-PIPELINING
  9. 250-SIZE 10240000
  10. 250-VRFY
  11. 250-ETRN
  12. 250-STARTTLS
  13. 250-ENHANCEDSTATUSCODES
  14. 250-8BITMIME
  15. 250 DSN
  16. ^]
  17. telnet>

嘿,我们已经验证了我们的服务器名,而且 Postfix 正在监听 SMTP 的 25 端口而且响应了我们键入的命令。

按下 ^] 终止连接,返回 telnet。输入 quit 来退出 telnet。输出的 ESMTP(扩展的 SMTP ) 250 状态码如下。 (LCTT 译注: ESMTP (Extended SMTP),即扩展 SMTP,就是对标准 SMTP 协议进行的扩展。详情请阅读维基百科

  • PIPELINING 允许多个命令流式发出,而不必对每个命令作出响应。
  • SIZE 表示服务器可接收的最大消息大小。
  • VRFY 可以告诉客户端某一个特定的邮箱地址是否存在,这通常应该被取消,因为这是一个安全漏洞。
  • ETRN 适用于非持久互联网连接的服务器。这样的站点可以使用 ETRN 从上游服务器请求邮件投递,Postfix 可以配置成延迟投递邮件到 ETRN 客户端。
  • STARTTLS (详情见上述说明)。
  • ENHANCEDSTATUSCODES,服务器支撑增强型的状态码和错误码。
  • 8BITMIME,支持 8 位 MIME,这意味着完整的 ASCII 字符集。最初,原始的 ASCII 是 7 位。
  • DSN,投递状态通知,用于通知你投递时的错误。

Postfix 的主配置文件是: /etc/postfix/main.cf,这个文件是安装程序创建的,可以参考这个资料来查看完整的 main.cf 参数列表, /etc/postfix/postfix-files 这个文件描述了 Postfix 完整的安装文件。

本教程的第 2 部分将介绍如何使用 Dovecot 将邮件从 Postfix 服务器移动到用户的收件箱。

第一部分中,我们安装并测试了 Postfix SMTP 服务器。Postfix 或任何 SMTP 服务器都不是一个完整的邮件服务器,因为它所做的只是在 SMTP 服务器之间移动邮件。我们需要 Dovecot 将邮件从 Postfix 服务器移动到用户的收件箱中。

Dovecot 支持两种标准邮件协议:IMAP(Internet 邮件访问协议)和 POP3(邮局协议)。 IMAP 服务器会在服务器上保留所有邮件。您的用户可以选择将邮件下载到计算机或仅在服务器上访问它们。 IMAP 对于有多台机器的用户是方便的。但对你而言需要更多的工作,因为你必须确保你的服务器始终可用,而且 IMAP 服务器需要大量的存储和内存。

POP3 是较旧的协议。POP3 服务器可以比 IMAP 服务器服务更多的用户,因为邮件会下载到用户的计算机。大多数邮件客户端可以选择在服务器上保留一定天数的邮件,因此 POP3 的行为有点像 IMAP。但它又不是 IMAP,当你像 IMAP 那样(在多台计算机上使用它时)那么常常会下载多次或意外删除。

安装 Dovecot

启动你的 Ubuntu 系统并安装 Dovecot:

  1. $ sudo apt-get install dovecot-imapd dovecot-pop3d

它会安装可用的配置,并在完成后自动启动,你可以用 ps ax | grep dovecot 确认:

  1. $ ps ax | grep dovecot
  2. 15988 ? Ss 0:00 /usr/sbin/dovecot
  3. 15990 ? S 0:00 dovecot/anvil
  4. 15991 ? S 0:00 dovecot/log

打开你的 Postfix 配置文件 /etc/postfix/main.cf,确保配置了maildir 而不是 mbox 的邮件存储方式,mbox 是给每个用户一个单一大文件,而 maildir 是每条消息都存储为一个文件。大量的小文件比一个庞大的文件更稳定且易于管理。添加如下两行,第二行告诉 Postfix 你需要 maildir 格式,并且在每个用户的家目录下创建一个 .Mail 目录。你可以取任何名字,不一定要是 .Mail

  1. mail_spool_directory = /var/mail
  2. home_mailbox = .Mail/

现在调整你的 Dovecot 配置。首先把原始的 dovecot.conf 文件重命名放到一边,因为它会调用存放在 conf.d 中的文件,在你刚刚开始学习时把配置放一起更简单些:

  1. $ sudo mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot-oldconf

现在创建一个新的 /etc/dovecot/dovecot.conf

  1. disable_plaintext_auth = no
  2. mail_location = maildir:~/.Mail
  3. namespace inbox {
  4. inbox = yes
  5. mailbox Drafts {
  6. special_use = \Drafts
  7. }
  8. mailbox Sent {
  9. special_use = \Sent
  10. }
  11. mailbox Trash {
  12. special_use = \Trash
  13. }
  14. }
  15. passdb {
  16. driver = pam
  17. }
  18. protocols = " imap pop3"
  19. ssl = no
  20. userdb {
  21. driver = passwd
  22. }

注意 mail_location = maildir 必须和 main.cf 中的 home_mailbox 参数匹配。保存你的更改并重新加载 Postfix 和 Dovecot 配置:

  1. $ sudo postfix reload
  2. $ sudo dovecot reload

快速导出配置

使用下面的命令来快速查看你的 Postfix 和 Dovecot 配置:

  1. $ postconf -n
  2. $ doveconf -n

测试 Dovecot

现在再次启动 telnet,并且给自己发送一条测试消息。粗体显示的是你输入的命令。studio 是我服务器的主机名,因此你必须用自己的:

  1. $ telnet studio 25
  2. Trying 127.0.1.1...
  3. Connected to studio.
  4. Escape character is '^]'.
  5. 220 studio.router ESMTP Postfix (Ubuntu)
  6. EHLO studio
  7. 250-studio.router
  8. 250-PIPELINING
  9. 250-SIZE 10240000
  10. 250-VRFY
  11. 250-ETRN
  12. 250-STARTTLS
  13. 250-ENHANCEDSTATUSCODES
  14. 250-8BITMIME
  15. 250-DSN
  16. 250 SMTPUTF8
  17. mail from: tester@test.net
  18. 250 2.1.0 Ok
  19. rcpt to: carla@studio
  20. 250 2.1.5 Ok
  21. data
  22. 354 End data with .Date: November 25, 2016
  23. From: tester
  24. Message-ID: first-test
  25. Subject: mail server test
  26. Hi carla,
  27. Are you reading this? Let me know if you didn't get this.
  28. .
  29. 250 2.0.0 Ok: queued as 0C261A1F0F
  30. quit
  31. 221 2.0.0 Bye
  32. Connection closed by foreign host.

现在请求 Dovecot 来取回你的新消息,使用你的 Linux 用户名和密码登录:

  1. $ telnet studio 110
  2. Trying 127.0.0.1...
  3. Connected to studio.
  4. Escape character is '^]'.
  5. +OK Dovecot ready.
  6. user carla
  7. +OK
  8. pass password
  9. +OK Logged in.
  10. stat
  11. +OK 2 809
  12. list
  13. +OK 2 messages:
  14. 1 383
  15. 2 426
  16. .
  17. retr 2
  18. +OK 426 octets
  19. Return-Path: <tester@test.net>
  20. X-Original-To: carla@studio
  21. Delivered-To: carla@studio
  22. Received: from studio (localhost [127.0.0.1])
  23. by studio.router (Postfix) with ESMTP id 0C261A1F0F
  24. for <carla@studio>; Wed, 30 Nov 2016 17:18:57 -0800 (PST)
  25. Date: November 25, 2016
  26. From: tester@studio.router
  27. Message-ID: first-test
  28. Subject: mail server test
  29. Hi carla,
  30. Are you reading this? Let me know if you didn't get this.
  31. .
  32. quit
  33. +OK Logging out.
  34. Connection closed by foreign host.

花一点时间比较第一个例子中输入的消息和第二个例子中接收的消息。 返回地址和日期是很容易伪造的,但 Postfix 不会被愚弄。大多数邮件客户端默认显示一个最小的标头集,但是你需要读取完整的标头才能查看真实的回溯。

你也可以在你的 ~/Mail/cur 目录中查看你的邮件,它们是普通文本,我已经有两封测试邮件:

  1. $ ls .Mail/cur/
  2. 1480540325.V806I28e0229M351743.studio:2,S
  3. 1480555224.V806I28e000eM41463.studio:2,S

测试 IMAP

我们 Dovecot 同时启用了 POP3 和 IMAP 服务,因此让我们使用 telnet 测试 IMAP。

  1. $ telnet studio imap2
  2. Trying 127.0.1.1...
  3. Connected to studio.
  4. Escape character is '^]'.
  5. * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS
  6. ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
  7. A1 LOGIN carla password
  8. A1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS
  9. ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS
  10. THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT
  11. CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE
  12. QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS
  13. BINARY MOVE SPECIAL-USE] Logged in
  14. A2 LIST "" "*"
  15. * LIST (\HasNoChildren) "." INBOX
  16. A2 OK List completed (0.000 + 0.000 secs).
  17. A3 EXAMINE INBOX
  18. * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
  19. * OK [PERMANENTFLAGS ()] Read-only mailbox.
  20. * 2 EXISTS
  21. * 0 RECENT
  22. * OK [UIDVALIDITY 1480539462] UIDs valid
  23. * OK [UIDNEXT 3] Predicted next UID
  24. * OK [HIGHESTMODSEQ 1] Highest
  25. A3 OK [READ-ONLY] Examine completed (0.000 + 0.000 secs).
  26. A4 logout
  27. * BYE Logging out
  28. A4 OK Logout completed.
  29. Connection closed by foreign host

Thunderbird 邮件客户端

图 1 中的屏幕截图显示了我局域网上另一台主机上的图形邮件客户端中的邮件。

图 1: Thunderbird mail

此时,你已有一个可以工作的 IMAP 和 POP3 邮件服务器,并且你也知道该如何测试你的服务器。你的用户可以在他们设置邮件客户端时选择要使用的协议。如果您只想支持一个邮件协议,那么只需要在您的 Dovecot 配置中留下你要的协议名字。

然而,这还远远没有完成。这是一个非常简单、没有加密的、大门敞开的安装。它也只适用于与邮件服务器在同一系统上的用户。这是不可扩展的,并具有一些安全风险,例如没有密码保护。 我们会在下篇了解如何创建与系统用户分开的邮件用户,以及如何添加加密。


好了,以上就是原文,现在附上我自己的设置。

首先是postfix的main.cf:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
mail_spool_directory = /var/mail
home_mailbox = Maildir/
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = lovexu
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, lovexu.ooo, lovexu, localhost.localdomain, localhost, $mydomain
relayhost = 
mynetworks = 0.0.0.0/0 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
# mynetworks = all
mailbox_command = procmail -a "$EXTENSION"  DEFAULT=$HOME/Maildir/ MAILDIR=$HOME/Maildir
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

之前一直有问题,Maildir/不起作用是因为mailbox_command ,应该写成上文中的代码。

现在是dovecot.conf的设置:

rotocols = pop3 imap
 # 开启pop3 imap listen = *
 default_login_user=postfix
 default_internal_user=postfix
 # 使用postfix 用户
disable_plaintext_auth = no
 log_path = /var/log/dovecot.log
 # 日志路径
#info_log_path = /var/log/dovecot.info
 log_timestamp = "%Y-%m-%d %H:%M:%S "
 ssl = no mail_location =  maildir:~/Maildir
 # 邮件存储路径
mail_privileged_group = mail
 first_valid_uid = 115
 # postfix 用户UID
 protocol pop3 {
 pop3_uidl_format = %08Xu%08Xv
 }
 auth_mechanisms = plain login

passdb {
 driver=sql
 args = /etc/dovecot/dovecot-mysql.conf
 }
 userdb {
 driver=sql
 args = /etc/dovecot/dovecot-mysql.conf
 }
 }

postfix的UID在命令行输入

id postfix

 

新建一个dovecot-mysql.conf,然后修改成你自己的数据库名称及密码。

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=postfixadmin
default_pass_scheme = MD5-CRYPT
password_query = SELECT password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, 502 AS uid, 502 AS gid FROM mailbox WHERE username = '%u'