Perfectly secure Postfix MTA (SMTP) configuration

  • I want to secure my root server (further) service by service, starting with the SMTP service (Postfix MTA) as the most busy one. I the course of setting everything up, I read a lot about security and encryption and tried my best to gather the most valuable pieces of information. However, some issues seem to remain and I can't find anything else to make the configuration perfect.

    Desired Behaviour

    I want the service to be as restrictive as possible, i.e. use secure encryption whenever possible. Authentication should only be allowed after STARTTLS (submission) with secure encryption.

    • Server-to-server communication: highly encrypted, unencrypted only if necessary
    • Client-to-server communication: highly encrypted only
    • Client authentication only at port 587 (optional?)


    The main concern is security, encryption and specifically security related settings for the Postfix MTA. I do not seek advice for anti spam or anti virus solutions -- this is an other matter entirely. E-Mail encryption is no option because the concern is rather privacy than authenticity which ultimately does not justify the unreasonably high client-side effort necessary.

    Current Configuration

    • Server: Debian 7 (Wheezy)
    • MTA: Postfix 2.9.6
    • CaCert certificate: 4096 bit / sha512-RSA

    File /etc/postfix/ excerpt:

    # Incoming
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
    # Outgoing
    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
    # SASL Authentication (dovecot)
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_authenticated_header = yes
    broken_sasl_auth_clients = no
    smtpd_recipient_restrictions =
    # prevent leaking valid e-mail addresses
    disable_vrfy_command = yes

    File /etc/postfix/ excerpt:

    smtp      inet  n       -       -       -       -       smtpd
    submission inet n       -       -       -       -       smtpd
      -o syslog_name=postfix/submission
      -o smtpd_tls_security_level=encrypt
      -o smtpd_sasl_auth_enable=yes
      -o smtpd_client_restrictions=permit_sasl_authenticated,reject

    Open Issues

    • states:

      There is a self-signed certificate in the trust chain [...] There are validity issues for the certificate. Certificates are seldom verified for SMTP servers, so this doesn't mean that STARTTLS won't be used. Generally speaking it's a bad practice not to have a valid certificate, and an even worse practice not to verify them. Any attempted encrypted communication is left all but wide open to Man-in-the-Middle attacks.

      Is this an issue regarding server-to-server communication? If so, is there something I can do to improve this without paying for a certificate? (I have only clients I know personally)

    • The same site states:

      Anonymous Diffie-Hellman is accepted. This is suspectible to Man-in-the-Middle attacks.

      What setting is needed to disable these? (also see next list item)

    • shows issues for port 587:

      --> Testing standard cipher lists
       Anonymous NULL Cipher    offered (NOT ok) 
       Anonymous DH Cipher      offered (NOT ok) 

      This is probably the same issue as the previous item.

    • shows issues for port 25:

      --> Testing Protocols
       SSLv3      offered (NOT ok)
      --> Testing standard cipher lists
       Anonymous NULL Cipher    offered (NOT ok) 
       Anonymous DH Cipher      offered (NOT ok) 
       40 Bit encryption        offered (NOT ok) 
       56 Bit encryption        Local problem: No 56 Bit encryption configured in /usr/bin/openssl 
       Export Cipher (general)  offered (NOT ok) 
       Low (<=64 Bit)           offered (NOT ok) 
       DES Cipher               offered (NOT ok)
       Triple DES Cipher        offered
       Medium grade encryption  offered
      RC4 seems generally available. Now testing specific ciphers...

      Does this only apply to server-to-server communication? If not, how is this possible? At least SSLv3 should be disabled as per the file. How can these issues be resolved?

    • states:

      * - Certificate does not match hostname

      Probably not a security issue per se, yet interesting in combination with item one above. What hostname should I chose if a wildcard-certificate is not okay? or

    • What else can I do to make the configuration perfectly secure?

    "Is there something I can do to improve this without paying for a certificate?" Is "this" just communication with other computers/servers that you control, or also communication from general clients?

    I meant server-to-server communication; I see now, that this might not be an issue at all. I edited the question to make things clearer.

    You could use self-signed certificates and add exceptions to the browsers that your servers are supposed to communicate with. If there will be enough of your servers communicating with enough computers that you control, then [creating your own CA and adding it as a root for the browsers on the computers you control that your servers will be communicating with] might be no less efficient.

    Thanks, that is actually what I do. This would only be an issue if other **servers** (beyond my reach) would refrain from using encrypted channels due to the self-signed certificate.

    Just want to point out that `smtp_tls_mandatory_protocols = !SSLv2, !SSLv3` is worse than useless if you have the security level set to `may`. This will just force the connection to use plaintext. Broken crypto is better than that.

  • Small tangent - SMTP isn't secure, you're only talking about the MTA. TLS certificate validation modes (subject validation) is only a small subset, and doesn't matter if other concerns are addressed. For example, if you use SMIME or PGP, TLS might not matter. It depends on what your threats are.

    You say that TLS is preferred, and unencrypted if necessary. This is known as opportunistic encryption. Most modern MTAs do this.

    Yes, private TLS certificates that are self-signed are common and frequently in use. You don't have to validate the certificate. However, because of multitenancy and other issues, it's impossible to tie the domain name to the certificate itself.

    Do know that if you insist upon TLS connections inbound from a given domain, you will miss out on broadcast emails sent by mass-mailers that are authorized by SPF records. I know several banks that send security alerts via a broadcast service that doesn't use TLS for scalability.

    You're missing AV/AS, content/link scanning, MUA security, whitelisting, DKIM, SPF, DMARC, SMIME, PGP, BATV, directory harvest attacks, ... the list goes on, and on, and on.

    (not relevant to this question or answer, but:) Should your profile also say "Neither is TLS."?

    Thanks for the hint regarding SMTP/MTA, I edited the question to make things clearer. I also added information regarding e-mail encryption (sorry I didn't think of it earlier) and anti spam. I hope I could clear up any confusion.

  • It is important to notice that there is a big difference between public SMTP senders (that can use port 25 and send unencrypted content) and client's submission that is used for authentication and secure client-server content transfer.

    I prefer not to rely on public senders paranoid and security level, however always think about domain users security and user-to-user confidential level.

    First of all, I suggest to create your own CA and sigh server certificate with this root or intermediate certificate, distribute this certificate between users and install as trusted. This will avoid any mitm attacks and secure client to server data exchange. Second - please exclude SSLv2 and lower protocols. I even exclude SSLv3. It is also better to assign acceptable ciphers list. Below is configuration example for postfix.

    smtpd_tls_protocols = !SSLv2,!SSLv3,TLSv1,TLSv1.1,TLSv1.2
    smtpd_tls_mandatory_ciphers =HIGH 

    For unsecure senders, I close recepients list and add spf record to DNS to avoid any relays. You can limit local servers manually by removing them from "mynetworks" or by adding sender restrictions, where local sender addresses will be rejected by default.

    smtp  inet  n  - - - -  smtpd -o content_filter=spamassassin
       -o smtpd_sender_restrictions=permit
       -o smtpd_recipient_restrictions=permit_mynetworks,mysql:/etc/postfix/,reject

    As for the submission part (only for domain users), it is preferable to request encryption that avoids plain passwords to be sent over public unsecure networks.

    submission inet n   -   n   -   -   smtpd
      -o smtpd_enforce_tls=yes
      -o smtpd_tls_security_level=may # (! possible to force, but limits mail clients list and not recommended at all - non standard) -o smtpd_tls_security_level=encrypt
      -o smtpd_sasl_auth_enable=yes
      -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
      -o smtpd_sasl_type=dovecot
      -o smtpd_sasl_path=/var/spool/postfix/private/dovecot-auth
      -o smtpd_sasl_security_options=noplaintext # or (!!! - use according to your paranoid level)  -o smtpd_sasl_security_options=noanonymous
      -o smtpd_recipient_restrictions=mysql:/etc/postfix/,permit_mynetworks,permit_sasl_authenticated,reject_non_fqdn_recipient,reject
      -o smtpd_sasl_authenticated_header=yes

    With presented configuration we get:

    • client to server encryption and port 587 sasl authentification obligation
    • server-to-server tls enabled (but I suggest to use vpn tunnels for infrastructure communication anyway).

    In the submission config, `smtpd_enfore_tls=yes` is overwritten by `smtpd_tls_security_level=may`. I'd argue that setting `smtpd_tls_security_level=encrypt` is the better choice here. That setting should hardly limit *any* MUAs.

    Furthermore, `smtpd_sasl_security_options` is a list of options, so just specifying `noplaintext` would allow anonymous authentication, which is not what you'd want. If encryption is enforced (as it should be), the default value of this parameter is fine. Otherwise `smtpd_sasl_security_options=noplaintext,noanonymous` and `smtpd_sasl_tls_security_options=noanonymous` are somewhat decent settings. Still a good answer, +1.

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM