跳转至内容

Courier Mail Server

来自 ArchWiki
(重定向自 Maildrop)

本文或该章节是移动到 HowTo:courier-mta with authuserdb, vmail and IMAP/POP3 的候选。

注意: 特定的设置和令人困惑的页面标题(参见讨论)。(在 Talk:Courier Mail Server 讨论)

本文或本节需要在语言、wiki 语法或风格方面进行改进。请参阅 Help:Style 获取参考。

原因: 使用了不适合 wiki 的语言。这不是博客。(在 Talk:Courier Mail Server 讨论)

Courier MTA 是一个 邮件传输代理 和 POP3/IMAP4 服务器。本文建立在 邮件服务器 的基础上。

Courier-MTA 的优点是

  • MTA 和 POP3/IMAP 的认证都针对同一个数据源
  • 这个数据源可以是 MySQL, PgSQL 或 LDAP,也可以是更简单的 PAM 或编译的明文文件 (BerkeleyDB)
  • 轻松支持虚拟用户
  • 开箱即用的 SMTP-auth
  • 附带 Webmail
  • 支持基于 Web 的管理
  • 如果需要,还附带一个独立的邮件投递代理 (MDA)

前言

接下来的文本描述了一个在单台物理机上设置两个本地域的方案,这对于单用户或小型公司来说并不少见。我们针对一个基于 BerkeleyDB 的 ".dat" 文件进行认证,该文件由 courier 自带的工具自动从一个或多个文本文件中创建。Courier 文档中将此方法描述为 _authuserdb_,所以不要被名称混淆。针对其他提供商的认证会以适当的方式进行,并在 courier-authlibs 文档中有介绍。SASL 方法(如 PLAIN 或 CRAM-MD5)的处理方式会有所不同,具体取决于您喜欢使用哪个认证后端(_authuserd_、_authpam_、_authmysql_ ...)。只是不要期望此设置可以轻松地从描述的 _authuserdb_ 转换为 _authmysql_。

注意 如果您想在本地测试但没有运行 DNS 服务器,那么设置会在某些方面失败,因为 Courier-MTA 至少需要一个 MX 记录才能工作。要解决此问题,您可以从 "abs" 重新编译 courier-mta。在 configure 属性中添加 --without-tcpddns,然后去泡杯咖啡,因为这需要一段时间。然后确保将我们的虚拟域 "domain1" 和 "domain2" 添加到您的 /etc/hosts 文件中。

安装

安装 courier-mtaAUR 包。

任何其他邮件传输代理(如 Cyrus)或 SMTP 服务器(Sendmail, Postfix 等)都必须卸载,所以当提示时回答 'yes'。

TLS

警告 如果您部署 TLS,请确保禁用 SSLv3 以防止 POODLE 漏洞,并遵循 服务器端 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 用户

本文或本节需要在语言、wiki 语法或风格方面进行改进。请参阅 Help:Style 获取参考。

原因: 语言不适合 wiki。这不是博客。(在 Talk:Courier Mail Server 讨论)

我们希望主要将邮件投递给虚拟用户,这样我们就可以轻松创建电子邮件账户而无需创建真实用户。奶奶可能想阅读她的电子邮件,但她不需要 SSH 访问该服务器,对吗?为了实现这一点,我们需要一个“物理”用户,该用户在磁盘上物理拥有我们所有的邮件。请注意,这不是 courier 用户,courier 用户主要用于确保实际服务器进程不以 root 身份运行。许多人将这些东西保存在 /var 中,因为它主要用于这些目的。您可以将用户的“主目录”创建在任何您想要的地方!这个决定将受到您硬盘分区布局的影响。

添加一个名为 "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”。有关这些命令的详细信息,请查阅命令本身的 man 页以及与之链接的 man 页。

  • 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 及其相关(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_。现在,您希望您的服务器通过一个更有意义、甚至更酷的名称从网络上访问,因此您购买(或租用)了一个域名,如 _my-cool-domain.ca_。在这种情况下,设置如下:

locals
localhost
server237.blahfarm.com
hosteddomains
my-cool-domain.ca
project1.my-cool-domain.ca
smtp.my-cool-domain.ca
注意 如果您想拥有像 _info@project1.my-cool-domain.ca_ 这样的电子邮件地址,那么像 _project1.my-cool-domain.ca_ 或 _smtp.my-cool-domain.ca_ 这样的子域也必须包含在 /etc/courier/hosteddomains 中。

要了解这些规范之间的区别,请阅读 makehosteddomains 的 man page。您会发现以下内容适合我们的方法:

# 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
注意 [TAB] 可以通过键入 'Ctrl' + V 然后 'Tab' 来插入。

同样,这些值必须转换为 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”测试环境。现在,当您在 Sylpheed 中创建一个看起来像这样的账户时:姓名:user numberone 地址:user1@domain1 Sylpheed 因此发送邮件时显示为“user numberone <user1@domain1>”。这是错误的,因为它违反了 RFC。您将收到一个错误:517 - Syntax Error。为了测试,您可以通过将 Sylpheed 对话框中的域名设置为:地址:user1@domain1.xx 来欺骗 Courier-MTA。

在这种情况下,也会发生类似的情况(您只会收到错误 513 - Syntax Error)。

+--------------------------+            +------------------------+
|local laptop              |  ------->  |local MTA (courier-mta) |
| sylpheed account         |            | MTA delivers to        |
| user1@domain1.xx sends   |            | user2@domain2          |
| to user2@domain2         |            +------------------------+
+--------------------------+

因为 domain2 无效。您可以发送到 mail.domain2,这样就可以绕过这个问题。对于互联网上的服务器和正确配置的域,这绝对不是问题,因为您始终是一个域的一部分,因此 @ 符号后面总有一个点 (.)。