About Archive Tags RSS Feed

 

Entries tagged letsencrypt

I jumped on the SSL-bandwagon

4 December 2015 21:50

Like everybody else on the internet today was the day I started rolling out SSL certificates, via let's encrypt.

The process wasn't too difficult, but I did have to make some changes. Pretty much every website I have runs under its own UID, and I use a proxy to pass content through to the right back-end.

Running 15+ webservers feels like overkill, but it means that the code running start.steve.org.uk cannot read/modify/break the code that is running this blog - because they run as different UIDs.

To start with I made sure that all requests to the top-level /.well-known directory were shunted to a local directory - via this in /etc/apache2/conf-enabled/well-known.conf:

Alias /.well-known/ /srv/well-known/

<Directory "/srv/well-known/">
    ForceType text/plain
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
    AuthType None
    Require all granted
</Directory>

Then configured each proxy to avoid forwarding that path to the back-ends, by adding this to each of the individual virtual-hosts that run proxying:

<Proxy *>
  Order allow,deny
  Allow from all
</Proxy>
ProxyPass /.well-known !
ProxyPass        / http://localhost:$port/
..

Then it came to be time to actually generate the certificates. Rather than using the official client I used a simpler one that allowed me to generate requests easily:

CSR=/etc/apache2/ssl/csr/
KEYS=/etc/apache2/ssl/keys/
CERTS=/etc/apache2/ssl/certs/

# generate a key
openssl genrsa 4096 > $KEYS/lumail.key

# make a CSR
openssl req -new -sha256 -key $KEYS/lumail.key -subj "/" -reqexts SAN \
   -config <(cat /etc/ssl/openssl.cnf \
   <(printf "[SAN]\nsubjectAltName=DNS:www.lumail.org,DNS:lumail.org")) \
   > $CSR/lumail.csr

# Do the validation
acme_tiny.py --account-key ./account.key --csr $CSR/lumail.csr \
  --acme-dir /srv/well-known/acme-challenge/ > $CERTS/lumail.crt.new

And then I was done. Along the way I found some niggles:

  • If you have a host that listens on IPv6 only you cannot validate your request - this seems like a clear failure.
  • It is assumed that you generate all your certificates in their live-location. e.g. You cannot generate a certificate for foo.example.com on the host bar.example.com.
  • If you forward HTTP -> HTTPS the validation fails. I had to setup rewrite rules to avoid this, for example lumail.org contains this:
    • RewriteEngine On
    • RewriteCond %{REQUEST_URI} !^/.well-known
    • RewriteRule ^/(.*) https://lumail.org/$1 [L]

The first issue is an annoyance. The second issue is a real pain. For example *.steve.org.uk listens on one machine except for webmail.steve.org.uk. Since there are no wildcards created a single certificate with Alt-names for a bunch of names such as:

  • ..
  • blog.steve.org.uk
  • start.steve.org.uk
  • ..

Then seperately create a certificate for the webmail host - which I've honestly not done yet.

Still I wrote a nice little script to generate SSL for a number of domains, with different Alt-Names, wrapping around the acme_tiny.py script, and regenerating all my deployed certificates is now a two minute job.

(People talk about renewing certificates. I don't see the gain. Just replace them utterly every two months and you'll be fine.)

| 10 comments