Postfix 2.10基于客户端证书的中继

我试图在单独的CentOS 7系统上configuration2个Postfix 2.10.1实例,以允许从一个系统(我们称之为client.example.com )到另一个系统( server.example.com )的基于证书的中继),但我碰到了一个障碍。 服务器绝对拒绝接受基于客户端证书指纹的中继。

以下是我正在处理的内容:

服务器上输出postconf -n:

alias_database = hash:/etc/aliases alias_maps = hash:/etc/aliases command_directory = /usr/sbin config_directory = /etc/postfix daemon_directory = /usr/libexec/postfix data_directory = /var/lib/postfix debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 html_directory = no inet_interfaces = all inet_protocols = ipv4 local_recipient_maps = mail_owner = postfix mailq_path = /usr/bin/mailq.postfix manpage_directory = /usr/share/man mydestination = localhost mydomain = example.com myhostname = server.example.com mynetworks = 127.0.0.0/8 newaliases_path = /usr/bin/newaliases.postfix queue_directory = /var/spool/postfix readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES relay_clientcerts = hash:/etc/postfix/relay_clientcerts relayhost = [192.168.1.3] sample_directory = /usr/share/doc/postfix-2.10.1/samples sendmail_path = /usr/sbin/sendmail.postfix setgid_group = postdrop smtpd_recipient_restrictions = permit_tls_clientcerts, reject_unauth_destination smtpd_tls_CAfile = /etc/pki/tls/certs/cacert.pem smtpd_tls_ask_ccert = yes smtpd_tls_cert_file = /etc/pki/tls/certs/server.example.com.crt smtpd_tls_fingerprint_digest = sha1 smtpd_tls_key_file = /etc/pki/tls/private/server.example.com.key smtpd_tls_loglevel = 2 smtpd_tls_received_header = yes smtpd_tls_security_level = may tls_random_source = dev:/dev/urandom unknown_local_recipient_reject_code = 550 

客户端上输出postconf -n:

 alias_database = hash:/etc/aliases alias_maps = hash:/etc/aliases command_directory = /usr/sbin config_directory = /etc/postfix daemon_directory = /usr/libexec/postfix data_directory = /var/lib/postfix debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 html_directory = no inet_interfaces = localhost inet_protocols = all mail_owner = postfix mailq_path = /usr/bin/mailq.postfix manpage_directory = /usr/share/man mydestination = $myhostname, localhost.$mydomain, localhost newaliases_path = /usr/bin/newaliases.postfix queue_directory = /var/spool/postfix readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES relayhost = [server.example.com] sample_directory = /usr/share/doc/postfix-2.10.1/samples sendmail_path = /usr/sbin/sendmail.postfix setgid_group = postdrop smtp_tls_CAfile = /etc/pki/tls/certs/cacert.pem smtp_tls_cert_file = /etc/pki/tls/certs/client.example.com.crt smtp_tls_fingerprint_digest = sha1 smtp_tls_key_file = /etc/pki/tls/private/client.example.com.key smtp_tls_loglevel = 3 smtp_tls_note_starttls_offer = yes smtp_tls_security_level = may tls_random_source = dev:/dev/urandom unknown_local_recipient_reject_code = 550 

服务器上relay_clientcerts的内容(这与日志中的指纹以及openssl x509 -fingerprint ...命令的输出完全匹配):

 12:34:56:78:90:AB:CD:EF:FE:DC:BA:09:87:65:43:21:C0:DE:BE:EF client.example.com 

通过邮件在客户端启动出站邮件

 mail -s "Hello world" [email protected] hello world . 

日志输出从服务器:

 Nov 30 21:40:39 server postfix/smtpd[7859]: client.example.com[192.168.1.1]: subject_CN=client.example.com, issuer=ca.example.com, fingerprint=12:34:56:78:90:AB:CD:EF:FE:DC:BA:09:87:65:43:21:C0:DE:BE:EF, pkey_fingerprint=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX Nov 30 21:40:39 server postfix/smtpd[7859]: Trusted TLS connection established from client.example.com[192.168.1.1]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Nov 30 21:40:39 server postfix/smtpd[7859]: NOQUEUE: reject: RCPT from client.example.com[192.168.1.1]: 454 4.7.1 <[email protected]>: Relay access denied; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<client.example.com> Nov 30 21:40:39 server postfix/smtpd[7859]: disconnect from client.example.com[192.168.1.1] 

来自客户端的日志输出:

 Nov 30 21:40:39 client postfix/smtp[15525]: server.example.com[192.168.1.2]:25: subject_CN=server.example.com, issuer_CN=ca.example.com, fingerprint=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX, pkey_fingerprint=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX Nov 30 21:40:39 client postfix/smtp[15525]: Trusted TLS connection established to server.example.com[192.168.1.2]:25: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) Nov 30 21:40:39 client postfix/smtp[15525]: 563502306537: to=<[email protected]>, relay=server.example.com[192.168.1.2]:25, delay=431, delays=430/0.02/0.07/0.11, dsn=4.7.1, status=deferred (host server.example.com[192.168.1.2] said: 454 4.7.1 <[email protected]>: Relay access denied (in reply to RCPT TO command)) 

额外细节:

  • 两个系统都有由我的内部CA签署的有效证书
  • 两个系统都有有效的A和PTRlogging
  • 我可以使用postmap postmap -q成功查询relay_clientcerts数据库中的指纹
  • 在服务器指定smtpd_recipient_restrictions = permit_tls_clientcerts, permit_mynetworks, reject_unauth_destinationmynetworks = 127.0.0.0/8, 192.168.1.0/24 确实允许客户端通过服务器中继邮件,而没有任何问题

我对Postfix文档,postfix-users邮件列表存档和Google进行了详细的介绍,而且我的configuration似乎对我来说是正确的(至less可以正确工作)。 我的理解是,permit_tls_clientcerts和relay_clientcerts的组合应该足以允许中继。 显然,我是错的,或者只是没有看到它。

我错过了什么防止服务器允许基于客户端指纹的中继?

我继续在Postfix文档中进行挖掘,偶然发现了答案:

在Postfix 2.10中,引入了一个名为smtpd_relay_restrictions的新configuration参数,用于解决smtpd_recipient_restrictions中允许的垃圾邮件阻止策略导致允许的中继策略的问题。 根据文档( http://www.postfix.org/postconf.5.html#smtpd_relay_restrictions ),该参数接受相同的值,应该“最好”用于configuration中继策略:

从Postfix 2.10开始,中继权限规则最好使用smtpd_relay_restrictions来实现,这样smtpd_recipient_restrictions下的允许垃圾邮件阻止策略将不再导致允许的邮件中继策略。

指定一个由逗号和/或空格分隔的限制列表。 通过用空格开始下一行继续较长的行。 smtpd_recipient_restrictions中提供了相同的限制。

什么是不明显的(对我来说,至less),是smtpd_relay_restrictions参数有一个默认值的permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination (通过运行postconf没有选项显示),并且完全覆盖smtpd_recipient_restrictions,当它有一个非空值。 从文档:

为了向后兼容,在2.10之前从Postfix版本迁移的站点可以将smtpd_relay_restrictions设置为空值,并像以前一样使用smtpd_recipient_restrictions。

因此,解决scheme是将smtpd_relay_restrictions设置为main.cf中的空值,并像以前的版本一样使用smtpd_recipient_restrictions ,或使用新参数configuration中继策略。 我select了后者,基于证书的中继现在按预期工作。