Am 2015-12-11 20:33, schrieb Viktor Dukhovni:
On Fri, Dec 11, 2015 at 11:50:40AM -0600, Brian Sebby wrote:

other.mail.server:smtp  inet    n       -       n       -       0       smtpd
        -o myhostname=other.mail.server
        -o smtp_tls_cert_file=/path/to/certfile.pem
        -o smtpd_tls_cert_file=/path/to/certfile.pem

It seems to work pretty well for us. A wildcard certificate or one with multiple subject alternate names will also work, but those tend to be more
expensive.

Over the years there have from time to time been requests for
server-side SNI support in Postfix, but most users have found
workable alternatives, such as above.

A key reason that SNI support is not there yet, is that we like to
do things right(TM) in Postfix or not at all, and it is not entirely
clear what the "right" configuration interface for server-side SNI
might me (we can ignore implementation difficulties for now).

The main obstacle is that the primary cert/key are as "root" *before*
smtpd(8) drops privileges, while SNI information arrives during
the connection, when smtpd(8) is already running as the unprivileged
"postfix" user, possibly within a chroot jail.  This means that
smtpd(8) would need to arrange to gain access to all requisite keys
and certificates while still running root during process startup.

Now we certainly don't want to pay the cost of loading all the
certificates and keys into memory, so the options are perhaps:

  1. Use a table lookup that maps domain names (or domain name
     suffixes) to base64-encoded chain (PKCS#7) and key (PKCS#8)
     objects.  The table would be a "cdb" or "lmdb" database owned
     by root, mode 0[46]00.

        example.com
        
chain=MIIByQYJKoZIhvcNAQcCoIIBujCCAbYCAQExADALBgkqhkiG9w0BBwGgggGcMIIBmDCCAT6gAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xNTEyMTExODUyMDlaFw0xNjAxMTAxODUyMDlaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEb2rusHCpKLrDj0tOIqr+g22Iq9eDg4atYtRhKVas6ve2L9o9d3cRnnGIt9qTJV3E6vjvGfxBPV6q+H14Q8XDbqN9MHswHQYDVR0OBBYEFELpnC1wAEKrfE2xJuRt/lX6FF2MMB8GA1UdIwQYMBaAFELpnC1wAEKrfE2xJuRt/lX6FF2MMAwGA1UdEwQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDSAAwRQIgRtBQtdE4AGJozAVkGs81uYW/KVBquoHYBP7XxBC/z6YCIQDXzLBOw5ivFiWf1a/9tl1ddHL0IWYBX61NM0clM/oDJqEAMQA=
        
key=MHcCAQEEIMoR3bMT+b2/5NCa/ZGZom/a3cMoE1wGu+awdw8pOII2oAoGCCqGSM49AwEHoUQDQgAEb2rusHCpKLrDj0tOIqr+g22Iq9eDg4atYtRhKVas6ve2L9o9d3cRnnGIt9qTJV3E6vjvGfxBPV6q+H14Q8XDbg==

     The PKCS#12 content would be protected by file-system permissions,
     not a password.  The smtpd(8) server is not a human, and any
     required password would have to be stored along with the
     certificates.  In such cases, since passwords are not optional
     with PKCS#12, I tend to use passwords such as "umask 077",
     which convey where the effective security lies.

     There would need to be a tool that "compiles" a directory
     of PKCS#12 files into such a table.

  2. Leave the keys and certificates in files, and use strong
     passphrases for the keys, but configure smtpd(8) with a root
     owned table (mode 0[46]00) that maps domains or domain suffixes
     to a (password, key, chain) triple.

        # Filenames are relative to the queue directory, because
        # that's the chroot jail.
        #
        example.com
            pw=ABLLUpNBh8eakVs4Qinv,
            key=sni/example.com.pem,
            chain=sni/example.com.pem

     The private key files would then be owned by "postfix" (mode
     0400) and protected from other non-privileged Postfix processes
     via the associated strong passwords.

     example.com.pem:

         -----BEGIN ENCRYPTED PRIVATE KEY-----
         MIHeMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAiCQc48rR0diwICCAAw
         HQYJYIZIAWUDBAECBBCwIPRri8y1TOo872zl1It/BIGQfPsiJk83asYBOgJ60a44
         IBq1v/wSE9v8yD9jTq8Cb/jQBvie9tdMSCr8xjwVlvC/vDfbNx6W+d3wjQRM6rzY
         sXWVBeSb2TzxKGfZ9xD9ejZhUGXADIYsuoUDfZlz3vl6htViq7sjYWL8Dgz/PDit
         Sf4Rk1tiqV3cnFMY2OgQz06HGn0U22elq2MpYExL3BCz
         -----END ENCRYPTED PRIVATE KEY-----
         -----BEGIN CERTIFICATE-----
         MIIBmDCCAT6gAwIBAgIBATAKBggqhkjOPQQDAjAWMRQwEgYDVQQDDAtleGFtcGxl
         LmNvbTAeFw0xNTEyMTExODUyMDlaFw0xNjAxMTAxODUyMDlaMBYxFDASBgNVBAMM
         C2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEb2rusHCpKLrD
         j0tOIqr+g22Iq9eDg4atYtRhKVas6ve2L9o9d3cRnnGIt9qTJV3E6vjvGfxBPV6q
         +H14Q8XDbqN9MHswHQYDVR0OBBYEFELpnC1wAEKrfE2xJuRt/lX6FF2MMB8GA1Ud
         IwQYMBaAFELpnC1wAEKrfE2xJuRt/lX6FF2MMAwGA1UdEwQFMAMBAf8wEwYDVR0l
         BAwwCgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0E
         AwIDSAAwRQIgRtBQtdE4AGJozAVkGs81uYW/KVBquoHYBP7XxBC/z6YCIQDXzLBO
         w5ivFiWf1a/9tl1ddHL0IWYBX61NM0clM/oDJg==
         -----END CERTIFICATE-----

Beyond that, support for this may require sufficiently recent
OpenSSL releases (1.0.2 is enough, 1.0.1 may suffice), as the
server-side SNI interface is IIRC a pain to work with in older
releases.

So the question is whether either interface proposal is usable and
desirable.  Is there a better way to do this?

From an operational standpoint, I like solution 2 more than solution 1. However, from a security standpoint, it looks like the opposite is better since another non-privileged Postfix process is not able to access the private key.

Michael

Reply via email to