Courier 邮件服务器
Courier MTA 是一个 邮件传输代理 和带有 Courier 的 POP3/IMAP4 服务器。本文构建于 邮件服务器 之上。
Courier-MTA 的优点是
- MTA 和 POP3/IMAP 的身份验证针对一个数据源进行
- 此数据源可以是 MySQL、PgSQL 或 LDAP,但也可以更简单,例如 PAM 或编译的纯文本文件 (BerkeleyDB)
- 轻松支持虚拟用户
- 开箱即用的 SMTP-auth
- 自带网络邮件
- 可以进行基于 Web 的管理
- 如果需要,还有一个单独的邮件投递代理 (MDA)
序言
以下文本描述了一个物理机上两个本地域的设置,这对于单个用户或小型公司来说并不罕见。我们针对基于 BerkeleyDB 的 ".dat" 文件进行身份验证,该文件由 courier 附带的工具自动从文本或多个文本文件创建。Courier 文档将此方法描述为 authuserdb,因此不要对名称感到困惑。针对其他提供商的身份验证以适当的方式进行,并在 courier-authlibs 文档中介绍。SASL 方法(例如 PLAIN 或 CRAM-MD5)的处理方式存在差异,具体取决于您想要使用的身份验证后端(authuserd、authpam、authmysql ...)。只是不要期望此设置可以从描述的 authuserdb 无痛地转换为 authmysql。
--without-tcpddns
添加到配置属性,然后去煮杯咖啡,因为这将需要一段时间。然后确保将我们的虚拟域名 "domain1" 和 "domain2" 添加到您的 /etc/hosts
中。安装
安装 courier-mtaAUR 软件包。
任何其他邮件传输代理(如 Cyrus)或 SMTP 服务器(Sendmail、Postfix 等)都必须为此卸载,因此当提示时回答“是”。
TLS
您需要 获取证书。
Authuserdb 认证
让 Courier 知道我们要针对 authuserdb 进行身份验证。
在文件 /etc/authlib/authdaemonrc
中找到 authmodulelist=...
,然后删除除 authuserdb 之外的所有列出的模块
authmodulelist="authuserdb" # For test it is useful to set DEBUG_LOGIN from 0 to 2 DEBUG_LOGIN=2
创建 vmail 用户
我们希望主要将邮件投递给虚拟用户,这样我们可以轻松创建电子邮件帐户,而无需创建真实用户。奶奶可能想阅读她的电子邮件,但她不需要对该机器的 ssh 访问,对吗?为了实现这一点,我们需要一个“物理”用户,该用户在驱动器上物理拥有我们所有的邮件。请注意,这不是 courier 用户,courier 用户主要用于确保实际服务器进程不以 root 身份运行。许多人将这些东西保存在 /var
中,因为它主要是为这些东西而设计的。您可以将用户的“home”创建在您想要的任何位置!该决定将受到驱动器分区布局的影响。
添加一个用户 "vmail",他将是所有邮件文件的所有者
# useradd -u 7200 -m vmail # passwd vmail
创建电子邮件账户
虚拟用户及其属性将存储在一个地方。这可以是纯文本文件,也可以是包含多个文本文件的目录。有关详细信息,请参阅 courier-authlib 的文档。基于目录的方法使维护更容易一些,因为我们可以分隔域和子域的用户,因此我们将采用这种方法。目录的名称是不可协商的。
# mkdir /etc/authlib/userdb
“vmail”系统用户的属性也需要存储在此处,因为我们在 /etc/authlib/authdaemonrc
中只允许了 authuserdb。幸运的是,courier 附带了一个方便的脚本,可以将所有本地用户转换为 courier 语法的文件。此文件可以随意命名,我们将其称为 “system”。稍后我们还将为 “domain1” 和 “domain2” 创建文件。明白了吗?
# pw2userdb > /etc/authlib/userdb/system
仅保留 “vmail” 用户(这意味着没有本地用户可以接收电子邮件!)
# sed -n -i "/vmail/p" /etc/authlib/userdb/system
现在我们在身份验证数据库中创建虚拟用户。实际的 Maildir 文件夹必须稍后手动创建。这将创建用户 “user1@domain1” 和 “user2@domain2”。有关这些命令的详细信息,请查看命令本身的手册页以及链接到的手册页。
- user1
# userdb -f /etc/authlib/userdb/domain1 user1@domain1 \ set home=/home/vmail/domain1/user1 uid=7200 gid=7200
让我们为用户设置一个密码(用于 PLAIN 和 LOGIN 和 APOP)
# userdbpw -md5 | userdb -f /etc/authlib/userdb/domain1 user1@domain1 set systempw
以下用于 CRAM-MD5 和 friends(SASL 方法)。另请注意,此构造将密码直接管道传输到命令中,因此可以作为明文读取,但对于创建新用户的 shell 脚本来说可能很方便
# echo 'pwuser1' | userdbpw -hmac-md5 | \ userdb -f /etc/authlib/userdb/domain1 user1@domain1 set hmac-md5pw
- user2(对 user2@domain2 重复)
# userdb -f /etc/authlib/userdb/domain2 user2@domain2 \ set home=/home/vmail/domain2/user2 uid=7200 gid=7200
# userdbpw | userdb -f /etc/authlib/userdb/domain2 user2@domain2 set systempw
# echo 'pwuser2' | userdbpw -hmac-md5 | \ userdb -f /etc/authlib/userdb/domain2 user2@domain2 set hmac-md5pw
设置 Maildirs
我们需要在 “vmail” 系统用户主目录中的硬盘驱动器上创建一个物理位置,作为虚拟用户的 “Maildir”。请注意,“vmail” 用户需要写入权限,并且也将拥有这些文件。以 “vmail” 用户身份创建这些东西是最简单的
成为 “vmail”
# su vmail $ mkdir -p /home/vmail/domain1/user1 && maildirmake /home/vmail/domain1/user1/Maildir $ mkdir -p /home/vmail/domain2/user2 && maildirmake /home/vmail/domain2/user2/Maildir
离开 “vmail” 帐户并成为 root
$ exit
通过键入 exit
(如上所示)离开 “vmail” 帐户,确保您再次成为 root。
创建用户数据库
现在是时候从纯文本文件创建 BerkeleyDB 了。重要的是 /etc/authlib/userdb
中的文件仅对 root 可见。如果它们具有任何世界或组权限,则 courier 将不允许从信息创建 db 文件。
# chmod 700 /etc/authlib/userdb && chmod 600 /etc/authlib/userdb/* # makeuserdb
现在我们可以检查身份验证是否有效。Courier 附带了一个小工具,用于检查用户是否可以进行身份验证。在使用此工具之前,我们必须通过 启用 authdaemond.service
来确保身份验证守护程序正在运行。然后
# authtest user1@domain1 # authtest user2@domain2
如果您在测试身份验证时遇到任何错误,请查阅 这些说明,其中详细介绍了如何使用调试功能来查明问题。
配置 courier
现在我们完成了身份验证方面的工作。它为我们提供了一个灵活的布局,可以轻松扩展。是时候继续进行 courier 本身的配置了。首先,我们将尝试为服务器提供一些别名。别名非常密切地遵循 userdb 的方案。与其他服务器不同,无需在一个文件中处理所有别名。同样,您可以在一个文件夹中创建多个纯文本文件,您可以在其中按域或更精细的结构处理别名(如果您愿意)。文件夹的位置再次不可协商,您必须使用 /etc/courier/aliases
。已经有一个 “system” 文件处理 root、postmaster 和常用的嫌疑对象。只需在现有的 “postmaster: ” 后面添加 “user1@domain1”,即可将所有系统相关邮件传递到 “user1@domain1”。我们只是假设此用户是您的主要帐户。
# cat > /etc/courier/aliases/domain1 << EOALIASES user1@domain1: user1@domain1 user.user1@domain1: user1@domain1 u.user1@domain1: user1@domain1 userer1@domain1: user1@domain1 looser1@domain1: user1@domain1 EOALIASES
对每个域和用户重复此操作,在我们的测试用例中为 user2@domain2。在这里创建另一个方案可能会有所帮助,例如命名您的文件 domain1.user1,这使管理更容易和更透明。这也将有助于基于脚本的自动化管理。
最后,这些别名必须导出到 BerkeleyDB。同样,Courier 附带了一个用于该任务的小实用程序,称为 makealiases
# makealiases
只需检查一切是否正常
# makealiases -chk
设置 localdomain 和 hosteddomains
现在我们需要告诉 courier 谁是这台机器上的谁 —— 我们为谁提供电子邮件服务,以及我们不为谁提供服务。Courier 将其分为以下级别
- locals:这肯定是 localhost,在专用服务器上,您通常是域的一部分,例如 server234.serverfarm.tld
- hosteddomains:对于您托管的域和子域,例如 my-cool-domain.ca,project1.my-cool-domain.ca
例如,假设您在 blahfarm.com 有一台服务器。通常,他们将您的服务器作为其域上的主机。这很可能类似于 server234.blahfarm.com。现在,您希望您的服务器可以通过更具意义甚至更酷的名称从 Web 访问,因此您购买(或租用)一个域名,例如 my-cool-domain.ca。在这种情况下,设置如下所示
- locals
- localhost
- server237.blahfarm.com
- hosteddomains
- my-cool-domain.ca
- project1.my-cool-domain.ca
- smtp.my-cool-domain.ca
/etc/courier/hosteddomains
中要了解这些规范之间的区别,请阅读 makehosteddomains
的手册页。您会发现以下内容适合我们的方法
# echo localhost > /etc/courier/locals # echo server237.blahfarm.com >> /etc/courier/locals # mkdir /etc/courier/hosteddomains # cat > /etc/courier/hosteddomains/domain1 << EODOMAIN1HOSTED domain1 mail.domain1[TAB]domain1 EODOMAIN1HOSTED # cat > /etc/courier/hosteddomains/domain2 << EODOMAIN2HOSTED domain2 mail.domain2[TAB]domain2 EODOMAIN2HOSTED
同样,这些值必须转换为 BerkeleyDB - 使用 courier 命令
# makehosteddomains
在我们继续之前,还需要编写一件事 —— 我们接受邮件的域。在目录 /etc/courier/esmtpacceptmailfor.dir/
中,我们将创建一个名为 domain1
的文件,并在其中键入 domain1
# echo domain1 > /etc/courier/esmtpacceptmailfor.dir/domain1
对 domain2 重复
# echo domain2 > /etc/courier/esmtpacceptmailfor.dir/domain2
最后,转换为 BerkeleyDB
# makeacceptmailfor
...您就完成了。
测试你的设置
现在服务器已准备就绪。让我们在 SMTP 服务器上运行几个测试,看看它是否至少在发送和接收邮件方面运行良好。
############################################################################### # this is a test case suggested on couriers very own webpage, we just convert it # from a local to a virtual user # prepare as vmail su vmail cd ~/domain1/user1 maildirmake bounces && maildirmake test echo "./test" > .courier-test-default echo "./bounces" > .courier # back to root, start the server and finally run the script exit /usr/sbin/courier start /usr/lib/courier/perftest1 1000 "user1@domain1 user2@domain2" ###############################################################################
让我们测试更多有用的东西。
发送普通邮件(以 root 或普通用户身份)
$ echo "To: user2@domain2 From: user1@domain1" | sendmail
发送邮件到别名
$ echo "To: userer2@domain2 From: user1@domain1" | sendmail
发送邮件到外部电子邮件地址
$ echo "To: me_freak@gmail.com From: user1@domain1" | sendmail
配置 IMAP 和 POP3
到目前为止,我们的操作都集中在运行服务器本身的机器上。现在我们需要设置一些与交互相关的配置。由于安全很重要,我们将设置一些不错的身份验证模式,这些模式不会发送明文密码。Courier 支持 CRAM-MD5 等。您必须确保您的客户端也支持它。到目前为止,我使用这些设置测试了 sylpheed-claws > 1.0.4、esmtp 和 Thunderbird。
现在开始,我们将不得不配置几个服务器守护程序。Courier 已经在运行(从上面的 perftest),但它不向网络提供服务。因此,我们必须使用它们在 /etc/courier/<servicename>
中的各自配置文件来配置 esmtpd、pop3d 和 imapd。
由于我们希望使用 SMTPAuth 而不是基于 IP/域的 SMTP 身份验证,因此我们需要在 esmtpd 中激活 AUTHREQUIRED 选项。此外,我们还激活了 CRAM-MD5 质询方法进行授权。注意:此设置绝对可以将 Outlook 失败者拒之门外。对于这些有缺陷且过时的客户端,您将需要使用限制性较小的设置!
在 /etc/courier/esmtpd-ssl
中
AUTH_REQUIRED=1 ESMTPAUTH="CRAM-MD5"
/etc/courier/esmtpd
中设置 AUTH_REQUIRED=1
会阻止通过 smtp 接收来自国外邮件服务器的电子邮件。在 /etc/courier/pop3d
中
POP3AUTH="CRAM-MD5"
imapd 设置略有不同。在 /etc/courier/imapd
中,有一行以 IMAP_CAPABILITY 开头的长行。只需在参数末尾添加 “AUTH=CRAM-MD5”,您就应该完成了
IMAP_CAPABILITY="... AUTH=CRAM-MD5"
备注
由于我们的测试用例非常小,只有两个盒子且没有域控制,因此我们必须查看 Courier 的内在因素并解决一个小问题。Courier 对 RFC 合规性非常挑剔,这意味着您必须确保您了解如何配置您的电子邮件客户端以进行测试。这将在我们的测试中失败
+------------+ +---------------+ +-------------------+ |local laptop| -------> |local box(with | ------------> | MTA somewhere on | +------------+ | courier-mta) | | web | +---------------+ +-------------------+
为什么?因为您从无效的域名发送。我在这里假设我们使用我们的 “domain1” 和 “domain2” testpark。现在,当您在 Sylpheed 中创建一个帐户,如下所示:名称:user numberone 地址:user1@domain1 Sylpheed 因此将邮件作为 “user numberone <user1@domain1>” 发送。这是错误的,因为它违反了 RFC。您会收到错误:517 - 语法错误。对于测试,您可以简单地通过在 sylpheed 的对话框中将域设置为:地址:user1@domain1.xx 来欺骗 Courier-MTA
在这种情况下,也会发生类似的事情(您只会收到错误 513 - 语法错误)
+--------------------------+ +------------------------+ |local laptop | -------> |local MTA (courier-mta) | | sylpheed account | | MTA delivers to | | user1@domain1.xx sends | | user2@domain2 | | to user2@domain2 | +------------------------+ +--------------------------+
因为 domain2 无效。您可以发送到 mail.domain2,这将解决该问题。对于互联网上的盒子和正确配置的域,这绝对没有问题,因为您始终是域的一部分,因此在 @ 后面有一个点 (.)。