I'm attempting to configure 2 Postfix 2.10.1 instances, each on separate CentOS 7 systems, to allow certificate-based relay from one system (which we'll call client.example.com) to the other (server.example.com), but I've hit a snag. The server absolutely refuses to accept the relay based on the client's certificate fingerprint.
Here's what I'm working with:
Output of postconf -n on the server:
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
Output of postconf -n on the client:
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
Contents of relay_clientcerts on the server (this matches exactly the fingerprint in the logs and the output of the openssl x509 -fingerprint ...
command):
12:34:56:78:90:AB:CD:EF:FE:DC:BA:09:87:65:43:21:C0:DE:BE:EF client.example.com
Outbound mail being initiated on the client via mail:
mail -s "Hello world" myemail@outside.org
hello world
.
Log output from the server:
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 <myemail@outside.org>: Relay access denied; from=<root@client.example.com> to=<myemail@outside.org> proto=ESMTP helo=<client.example.com>
Nov 30 21:40:39 server postfix/smtpd[7859]: disconnect from client.example.com[192.168.1.1]
Log output from the client:
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=<myemail@outside.org>, 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 <myemail@outside.org>: Relay access denied (in reply to RCPT TO command))
Additional details:
- Both systems have valid certificates signed by my internal CA
- Both systems have valid A and PTR records
- I can successfully query the fingerprint in the relay_clientcerts DB with
postmap -q
- Specifying
smtpd_recipient_restrictions = permit_tls_clientcerts, permit_mynetworks, reject_unauth_destination
andmynetworks = 127.0.0.0/8, 192.168.1.0/24
on the server does allow the client to relay mail through the server with no problem
I've pored over the Postfix documentation, the postfix-users mailing list archive, and Google in general and my configuration appears correct to me (at least correct enough to work). My understanding is that the combination of permit_tls_clientcerts and relay_clientcerts should be sufficient to allow the relay. Obviously, I'm either wrong or just not seeing it.
What am I missing that is preventing the server from allowing the relay based on the client's fingerprint?
Best Answer
I continued to dig around in the Postfix documentation and stumbled on the answer:
In Postfix 2.10, a new configuration parameter called smtpd_relay_restrictions was introduced to address issues where permissive spam-blocking policies in smtpd_recipient_restrictions resulted in permissive relay policies. Per the documentation (http://www.postfix.org/postconf.5.html#smtpd_relay_restrictions), this parameter accepts the same values, and should "preferably" be used to configure the relay policy:
What was not immediately apparent (to me, at least), was that the smtpd_relay_restrictions parameter has a default value of
permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
(as revealed by runningpostconf
with no options), and overrides smtpd_recipient_restrictions completely when it has a non-empty value. From the documentation:The solution, therefore, is to either set smtpd_relay_restrictions to the empty value in main.cf and utilize smtpd_recipient_restrictions as with previous versions, or to configure the relay policy using the new parameter. I chose the latter, and certificate-based relay is now working as expected.