Letsencrypt: SAN cert for multiple Virtual Servers

4 posts / 0 new
Last post
#1 Fri, 04/01/2016 - 19:04

Letsencrypt: SAN cert for multiple Virtual Servers

Hey Gurus,

The new fantastic built-in Letsencrypt feature works allright for me (after manually uploading the Let's Encrypt Authority X3 cert as a CA Certificate).

I have a question though: Rather than using different Letsencrypt certs for each Virtual Server, is it possible to use a SAN cert that will cover them all? The reason I'm asking is that having one SAN cert rather than using SNI increases compatibility towards various OS versions and browsers.

Ofc, I tried to do it right away, but it didn't work out. I went to the "Let's Encrypt" tab and added a couple of domain names that are hosted on the same Virtualmin server and it failed to generate and install the Letsencrypt cert. Probably because the validation of the additional domains/Virtual Servers failed.

Can anyone come up with a nice solution/workaround to make this work?


Wed, 04/20/2016 - 07:18

I'm not exactly doing what your looking for, but sharing one certificate across a webmin subdomain, a usermin subdomain, postfix, dovecot and the default document root. I generalized/evolved this setup (CentOS 7 based) based on your question (not thoroughly tested; feedback welcome):

### Problems

  • ACME-Challenge has to work for all domains
  • To register them, all domains must be listed somewhere
  • All domains have to point to the same SSL Cert(s)/Key(s)
  • Auto-renewal has to be set up properly

### Solutions

  • We want to make our life as simple as possible and only want one challenge directory for all domains. Virtual hosts all point to different directory roots, but we can use Apache magic to redirect the /.well-known/acme-challenge/ requests all to the same root (hostname.domain.tld = ServerName):

    # Globally redirect ACME challenges to /var/www/html
    <If "%{HTTP_HOST} != 'hostname.domain.tld'">
      # simpleHttp challenge by default uses HTTP
      Redirect /.well-known/acme-challenge/ http://hostname.domain.tld/.well-known/acme-challenge/
      # If simpleHttp is used with TLS the above may not work.
      # In that case we have to do something like this:
      # (doesn't work for me right now; if someone gets this working please respond)
      #  <If "%{SERVER_PROTOCOL} != 'HTTPS'">
      #    Redirect /.well-known/acme-challenge/ http://hostname.domain.tld/.well-known/acme-challenge/
      #  </If>
      #  <Else>
      #    Redirect /.well-known/acme-challenge/ https://hostname.domain.tld/.well-known/acme-challenge/
      #  </Else>
    It's possible to differentiate this further using RewriteCond/RewriteRule, but previous to Apache 2.4.8 this would require explicitly enabling and inheriting the global configuration in each virtual host.
    # Global Rewrite Rules for ACME challenges
    #RewriteEngine on
    # New in Apache 2.4.8: gets rid of the explicit `RewriteOptions inhert` in every vhost
    # NB: With the right InheritOptions this can also be used to have a global configuration
    #     that can be overridden in selected virtual hosts.
    #RewriteOptions InheritDown
    # HTTP
    #RewriteCond %{SERVER_PORT} !^443$ [OR]
    #RewriteCond %{HTTPS} !=on
    #RewriteCond %{REQUEST_URI} ^/.well-known/acme-challenge/.*
    #RewriteRule ^(.*) http://hostname.domain.tld:80/ [R]
    # HTTPS
    #RewriteCond %{SERVER_PORT} ^443$ [OR]
    #RewriteCond %{HTTPS} =on
    #RewriteCond %{REQUEST_URI} ^/.well-known/acme-challenge/.*
    #RewriteRule ^(.*) https://hostname.domain.tld:443/ [R]
  • Webmin->Webmin Configuration->SSL Encryption->Let's Encrypt: Add all (sub)domains, set document root to /var/www/html and DO NOT (!) copy to webmin and DO NOT (!) enable auto-renewal. These settings are saved in /etc/webmin/webmin/config like this:

  • This should now have created, requested, received and symlinked the certificate and key files to the /etc/letsencrypt/live/host.domain.tld/ directory. They can now be referenced in the usual TLS/SSL configurations.

  • Some further notes:
    1. If the certificate is to be used by Webmin/Usermin the paths have to be adjusted there as well.
    2. Auto-renewal can be set up using a cron script or systemd timer-unit that calls `letsencrypt renew` every now and then (they recommend just running it daily). The letsencrypt client figures out by itself whether or not a certificate is in need of renewal. DO NOT USE WEBMINs/USERMINs AUTO-RENEWAL FOR NOW! (see NB below)

More info about letsencrypt renew:

NB: Webmin auto-renewal AFAIK always creates a completely new key and therefore new subdirectories are created under /etc/letsencrypt/live in a form like host.domain.tld, host.domain.tld-0001, host.domain.tld-0002 and so on. This makes the paths unstable and unfit for use in any configuration. Originally, everything under live is meant to be kept stable and the letsencrypt client changes the symlinks on renewal to the latest files in the archive directory.

EDIT: If you want to add additional domains to an existing cert you also have to use the letsencrypt client for that, as the webmin script would likely also just generate a completely new extra cert in a new sub-directory instead of renewing the previous one properly. Doing this is a bit tedious right now, as you have to list all domains registered on the old certificate and add the new domain like that:

letsencrypt certonly -d host.domain.tld -d host2.domain.tld -d newhost.domain.tld --expand

It's best to keep an .ini file for that, like it's explained here. It should be possible to extract the necessary configuration items from the respective file in /etc/letsencrypt/config/.

Sat, 12/30/2017 - 14:53 (Reply to #2)

Is this still the best practice to support multiple virtual hosts with one let's encrypt renewal?

Has there been no progress on supporting multiple virtual hosts with one let's encrypt auto-renewal?

Thu, 01/04/2018 - 08:02

I put together information from a lot of sources into one HowTo post, perhaps this will help you: https://www.virtualmin.com/node/42012


Topic locked