from wiki
This commit is contained in:
parent
954c674076
commit
45a510fd3b
1 changed files with 187 additions and 0 deletions
187
pages/AcmeTinyUbuntu.md
Normal file
187
pages/AcmeTinyUbuntu.md
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
# Using acme_tiny.py with LetsEncrypt on a Ubuntu Apache 2.4 System
|
||||
|
||||
In this example, I use ca.rpki.net as the instance name. Of course you will want to change that.
|
||||
|
||||
## Preparation
|
||||
|
||||
As strongly advised in the [acme_tiny README.md](https://github.com/diafygi/acme-tiny/blob/master/README.md), create a separate user acme, in which to do all this.
|
||||
|
||||
To keep things tidy, I create three sub-directories
|
||||
|
||||
```
|
||||
cd
|
||||
mkdir work secrets challenges
|
||||
chmod 750 work
|
||||
# protect secrets
|
||||
chmod 700 secrets
|
||||
chmod 750 challenges
|
||||
```
|
||||
|
||||
challenges has to be readable by the web server, but this hack can only be done by root
|
||||
|
||||
```
|
||||
chown acme:www-data /home/acme/challenges
|
||||
```
|
||||
|
||||
I do not have git on small machines, so just grab the code with fetch. Being lazy, I just fetch the source into /home/acme.
|
||||
|
||||
```
|
||||
curl https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py > acme_tiny.py
|
||||
chmod 700 acme_tiny.py
|
||||
```
|
||||
|
||||
## LetsEncrypt Account Key
|
||||
|
||||
I use the same LetsEncrypt account key for all servers. so I copy it
|
||||
|
||||
```
|
||||
rsync <somewhere>:/home/acme/secrets/account.key /home/acme/secrets
|
||||
chmod 600 /home/acme/secrets/account.key
|
||||
```
|
||||
|
||||
If you do not already have a Let's Encrypt account key, generate one per the README.md.
|
||||
|
||||
```
|
||||
openssl genrsa 4096 > /home/acme/secrets/account.key
|
||||
chmod 600 /home/acme/secrets/account.key
|
||||
```
|
||||
|
||||
If you generate an account key, keep it very safe and use it for all LetsEncrypt transactions from now on.
|
||||
|
||||
## Domain Private Key
|
||||
|
||||
The domain private key will be the server's TLS private key, and should be protected. Generate it as described in the README.md. It remains constant for the initial use and subsequent certificate refresh requests.
|
||||
|
||||
```
|
||||
openssl genrsa 4096 > /home/acme/secrets/domain.key
|
||||
chmod 600 /home/acme/secrets/domain.key
|
||||
```
|
||||
|
||||
## Generate the Certificate Request
|
||||
|
||||
As described in the README.md, generate the certificate request. It remains constant for the initial use and subsequent certificate refresh requests.
|
||||
|
||||
```
|
||||
openssl req -new -sha256 -key /home/acme/secrets/domain.key -subj "/CN=ca.rpki.net" > /home/acme/work/domain.csr
|
||||
```
|
||||
|
||||
If the web site virtualizes multiple domains,
|
||||
|
||||
```
|
||||
cat /etc/ssl/openssl.cnf |
|
||||
awk '
|
||||
{print}
|
||||
END {
|
||||
print "[SAN]";
|
||||
print "subjectAltName=DNS:permatrac.sql1.ietf.org,DNS:etherpad.sql1.ietf.org,DNS:tickets.meeting.ietf.org";
|
||||
}' |
|
||||
openssl req -new -sha256 -key secrets/domain.key -subj "/" \
|
||||
-reqexts SAN -config /dev/stdin -out work/domain.csr
|
||||
```
|
||||
|
||||
## Configure Apache to Provide Proof of Ownership
|
||||
|
||||
Now is the worst part, configuring Apache 2.4. LetsEncrypt will send a challenge nonce that we have to store where they can subsequently GET it from the web server for the domain being registered. acme_tiny.py uses what it calls a challenge directory. It must be writable by the acme_tiny.py script and readable by the web server; hence the perms and ownership used above.
|
||||
|
||||
LetsEncrypt fetches the challenge over port 80 from a URL of [http:your.domain/.well-known/acme-challenge/]. So we need to configure the apache server to make the challenge data readable on port 80. This takes me from 15 minutes ot an hour to sort out. If you can suggest how to make this simpler, please do.
|
||||
|
||||
I created an acme.conf
|
||||
|
||||
```
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
# remember to enable this
|
||||
Listen 80
|
||||
|
||||
Alias /.well-known/acme-challenge "/home/acme/challenges"
|
||||
DocumentRoot "/home/acme/challenges"
|
||||
<Directory "/home/acme/challenges">
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName archive.psg.com
|
||||
ServerAdmin randy@psg.com
|
||||
<LocationMatch "^(?!/\.well-known/acme-challenge/).+|^/$">
|
||||
Redirect permanent / https://archive.psg.com/
|
||||
</LocationMatch>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
Repeat the VirtualHost for all domains for which you are getting certificates.
|
||||
|
||||
Don't forget to restart the Apache server
|
||||
|
||||
```
|
||||
service apache2 restart
|
||||
```
|
||||
|
||||
It is a good check to ensure that you can browse to the challenge directory [http:ca0.rpki.net/.well-known/acme-challenge].
|
||||
|
||||
Getting my browsers not to fall forward to https was very painful. So I tested as follows:
|
||||
|
||||
```
|
||||
echo gobbledygook > challenges/foo
|
||||
chmod 644 challenges/foo
|
||||
curl http://ca0.rg.net/.well-known/acme-challenge/foo
|
||||
gobbledygook
|
||||
```
|
||||
|
||||
## Getting the Certificate
|
||||
|
||||
I lost a number hours because I have a conservative umask. So I made a handy script to get the certificate and, while we're at it, the certificate chain from LetsEncrypt.
|
||||
|
||||
Before you go for real, I strongly suggest you test using the staging server so as not to encounter LetsEncrypt's rate limiting. To do this, hack the acme_tiny.py as follows:
|
||||
|
||||
```
|
||||
DEFAULT_CA = "https://acme-staging.api.letsencrypt.org"
|
||||
#DEFAULT_CA = "https://acme-v01.api.letsencrypt.org"
|
||||
```
|
||||
|
||||
When it all works, then you can go for real.
|
||||
|
||||
```
|
||||
#!/bin/sh -x
|
||||
|
||||
umask 0022
|
||||
H=/home/acme
|
||||
WK=$H/work
|
||||
SEC=$H/secrets
|
||||
CH=$H/challenges
|
||||
|
||||
python acme_tiny.py \
|
||||
--account-key \
|
||||
$SEC/account.key \
|
||||
--csr $WK/domain.csr \
|
||||
--acme-dir $CH \
|
||||
> $WK/signed.crt
|
||||
|
||||
curl https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem \
|
||||
> $WK/intermediate.pem
|
||||
|
||||
# note that you may have the certs stored elsewhere
|
||||
sudo $H/CAT $SEC/domain.key /etc/ssl/private/ssl-cert-snakeoil.key
|
||||
sudo $H/CAT $WK/signed.crt /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
sudo $H/CAT $WK/intermediate.pem /etc/apache2/ssl.crt/server-ca.crt
|
||||
#
|
||||
sudo /usr/sbin/service apache2 restart
|
||||
```
|
||||
|
||||
Where `/home/acme/CAT` is
|
||||
|
||||
```
|
||||
/bin/cat $1 > $2
|
||||
```
|
||||
|
||||
And you will have needed to hack /etc/sudoers to have
|
||||
|
||||
```
|
||||
acme ALL = (root) NOPASSWD: /home/acme/CAT
|
||||
acme ALL = (root) NOPASSWD: /usr/sbin/service
|
||||
```
|
||||
|
||||
## Renewal
|
||||
|
||||
You can run the same script as above for certificate renewal.
|
||||
Loading…
Add table
Add a link
Reference in a new issue