跳转至内容

OpenSMTPD

来自 ArchWiki

OpenSMTPD 是一个免费的 邮件传输代理,作为 OpenBSD 项目的一部分进行开发。本文基于 邮件服务器

安装

安装 opensmtpd 包。

配置

OpenSMTPD 在 /etc/smtpd/ 中进行配置。主配置文件是 /etc/smtpd/smtpd.conf;有关其文档,请参见 smtpd.conf(5)

确保使用以下命令测试配置

# smtpd -n

如果收到消息“configuration OK”—您就可以 启动重启 smtpd.service 了。否则,请修复任何配置错误并重试。

本地邮件

要实现本地邮件功能,例如用于 cron 邮件,只需 启动 smtpd.service 即可。

OpenSMTPD 的默认配置是进行本地检索和邮件递送至 Maildir,同时也会中继出站邮件。请参见 smtpd.conf(5)

仅本地邮件

仅用于本地邮件,以下配置就足够了

/etc/smtpd/smtpd.conf
listen on localhost
action "local" maildir alias <aliases>
match for local action "local"

混合模式:本地邮件和中继

/etc/smtpd/smtpd.conf 中的这两行

action "local" maildir alias <aliases>
action "relay" relay host "smtps://smtp.example.net" mail-from "@example.net"
match for local action "local"
match for any action "relay"

将 OpenSMTPD 配置为

  • 将本地电子邮件本地发送,无需通过中继(适用于 cron 和 at 邮件通知)
  • 使用中继将邮件发送到 localhost 之外

只需将 smtp.example.net 替换为您的 ISP 邮件服务器,或您方便的其他服务器。

仅中继

要通过中继发送所有本地电子邮件,请调用 procmail

/etc/smtpd/smtpd.conf
action "local" mda "procmail -f -" virtual <aliases>
action "relay" relay host "smtps://label@smtp.example.net" auth <secrets> mail-from "@example.net"
match for local action "local"
match for any action "relay"

aliases 选项用于本地用户映射,为了简化映射,您可以使用虚拟别名,并带有一个通配符

/etc/smtpd/aliases
@ user@example.net

/var/spool/mail/

OpenSMTPD 6.6.3p1 将默认的本地邮件配置更改为在 ~/Maildir/ 中使用 maildir,而不是在 /var/spool/mail/username 中使用 mbox,以避免安全问题。

要让您的本地邮件转到 /var/spool/mail/username,请在 /etc/smtpd/smtpd.conf 中将 action "local" maildir alias <aliases> 替换为 action "local" maildir "/var/spool/mail/%{user.username}" alias <aliases>

或者,设置 MAIL 环境变量,大多数邮件客户端都支持该变量,使其指向 ~/Maildir/。例如:

export MAIL="${HOME}/Maildir/"

简单的 OpenSMTPD/maildir 配置

TLS

获取证书,请参见 OpenSSL#Usage

注意 OpenSMTPD 具有稳固的默认设置,SSLv3 始终被禁用,且默认的 ciphers 并未被证实不安全。您仍然可能希望按 Server-side TLS 中所述测试服务器。

创建用户账户

  • 为每个所需的邮箱在邮件服务器上创建用户账户。
# useradd -m roger
# useradd -m shirley
  • OpenSMTPD 会将消息递送到用户账户的 maildir 中,位于 /var/spool/mail/username/
  • 如果需要,可以将多个 SMTP 电子邮件地址路由到指定的 maildir。

创建简单的 smtpd.conf 设置

只需九行即可实现一个可用的配置

/etc/smtpd/smtpd.conf
pki mx.domain.example cert         "/etc/smtpd/tls/smtpd.crt"
pki mx.domain.example key          "/etc/smtpd/tls/smtpd.key"

table creds file:/etc/smtpd/creds
table vdoms file:/etc/smtpd/vdoms
table vusers file:/etc/smtpd/vusers

listen on eth0 tls pki mx.domain.example
listen on eth0 port 465 smtps pki mx.domain.example auth <creds>
listen on eth0 port 587 tls-require pki mx.domain.example auth <creds>

action "receive" maildir "/var/spool/mail/%{user.username}" virtual <vusers>
action "send" relay

match from any for domain <vdoms> action "receive"
match for any action "send"

创建表

对于域表文件;每行只输入一个域名

/etc/smtpd/vdoms
example.org
example.com

对于用户表文件;每行列出一个入站 SMTP 电子邮件地址,然后将其映射到 maildir 用户账户名、SMTP 电子邮件地址或两者的任何组合,用逗号分隔。

/etc/smtpd/vusers
roger@example.org          roger
newsletters@example.org    roger,roger.rulz@mail.example

roger@example.com          roger
shirley@example.com        shirley
info@example.com           roger,shirley
contact@example.com        info@example.com

对于 creds 表文件;第一列输入用户名,第二列输入密码哈希

/etc/smtpd/creds
roger                              password_hash_created_using_'smtpctl encrypt'_command
shirley                            password_hash_created_using_'smtpctl encrypt'_command

DKIM

要使用 DomainKeys Identified Mail (DKIM) 对消息进行签名,请安装 opensmtpd-filter-dkimsign

