# LetsEncrypt and multiple vhosts

## NathanZachary

Hello,

Is anyone currently using LetsEncrypt (the official certbot client or otherwise) to automatically obtain certificates for Apache with multiple vhosts?  I don't particularly like the idea of certbot being able to modify vhost configurations, but would imagine that it's possible to use it just to grab the new certificates every X days and overwrite them.  Does anyone have experience with this process?

Cheers,

Nathan Zachary

----------

## geki

There is good documentation out there. See webroot variant to fetch only certs. On that site you find infos how to use cron to update every ~90 days.

https://certbot.eff.org/docs/using.html#webroot

Since I have dyndns and letsencrypt has rate-limits I added this script to cron to get the certificates somewhen in the future:

```
# crontab -l | grep cert

23 1 */3 * * /root/certonly.sh

# cat /root/certonly.sh 

#!/bin/sh

if [ ! -d /etc/letsencrypt/live ]

then

        rm -vrf /etc/letsencrypt/*

        rm -v /var/log/letsencrypt/letsencrypt.log*

        /usr/bin/yes N | /usr/bin/certbot certonly --webroot -w /var/www/<host1>/htdocs/ -d <domain1> -w /var/www/<host2>/htdocs/ -d <domain2> -m <mail address> --agree-tos --force-interactive

fi

exit 0
```

The 'yes N' command tells certbot(or companies behind it) not to reuse (anonymously?) information about my data. See by executing on cli without 'yes N'.

----------

## Fitzcarraldo

On one of my servers I have more than one vhost running Apache, and use the same Let's Encrypt certificate for them. One vhost is responsible for updating the certificate, and it copies the certificate to the other vhost. I don't use the Let's Encrypt vhost configuration; I just configure the certificate locations in each vhost's config file.

I use a cron job to check for certificate renewal. It does not matter if you check more frequently than every ~90 days; The cron job checks twice-daily, as you can see below in the crontab entry.

```
vhost1user@vhost1:~$ sudo crontab -l | grep -v ^# | grep cert

23 2,14 * * * /usr/local/sbin/certbot-auto renew --renew-hook /home/vhost1user/renew-hook-script.sh --no-self-upgrade >> /var/log/le-renew.log

27 2,14 * * * /home/vhost1user/copy_SSLcerts_to_vhost2.sh 2>> /var/log/le-cp-errors.log
```

The renewal hook shell script makes a time-date stamp record on the vhosts of when the renewal occurred (which also acts as a flag to the other vhost that the renewed certificate files have been copied over) and gracefully restarts Apache on the vhost that renewed the certificate:

```
vhost1user@vhost1:~$ cat renew-hook-script.sh 

#!/bin/bash

# This script will be run by a root crontab job (sudo crontab -e) only once when the SSL certificate is actually renewed.

date > /home/vhost1user/SSLcert_renewed

sshpass -p '<vhost2user's password>' scp /home/vhost1user/SSLcert_renewed vhost2user@vhost2:/home/vhost2user/SSLcert_renewed

/usr/sbin/apachectl graceful
```

The second cron job shown above runs a shell script that copies the renewed certificates to the other vhost:

```
vhost1user@vhost1:~$ cat copy_SSLcerts_to_vhost2.sh

#! /bin/bash

# This script will be run by a root crontab job (sudo crontab -e) to copy the SSL certificates to vhost2.

sshpass -p '<vhost2's password>' scp /etc/letsencrypt/live/<my ddns domain name>/cert.pem vhost2user@vhost2:/home/vhost2user/letsencrypt/cert.pem 2>> /var/log/le-cp-errors.log

sshpass -p '<vhost2's password>' scp /etc/letsencrypt/live/<my ddns domain name>/chain.pem vhost2user@vhost2:/home/vhost2user/letsencrypt/chain.pem 2>> /var/log/le-cp-errors.log

sshpass -p '<vhost2's password>' scp /etc/letsencrypt/live/<my ddns domain name>/privkey.pem vhost2user@vhost2:/home/vhost2user/letsencrypt/privkey.pem 2>> /var/log/le-cp-errors.log
```

On the other vhost I have another cron job to restart Apache on the other host when the certificate files have been copied:

```
vhost2user@vhost2:~$ sudo crontab -l | grep -v ^# | grep cert

28 2,14 * * * /home/vhost2user/restart_apache.sh 2>> /var/log/le-cert-update.log
```

... which runs a shell script to restart gracefully Apache on the other vhost:

```
vhost2user@vhost2:~$ cat restart_apache.sh

#!/bin/bash

# This script will be run by a root crontab job (sudo crontab -e) and will only restart Apache if the SSL certificate has just been renewed.

if [ -f /home/vhost2user/SSLcert_renewed ]; then

    /usr/sbin/apachectl graceful

    rm /home/vhost2user/SSLcert_renewed

    /usr/bin/logger "SSL certificate renewed and Apache restarted"

fi

```

This used to work fine when Let's Encrypt had a few servers, which I could whitelist in the firewall. However, recently Let's Encrypt added a lot more servers. The problem then is that, when the script /usr/local/sbin/certbot-auto tries to renew the certificate, Let's Encrypt then establishes a new inbound connection from a different (and therefore unknown) IP address to your vhost, which is blocked by your firewall. The upshot of all this is that, when I receive a crontab e-mail once every ~90 days from vhost1 telling me that the renewal job failed, I manually disable the firewall temporarily, run the above-mentioned /usr/local/sbin/certbot-auto command to renew the certificate, then re-enable the firewall. I could of course automate this, but I choose not to in case something goes wrong and the firewall does not get re-enabled. I just don't want to risk this happening, as potentially I may be away on a work trip and unable to fix the problem immediately remotely.

