I decided to set up some of my mail servers to require certification authentication on the submission port (587). In my case, I want to forward mail from my server at home to my public servers out there on the Internet. I don’t want just anyone to be able to submit mail here, so the easiest way for me do to this was with certification.
I could have done it with IP addresses, but I have a dynamic IP address at home.
I could have done it with my OpenVPN configuration, but I wanted submission to work even if my VPN was not operational.
I started by adding this configuration to master.cf.
See below for the configuration I eventually arrived at. I will explain more about these settings later.
10.2.3.4:submission inet n - n - - smtpd -o smtpd_recipient_restrictions=permit_sasl_authenticated,permit_tls_clientcerts,reject_unauth_destination -o smtpd_tls_req_ccert=yes -o smtpd_tls_auth_only=yes -o smtpd_tls_security_level=encrypt -o smtpd_tls_cert_file=/usr/local/etc/ssl/server.pem -o smtpd_tls_key_file=/usr/local/etc/ssl/supernews.example.org.nopassword.key -o smtpd_client_restrictions=permit_tls_clientcerts -o relay_clientcerts=hash:/usr/local/etc/postfix-config/main/relay_clientcerts -o smtpd_tls_ask_ccert=yes -o smtp_tls_CAfile=/usr/local/etc/ssl/ca.pem -o smtpd_tls_CAfile=/usr/local/etc/ssl/ca.pem
This configuration got me this error message on the client server when trying to submit mail:
Oct 6 23:34:50 cliff postfix/smtp[64233]: 817F83B81: host supernews.example.org[10.2.3.4] refused to talk to me: 421 4.7.1 supernews.example.org Error: Client certificate not trusted
And this message on the receiving server:
Oct 6 23:22:29 supernews postfix/smtpd[77682]: certificate verification failed for pool-10-6-7-8.phlapa.fios.verizon.net[10.6.7.8]: untrusted issuer /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 2 Primary Intermediate Server CA Oct 6 23:22:29 supernews postfix/smtpd[77682]: NOQUEUE: abort: TLS from pool-10-6-7-8.phlapa.fios.verizon.net[10.6.7.8]: Client certificate not trusted
I then followed http://stevejenkins.com/blog/2011/09/how-to-use-a-free-startssl-certificate-in-postfix-for-ssltls/. Pay attention to step 4 on how to get the bundle.
I just did a:
fetch https://www.startssl.com/certs/ca-bundle.pem
Then I started getting getting:
Oct 6 23:38:27 cliff postfix/smtp[64363]: 4735D3B85: host supernews.example.org[10.2.3.4] said: 450 4.1.8: Sender address rejected: Domain not found (in reply to RCPT TO command)
Oh. I know why. My sending server is behind my firewall, and there is no such domain out there on the Internet.
I added this entry to cope with that:
-o smtpd_sender_restrictions=hash:/usr/local/etc/postfix-config/sender_access
And created this file:
# cat /usr/local/etc/postfix-config/sender_access cliff.example.org OK
Then I asked for comments on the Postfix mailing list. I eventually wound up with this configuration:
10.2.3.4:submission inet n - n - - smtpd -o smtpd_recipient_restrictions=permit_tls_clientcerts,reject -o smtpd_tls_req_ccert=yes -o smtpd_tls_auth_only=no -o smtpd_tls_security_level=encrypt -o smtpd_tls_cert_file=/usr/local/etc/ssl/server.pem -o smtpd_tls_key_file=/usr/local/etc/ssl/supernews.example.org.nopassword.key -o smtpd_tls_fingerprint_digest=sha1 -o relay_clientcerts=hash:/usr/local/etc/postfix-config/main/relay_clientcerts -o smtpd_relay_restrictions=permit_tls_clientcerts,reject -o smtpd_tls_CAfile=/usr/local/etc/ssl/ca-bundle.crt -o smtpd_sender_restrictions=$submission_sender_restrictions -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_data_restrictions=
With this file contents (slightly changed to protect myself):
# cat /usr/local/etc/postfix-config/main/relay_clientcerts AA:BB:CC:DD:EE:FF:12:34:56:67:2E:FB:3F:34:99:90:AB:CD:EF:4C cliff.example.org
This is how you can generate this fingerprint:
$ sudo openssl x509 -noout -fingerprint -in /usr/local/etc/ssl/cliff.example.org HA1 Fingerprint=AA:BB:CC:DD:EE:FF:12:34:56:67:2E:FB:3F:34:99:90:AB:CD:EF:4C