filter-dkimsign(8) 支持 RSA 和 Ed25519 密钥。虽然 RFC 8463 要求验证器支持 Ed25519,但并非所有验证器都支持,因此最好同时使用 Ed25519 和 RSA。

为 DKIM 创建私钥

创建一个用于存储密钥的目录

# install -dm750 -g smtpd /etc/smtpd/dkim

使用 OpenSSL 创建私钥。

Ed25519

# openssl genpkey -algorithm ed25519 -out /etc/smtpd/dkim/dkim_ed25519.key

RFC 8301 要求支持 1024 位到 4096 位的 RSA 密钥,因此创建一个 4096 位 RSA 密钥

# openssl genrsa -out /etc/smtpd/dkim/dkim_rsa4096.key 4096

更改 文件权限,以便以 smtpd 用户和组权限运行的 filter-dkimsign 可以访问它

# chown root:smtpd /etc/smtpd/dkim/dkim_*.key
# chmod 640 /etc/smtpd/dkim/dkim_*.key

准备 DNS 记录

DKIM 使用一个 TXT 记录,域名为 selector._domainkey.domainname,例如 selector1._domainkey.mydomain.example。有关更多详细信息,请参见 Wikipedia:DomainKeys Identified Mail#Verification。以下示例将使用 selector1._domainkey.domain.example 作为 Ed25519 密钥,并使用 selector2._domainkey.domain.example 作为 RSA。

使用以下命令从公钥中获取 DNS 记录值[1]

# openssl pkey -in /etc/smtpd/dkim/dkim_ed25519.key -pubout | openssl asn1parse -offset 12 -noout -out /dev/stdout | openssl base64 | sed '1s/^/v=DKIM1;h=sha256;k=ed25519;p=/'
# openssl pkey -in /etc/smtpd/dkim/dkim_rsa4096.key -pubout | sed '1s/.*/v=DKIM1;h=sha256;k=rsa;p=/;:nl;${s/-----.*//;q;};N;s/\n//g;b nl;'

使用这些值更新您的 DNS 记录。

配置 filter-dkimsign

/etc/smtpd/smtpd.conf 中定义过滤器,并将过滤器链添加到所有 listen 指令中。将 mydomain.example 替换为您的域名,并将 selector1selector2 替换为与您的 DNS 记录匹配的 _domainkey 选择器。

/etc/smtpd/smtpd.conf
...
filter "dkimsign_ed25519" proc-exec "filter-dkimsign -t -a ed25519-sha256 -d mydomain.example -s selector1 -k /etc/smtpd/dkim/dkim_ed25519.key"
filter "dkimsign_rsa4096" proc-exec "filter-dkimsign -t -a rsa-sha256 -d mydomain.example -s selector2 -k /etc/smtpd/dkim/dkim_rsa4096.key"
filter "dkimsign" chain { "dkimsign_ed25519", "dkimsign_rsa4096" }
...
listen on mydomain.example port 465 smtps filter "dkimsign"
listen on socket filter "dkimsign"
...
提示 listen on socket 默认启用,通常不需要手动添加,但在这种情况下,需要添加它以便过滤器可以应用于它。

故障排除

控制台调试

如果在邮件递送过程中遇到问题,请尝试 停止 smtpd.service,然后使用“不守护进程”和“详细输出”选项手动启动守护进程。然后观察控制台以查找错误。

# smtpd -dv

子系统跟踪

添加 -T 标志以获取实时子系统跟踪

# smtpd -dv -T smtp

或者,如果守护进程已在运行,则使用 smtpctl trace subsystem 命令。跟踪输出将出现在上面的控制台输出以及 smtpd.service 的 journalctl 输出中。例如

# smtpctl trace expand && smtpctl trace lookup

…将跟踪别名/虚拟/forward 扩展以及用户/凭据查找。

手动提交端口认证

以 base64 编码用户名和密码

$ printf '\0%s\0%s' 'username' 'password' | base64

使用 openssl s_client 命令连接到提交端口,使用以下命令之一

  • 通过端口 465(隐式 TLS)连接
    $ openssl s_client -host mx.domain.example -port 465
  • 通过端口 587(STARTTLS)连接
    $ openssl s_client -host mx.domain.example -port 587 -starttls smtp

输入 EHLO myhostname,然后输入 AUTH PLAIN。在收到 334 响应后,粘贴上面步骤中的 base64 字符串

250 HELP
EHLO test.domain.example
250-mx.hostname.example Hello test.domain.example [127.0.0.1], pleased to meet you
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SIZE 36700160
250-DSN
250-AUTH PLAIN LOGIN
250 HELP
AUTH PLAIN
334 
dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ=
235 2.0.0: Authentication succeeded

"Helo 命令被拒绝:需要完全限定主机名"

发送电子邮件时,如果收到此类消息,请在 /etc/smtpd/mailname 文件中设置您的 FQDN。否则,服务器名称将从本地 主机名派生,该主机名由 gethostname(3p) 返回,如果它是完全限定域名,则直接使用,或者通过检索关联的规范名称(通过 getaddrinfo(3))。

系统用户认证失败

如果您正在使用系统用户并且使用有效凭据的认证失败,您需要配置 PAM

/etc/pam.d/smtpd
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.