From c21ebe43aa5c22c350737141f6af4f00060e22f2 Mon Sep 17 00:00:00 2001 From: LanQin Date: Wed, 17 Jun 2026 00:19:40 +0800 Subject: [PATCH] =?UTF-8?q?chore(deploy):=20=E9=85=8D=E7=BD=AE=E5=B7=B2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E9=82=AE=E4=BB=B6=E8=87=AA=E5=8A=A8=E5=BD=92?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为 `submission` 和 `smtps` 启用 `sender_bcc_maps`,将已认证发件人自动抄送到 `发件人+Sent@域名`。 - 补充 Postfix 与 Dovecot 的 `recipient_delimiter` 和 `lmtp_save_to_detail_mailbox` 配置,确保 `Sent` 文件夹可落盘保存。 - 更新部署文档,说明第三方客户端发信后的“已发送”同步流程。 --- deploy/README.md | 1 + deploy/dovecot/dovecot.conf | 2 ++ deploy/postfix/main.cf | 1 + deploy/postfix/master.cf | 2 ++ deploy/postfix/sqlite-sender-bcc.cf | 2 ++ 5 files changed, 8 insertions(+) create mode 100644 deploy/postfix/sqlite-sender-bcc.cf diff --git a/deploy/README.md b/deploy/README.md index a9274d2..3527458 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -128,6 +128,7 @@ docker compose -f docker-compose.stack.yml -f docker-compose.stack.build.yml up - Rspamd 会周期性从 SQLite 导出域名 DKIM 私钥到容器内 `/var/lib/rspamd/dkim`。 - Go API 是 Webmail 和管理后台入口;浏览器不直接连接 SMTP/IMAP/POP3。 - Go API 会读取 `LANQIN_MAILDIR_ROOT=/var/mail/vhosts`,周期扫描 Maildir,把 Postfix/Dovecot 入站邮件同步成 Webmail 索引。 +- 第三方客户端通过 SMTP `465/587` 发信时,Postfix 会把已认证发件人的邮件自动 BCC 到 `发件人+Sent@域名`,Dovecot LMTP 会保存到该邮箱的 `Sent` 文件夹,Webmail 扫描后会显示在“已发送”。 ## 邮件客户端 TLS 证书 diff --git a/deploy/dovecot/dovecot.conf b/deploy/dovecot/dovecot.conf index 056b445..f6690cb 100644 --- a/deploy/dovecot/dovecot.conf +++ b/deploy/dovecot/dovecot.conf @@ -68,4 +68,6 @@ service auth { protocol lmtp { postmaster_address = postmaster@localhost + recipient_delimiter = + + lmtp_save_to_detail_mailbox = yes } diff --git a/deploy/postfix/main.cf b/deploy/postfix/main.cf index 22c8374..749be76 100644 --- a/deploy/postfix/main.cf +++ b/deploy/postfix/main.cf @@ -4,6 +4,7 @@ myorigin = $myhostname mydestination = localhost inet_interfaces = all inet_protocols = all +recipient_delimiter = + # SQLite maps read the same LanQin DB created by the Go API. virtual_mailbox_domains = sqlite:/etc/postfix/sqlite-domains.cf diff --git a/deploy/postfix/master.cf b/deploy/postfix/master.cf index 245305a..e61413e 100644 --- a/deploy/postfix/master.cf +++ b/deploy/postfix/master.cf @@ -4,11 +4,13 @@ submission inet n - n - - smtpd -o smtpd_tls_security_level=may -o smtpd_sasl_auth_enable=yes -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o sender_bcc_maps=sqlite:/etc/postfix/sqlite-sender-bcc.cf smtps inet n - n - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o sender_bcc_maps=sqlite:/etc/postfix/sqlite-sender-bcc.cf pickup unix n - n 60 1 pickup cleanup unix n - n - 0 cleanup qmgr unix n - n 300 1 qmgr diff --git a/deploy/postfix/sqlite-sender-bcc.cf b/deploy/postfix/sqlite-sender-bcc.cf new file mode 100644 index 0000000..d8f967d --- /dev/null +++ b/deploy/postfix/sqlite-sender-bcc.cf @@ -0,0 +1,2 @@ +dbpath = /data/lanqin.db +query = SELECT local_part || '+Sent@' || substr(address, instr(address, '@') + 1) FROM mailboxes WHERE address='%s' AND status='active'