By default, Postfix does not encrypt outgoing e-mails. In case of a man-in-the-middle-attacks, this can be a security issue.
By setting the following parameter in /etc/postfix/main.cf, all outgoing e-mails (to any destination) will be encrypted with TLS:
smtp_tls_security_level = encrypt
But this brings another problem: Many mail servers do not accept TLS connections. E-mails to such mail servers will therefore not be sent.
As an alternative, one can set smtp_tls_security_level = may - with this setting, TLS encryption is only used, if the recipient server accepts TLS connections.
In some circumstances, it is necessary to enforce certain TLS connections to specific domains. That's what I had to do today.
While looking through the Postfix documentation, I got aware of the TLS Policy Table. This setting allows to define TLS connections on a per-domain basis.
Example: One wants to enforce TLS on all e-mails sent to *@example.com. The MX of example.com is receive.example.com.
First, create the tls_policy file and enter the specific domain followed by the TLS option. Then create the hash database of that file:
# touch /etc/postfix/tls_policy
# echo "example.com encrypt" > /etc/postfix/tls_policy
# postmap /etc/postfix/tls_policy
Now you need to tell Postfix to use a TLS Policy Table. You define that in /etc/postfix/main.cf:
# cat /etc/postfix/main.cf | grep tls_policy
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
Reload Postfix (restart is not necessary), to use TLS Policy Table:
# /etc/init.d/postfix reload
Let's see how it looks in the logs, when Postfix sends an e-mail (debug_peer activated).
LOG OUTPUT WITHOUT TLS:
postfix/pickup[28256]: 4CAEB11560005: uid=0 from=
postfix/cleanup[28257]: 4CAEB11560005: message-id=<20120803074914.4CAEB11560005@send.example.com>
postfix/qmgr[28259]: 4CAEB11560005: from=
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 220 area-1.ch ESMTP Postfix (Debian/GNU)
postfix/smtp[28260]: > send.example.com[192.168.10.20]:25: EHLO send.example.com
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-area-1.ch
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-PIPELINING
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-SIZE 36700160
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-VRFY
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-ETRN
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-STARTTLS
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-AUTH PLAIN LOGIN
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-ENHANCEDSTATUSCODES
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250-8BITMIME
postfix/smtp[28260]: < receive.example.com[192.168.10.10]:25: 250 DSN
postfix/smtp[28260]: server features: 0x901f size 36700160
postfix/smtp[28260]: Using ESMTP PIPELINING, TCP send buffer size is 4096
postfix/smtp[28260]: > send.example.com[192.168.10.20]:25: MAIL FROM:
...
LOG OUTPUT WITH TLS:
postfix/pickup[28066]: 4057311560005: uid=0 from=
postfix/cleanup[28067]: 4057311560005: message-id=<20120803074748.4057311560005@send.example.com>
postfix/qmgr[28069]: 4057311560005: from=
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 220 area-1.ch ESMTP Postfix (Debian/GNU)
postfix/smtp[28070]: > send.example.com[192.168.10.20]:25: EHLO send.example.com
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-area-1.ch
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-PIPELINING
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-SIZE 36700160
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-VRFY
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-ETRN
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-STARTTLS
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-AUTH PLAIN LOGIN
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-ENHANCEDSTATUSCODES
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250-8BITMIME
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 250 DSN
postfix/smtp[28070]: server features: 0x901f size 36700160
postfix/smtp[28070]: Using ESMTP PIPELINING, TCP send buffer size is 4096
postfix/smtp[28070]: > send.example.com[192.168.10.20]:25: STARTTLS
postfix/smtp[28070]: < receive.example.com[192.168.10.10]:25: 220 2.0.0 Ready to start TLS
postfix/smtp[28070]: send attr request = lookup
postfix/smtp[28070]: send attr cache_type = smtp
postfix/smtp[28070]: send attr cache_id = smtp:192.168.10.10:25:area-1.ch&p=1&c=ALL:!EXPORT:!LOW:+RC4:@STRENGTH:!eNULL
postfix/smtp[28070]: private/tlsmgr: wanted attribute: status
...
Note that the sending server "tells" the recipient server (area-1.ch) to use TLS (STARTTLS) and area-1.ch confirms. This is then followed by the TLS encryption itself.
As I've defined "encrypt" as TLS option, this means, that TLS is enforced and all server certificates of the recipient server are accepted, including self-signed certificates.
If you're suspicious, you can set the TLS option to the highest value: secure. With secure, the server certificate on the recipient side MUST be verified by a known Certificate Issuer (e.g. VeriSign), otherwise the mail will not be sent and will stay in the mail queue:
...
postfix/smtp[28515]: input attribute value: z0FpDdCLPEJc225tMd0BI5CHP28PkTUD36/TT+YU5bI=
postfix/smtp[28515]: private/tlsmgr: wanted attribute: (list terminator)
postfix/smtp[28515]: input attribute name: (end)
postfix/smtp[28515]: certificate verification failed for receive.example.com[192.168.10.10]:25: untrusted issuer /C=CH/ST=Geneva /L=Geneva/O=Claudio Kuenzler/OU=Claudio Kuenzler/CN=receive.example.com
postfix/smtp[28515]: send attr request = update
postfix/smtp[28515]: send attr cache_type = smtp
postfix/smtp[28515]: send attr session = [data 1712 bytes]
...
# mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
5626511560005 330 Fri Aug 3 09:50:15 root@send.example.com
(Server certificate not trusted)
recipient@receive.example.com
Sebastian from Germany wrote on Dec 1st, 2015:
Thanks, it works well but I needed to add the domain from "tls_policy" to "transport" file to get it to work. Otherwise postfix sends all mails to our standard relay host.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office OpenSearch PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder