我正在将我们的服务器从 Debian 8 迁移到 Debian 10。现在,我正在尝试设置我们的邮件服务器(postfix-dovecot-mysql)。虽然我能够像这样设置 mysql (MariaDB 10.3) 和 Dovecot 而没有任何重大问题,但我仍然遇到与 postfix (3.4.14) 相同的问题:
所有通过 SMTP 从外部邮件服务器进来的邮件都被拒绝:554 中继访问被拒绝
master.cf(用于 smtp 服务):
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd -v
-o smtpd_sasl_auth_enable=no
我在 main.cf 中的允许/拒绝规则是:
#1 client
smtpd_client_restrictions = permit_mynetworks
permit_sasl_authenticated
reject_unknown_client_hostname
#2 helo
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
#3 sender
smtpd_sender_restrictions = permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_sender_login_mismatch
#4 relay
smtpd_relay_restrictions = reject_non_fqdn_recipient
permit_mynetworks
permit_sasl_authenticated
permit_auth_destination
reject_unauth_destination
#5 recipient
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/mysql/recipient_access.cf
#6 data
smtpd_data_restrictions = reject_unauth_pipelining
另外,我将mydestination设置为空以确保虚拟传输
mydestination =
我已经确认reject_unauth_destination通过设置不同的状态码来触发拒绝:
relay_domains_reject_code = 564
access_map_reject_code = 574
maps_rbl_reject_code = 584
状态码现在始终为564,根据后缀手册,如果拒绝_unauth_destination规则启动,则会触发relay_domains_reject_code。
我不明白的部分(即使经过数小时的反复试验以及互联网研究)是 postfix 似乎忽略了我基于 mysql 的虚拟地图,因为 mysql 日志记录显示没有执行任何查询。我能看到的唯一查询是来自smtpd_recipient_restrictions的返回 OK 的查询。
mail.log显示以下内容:(我刚刚将电子邮件地址设为匿名并屏蔽了 IP 地址):
postfix/smtpd[6963]: >>> START Recipient address RESTRICTIONS <<<
postfix/smtpd[6963]: generic_checks: name=reject_non_fqdn_recipient
postfix/smtpd[6963]: reject_non_fqdn_address: [email protected]
postfix/smtpd[6963]: generic_checks: name=reject_non_fqdn_recipient status=0
postfix/smtpd[6963]: generic_checks: name=permit_mynetworks
postfix/smtpd[6963]: generic_checks: name=permit_mynetworks status=0
postfix/smtpd[6963]: generic_checks: name=permit_sasl_authenticated
postfix/smtpd[6963]: generic_checks: name=permit_sasl_authenticated status=0
postfix/smtpd[6963]: generic_checks: name=permit_auth_destination
postfix/smtpd[6963]: permit_auth_destination: [email protected]
postfix/smtpd[6963]: ctable_locate: leave existing entry key [email protected][email protected]
postfix/smtpd[6963]: generic_checks: name=permit_auth_destination status=0
postfix/smtpd[6963]: generic_checks: name=reject_unauth_destination
postfix/smtpd[6963]: reject_unauth_destination: [email protected]
postfix/smtpd[6963]: permit_auth_destination: [email protected]
postfix/smtpd[6963]: ctable_locate: leave existing entry key [email protected][email protected]
postfix/smtpd[6963]: NOQUEUE: reject: RCPT from x.x.x.x[y.y.y.y]: 564 5.7.1 <[email protected]>: Relay access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<z.z.z.z>
postfix/smtpd[6963]: generic_checks: name=reject_unauth_destination status=2
postfix/smtpd[6963]: >>> END Recipient address RESTRICTIONS <<<
permit_auth_destination检查不会启动- 即使它应该启动,因为(根据后缀手册)如果收件人地址列在virtual_alias_domains或virtual_mailbox_domains中,它就会启动。通过运行,我已经确认在我的情况下两者都是正确的:
[19:00:39][me@server:~]# postmap -q [email protected] proxy:mysql:/etc/postfix/mysql/virtual_alias_domains.cf
recipient.com
[19:00:39][me@server:~]# postmap -q [email protected] proxy:mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
recipient.com
在permit_auth_destination没有启动之后,reject_unauth_destination确实启动了——尽管出于同样的原因它不应该启动。
如前所述,我可以从mysql日志中看到,此时postfix没有执行任何查询。我不知道后缀如何决定不触发permit_auth_destination而是触发reject_unauth_destination。
什么可能导致这种行为?
这是完整的 main.cf:
###########
# Network #
###########
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
#mydomain =
myhostname = mail.server.com
mydestination =
inet_interfaces = all
inet_protocols = ipv4, ipv6
smtp_address_preference = ipv4
smtpd_banner = $myhostname ESMTP $mail_name
#########
# Local #
#########
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
###########
# Virtual #
###########
proxy_read_maps = proxy:mysql:/etc/postfix/mysql/virtual_alias_maps.cf
proxy:mysql:/etc/postfix/mysql/virtual_alias_domains.cf
proxy:mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
proxy:mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
proxy:mysql:/etc/postfix/mysql/recipient_access.cf
virtual_mailbox_base = /home/vmail/mailboxes
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql/virtual_alias_maps.cf
virtual_alias_domains = proxy:mysql:/etc/postfix/mysql/virtual_alias_domains.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_minimum_uid = 5000
local_recipient_maps = $virtual_mailbox_maps
################
# TLS settings #
################
tls_ssl_options = NO_COMPRESSION
################
# TLS outbound #
################
smtp_dns_support_level = dnssec
smtp_tls_security_level = may
proxy:mysql:/etc/postfix/msql/smtp_tls_policy_maps.cf
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_protocols = !SSLv3, TLSv1.3
smtp_tls_ciphers = high
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
###############
# TLS inbound #
###############
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv3, TLSv1.3
smtpd_tls_ciphers = high
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_cert_file = /etc/letsencrypt/getssl-certs/mail.server.com/chain.pem
smtpd_tls_key_file = /etc/letsencrypt/getssl-certs/mail.server.com/key.pem
###################################
# Local mail delivery via Dovecot #
###################################
virtual_transport = lmtp:unix:private/dovecot-lmtp
#############
# SASL auth #
#############
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
#########
# Relay #
#########
#1 client
smtpd_client_restrictions = permit_mynetworks
permit_sasl_authenticated
reject_unknown_client_hostname
#2 helo
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
#3 sender
smtpd_sender_restrictions = permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_sender_login_mismatch
#4 relay
smtpd_relay_restrictions = reject_non_fqdn_recipient
permit_mynetworks
permit_sasl_authenticated
permit_auth_destination
reject_unauth_destination
#5 recipient
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/mysql/recipient_access.cf
#6 data
smtpd_data_restrictions = reject_unauth_pipelining
#7 end-of-data
relay_domains_reject_code = 564
access_map_reject_code = 574
maps_rbl_reject_code = 584
#################
# Miscellaneous #
#################
mail_owner = postfix
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
更新
如果我将virtual_mailbox_domains设置从 proxy:mysql 查找更改为静态值(收件人的域),一切都会按预期工作:
virtual_mailbox_domains = static:recipient.com
看起来通过 mysql 进行的特定查找是问题所在。这特别奇怪,因为问题似乎只存在于smtpd_relay_restrictions(没有执行 mysql 查询)。对于smtpd_recipient_restrictions它工作正常(执行 mysql 查询)
我终于能够通过查看 proxymap 的详细日志来解决这个问题。
交给mysql查询的key其实只是收件人的域,而不是整个email地址:
在这种情况下,似乎%d参数(实际上应该带有域名)不能用于 mysql 查询。使用%s(带有原始输入键)终于奏效了。
我实际上通过仅使用域运行postmap并且没有得到任何结果来意识到%d是空的: