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? -- Viktor.