----------

## Ant P.

I use le.pl to generate a wildcard cert. I don't like the idea of something messing with my system config files either, it runs as a confined user and the cert is copied out of its home directory afterwards.

Haven't bothered to automate the process yet beyond a cronjob checking the last update and sending warning emails after 70 days, but it's infrequent enough I don't really care about that.

----------

## NathanZachary

Thank you both for your responses!  I guess what I'm wondering here is if it is possible to just pull one certificate and use it across the virtual hosts.  My guess is no, since the FQDNs are different.  So, I would likely need to have a list of the domains that are virtual hosts, and have certbot generate a new cert for each of them once every ~90 days and put it in place.  As long as the name stays the same, no Apache vhost modifications will be necessary.  Does that seem like a feasible plan?

So, for instance, let's say I have domain{1,2,3}.com and they are set up under /etc/apache2/vhosts.d/includes/domain{1,2,3}.com.conf.

The root for each site is /var/www/domains/domain{1,2,3}.com/.

I'm guessing that I could set up a directory for the certificates either under each site (in, say, /var/www/domains/domain{1,2,3}.com/ssl/) or in a location under Apache like /etc/apache2/vhosts/ssl/.

certbot can then generate a certificate for each site and place it in the corresponding directory.

As long as the name of each certificate remains the same, then no Apache modifications/reloads will need to happen.

Does this approach seem valid?

Thanks again for your help!

Cheers,

Nathan Zachary

----------

## Ant P.

It should be possible to use one cert for multiple hosts, that's what I did before wildcards were added. It'll be the same process whether they're subdomains on one host or different domains entirely.

----------

## NathanZachary

 *Ant P. wrote:*   

> It should be possible to use one cert for multiple hosts, that's what I did before wildcards were added. It'll be the same process whether they're subdomains on one host or different domains entirely.

 

That would be amazing if I could use just one certificate for multiple FQDNs/domains/vhosts.  They all hit the same IP, so if that could work, that would be ideal in my opinion (provided they won't throw security errors/warnings).  I could then just have the Apache configs point to the same certificate, which would really help with scaling it out.

I don't see any documentation on how that would work, though.  Looking through the certbot webroot documentation, it looks like I would need to issue the commands for each domain and even each subdomain separately.

----------

## Fitzcarraldo

 *NathanZachary wrote:*   

> That would be amazing if I could use just one certificate for multiple FQDNs/domains/vhosts. They all hit the same IP, so if that could work, that would be ideal in my opinion (provided they won't throw security errors/warnings). I could then just have the Apache configs point to the same certificate, which would really help with scaling it out.

 

https://letsencrypt.org/docs/faq/

 *Let's Encrypt FAQ wrote:*   

> Can I get a certificate for multiple domain names (SAN certificates or UCC certificates)?
> 
> Yes, the same certificate can contain several different names using the Subject Alternative Name (SAN) mechanism.
> 
> Does Let’s Encrypt issue wildcard certificates?
> ...

 

 *NathanZachary wrote:*   

> I don't see any documentation on how that would work, though. Looking through the certbot webroot documentation, it looks like I would need to issue the commands for each domain and even each subdomain separately.

 

https://certbot.eff.org/docs/using.html#certbot-command-line-options

 *Quote:*   

> obtain, install, and renew certificates:
> 
>     (default) run   Obtain & install a certificate in your current webserver
> 
>     certonly        Obtain or renew a certificate, but do not install it
> ...

 

You could use a mechanism similar to the one I outlined in my previous post, to copy the certificate files from the vhost that renews the certificate to the other vhosts.

----------

## Elleni

 *NathanZachary wrote:*   

>  *Ant P. wrote:*   It should be possible to use one cert for multiple hosts, that's what I did before wildcards were added. It'll be the same process whether they're subdomains on one host or different domains entirely. 
> 
> That would be amazing if I could use just one certificate for multiple FQDNs/domains/vhosts.  They all hit the same IP, so if that could work, that would be ideal in my opinion (provided they won't throw security errors/warnings).  I could then just have the Apache configs point to the same certificate, which would really help with scaling it out.
> 
> I don't see any documentation on how that would work, though.  Looking through the certbot webroot documentation, it looks like I would need to issue the commands for each domain and even each subdomain separately.

 

Hi, you describe the setup I have on my webserver, so it is possible with certbot. You initially create one certificate for multiple domains with certbot certonly for all your domains (try those options with --dry-run first), and then renew them with a cronjob (crontab -e) periodically issuing certbot renew and maybe --renew-hook /usr/local/bin/restart_services.sh 

See: https://certbot.eff.org/docs/using.html#webroot

You end up with the following two lines in your vhost configuration files: 

```
SSLCertificateFile /etc/letsencrypt/live/yourdomain/fullchain.pem

SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain/privkey.pem

```

Those are symlinks to the actual certs that are managed by certbot upon renewal.

And certbot will store everything needed for the renewal process in: 

```
/etc/letsencrypt/renewal/yourdomain.conf

```

----------

