![如何在 Postfix 与 MySQL 中指定目标目录?](https://linux22.com/image/666722/%E5%A6%82%E4%BD%95%E5%9C%A8%20Postfix%20%E4%B8%8E%20MySQL%20%E4%B8%AD%E6%8C%87%E5%AE%9A%E7%9B%AE%E6%A0%87%E7%9B%AE%E5%BD%95%EF%BC%9F.png)
我已经使用 Postfix、Dovecot 和 MySQL 设置了一个邮件服务器。Dovecot 运行正常。Postfix 可以发送邮件,但我在接收邮件时遇到了问题。
经过 2 天的调试和调整配置,我现在能够成功接收邮件。唯一的问题是 Postfix 将邮件保存在错误的位置。我希望将邮件保存在/var/mail/vhosts/domain.tld/user/
目录但[email protected]
邮件保存在/var/mail/vhosts/[email protected]
文件。
/ v a r / m a i l / v h o s t s / u s e r @ d o m a i n . t l d
------------------------------- -----------------------------
^ virtual_mailbox_base ^ ^ sql result from ^
| virtual_mailbox_maps |
--
Postfix 配置
# (postconf -d; postconf -d; postconf -n;) | sort | uniq -u
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
broken_sasl_auth_clients = yes
local_recipient_maps = $virtual_mailbox_maps
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
mydestination = localhost.localdomain, localhost
myhostname = {censored}
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
process_id = 6297
process_id = 6298
readme_directory = no
recipient_delimiter = +
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_tls_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem
smtpd_tls_cert_file = /etc/ssl/certs/mail.roofworkshop.com.crt
smtpd_tls_key_file = /etc/ssl/private/mail.roofworkshop.com.key
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_note_starttls_offer = yes
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
virtual_gid_maps = static:5000
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_uid_maps = static:5000
mysql-虚拟邮箱域.cf
user = mailuser
password = {censored}
hosts = 127.0.0.1
dbname = mailserver
query = SELECT name FROM virtual_domains WHERE name='%s'
mysql-虚拟邮箱地图.cf
user = mailuser
password = {censored}
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM virtual_users WHERE email='%s'
答案1
另一种方法是使用 postfix 中的 mysql 扩展功能。请参阅人5 mysql_table。
这是您的查询的替代版本
query = SELECT '%d/%u/' FROM virtual_users WHERE email='%s';
当输入[电子邮件保护],字符串%d/%u/
将扩展为example.com/user/
。此部分WHERE email='%s'
将限制此查询仅针对有效的用户名。
也可以看看这篇博文获得此扩展的示例。
文档页面的相关摘录
询问 用于搜索数据库的 SQL 查询模板,其中 %s 是 Postfix 尝试解析的地址的替代,例如查询 = SELECT replacement FROM aliases WHERE mailbox = '%s'
此参数支持以下'%'扩展:
%% 它被文字“%”字符替换。
%s 这由输入键替换。SQL 引用用于确保输入键不会添加意外的元字符。
%u 当输入键是 user@domain 形式的地址时,%u 将被 SQL 引用的地址本地部分替换。否则,%u 将被整个搜索字符串替换。如果本地部分为空,则查询将被抑制并且不返回任何结果。
%日 当输入键是 user@domain 形式的地址时,%d 将被 SQL 引用的地址域部分替换。否则,查询将被抑制并且不返回任何结果。
答案2
我使用了一个小技巧来解决这个问题。我更改了mysql-virtual-mailbox-maps.cf
文件如下:
user = mailuser
password = {censored}
hosts = 127.0.0.1
dbname = mailserver
query = SELECT CONCAT(SUBSTRING(email, LOCATE('@', email) + 1), '/', SUBSTRING_INDEX(email, '@', 1), '/') AS `domain` FROM virtual_users WHERE email='%s'
我仍然想知道是否有比这种廉价的解决方法更好的方法。