Let's encrypt certificate for offline servers with OVH DNS
Posted on 27 Dec 2016 in security • 3 min read
Let's encrypt provide free and easy SSL certificates. Nevertheless it need to verify that you own the machine. In order to do that we usually use HTTP verification with the .well-known directory.
But sometime our servers are not reachable from the internet. Therefore the HTTP validation is not possible. Hopefully there is another way the acme challenge can be validated: DNS validation.
In this post we will see how we can generate Let's encrypt SSL certificate for offline machine with DNS validation for domains hosts by OVH.
Certificate generation
Requirements
- A domain name with its DNS hosted by OVH
- curl (sudo apt-get install curl)
- Python 2 or 3 and pip (sudo apt-get install python-pip)
- python-ovh (pip install ovh)
- dehydrated (git clone https://github.com/lukas2511/dehydrated)
- OVH hook (git clone https://github.com/antoiner77/letsencrypt.sh-ovh)
API Key generation
We need API keys in order to use the hook script for the DNS validation. For that, register the application on OVH API.
We get two elements from the website: * APP_KEY * APP_SECRET
We need to put them in our ovh.conf
file in the OVH hook script:
[default]
; general configuration: default endpoint
endpoint=ovh-eu
[ovh-eu]
; configuration specific to 'ovh-eu' endpoint
application_key=APP_KEY
application_secret=APP_SECRET
; uncomment following line when writing a script application
; with a single consumer key.
;consumer_key=MA_CLEFS
Now we need to generate the use token in order to validation our keys (you may need to had execution permissions to the script):
./ovhdns.py --init
We get an other link where we need to authenticate one more time. When it is
done just press the ENTER
key.
The script indicate the user token to insert in the ovh.conf
file. Be sure to
uncomment the line by deleting the ;
at the beginning of the line.
The configuration file will be needed in the dehydrated
folder, let's just
create a symlink:
ln -s /home/user/letsencrypt.sh-ovh/ovh.conf /home/user/dehydrated/ovh.conf
The hook script configuration is finished, now let's configure the dehydrated
script.
dehydrated configuration
In the domains.txt file, indicate the certificates that you want to generate. Each line will be a certificate but one certificate can be valid for several domains. For instance, the following configuration will generate two certificates each for two domains.
example.org www.example.org
gitlab.example.com wikimedia.example.com
Certificates generation
Just launch the dehydrated script (you may need to had execution permission):
./dehydrated -c -t dns-01 -k '/home/user/letsencrypt.sh-ovh/ovhdns.py'
-c
(re)generate certificates, will renew them if they expire in less than one month-t dns-01
use the DNS challenge for acme validation-k
use specific script for hook
The certificates are stored in /home/user/dehydrated/certs/
.
Automatically renew certificates
In order to automatically renew certificate:
Create a symlink in order to use the certificate and the necessary key. This
is the only moment where we will need root permissions. For
instance, for the gitlab certificate we need gitlab.crt
and gitlab.key
:
# ln -s /home/user/dehydrated/certs/git.exemple.fr/fullchain.pem /etc/gitlab/ssl/gitlab.crt
# ln -s /home/user/dehydrated/certs/git.exemple.fr/privkey.pem /etc/gitlab/ssl/gitlab.key
Add the following line to the crontab (crontab -e
):
0 15 * * * cd /home/user/dehydrated/; ./dehydrated -c -t dns-01 -k '/home/user/letsencrypt.sh-ovh/ovhdns.py'
Source
https://ungeek.fr/letsencrypt-api-ovh/
Disqus comments
This is a copy of the Disqus comments for this page
Christoph Haas - 2017
Hi maggick,
I followed your instructions, the only thing i was uncertain was if I should change ";consumer_key=MA_CLEFS" with the output of "./ovhdns.py --init", then remove the ";" in front.
I got this error response from the dehydrated-call: --- snip --- Traceback (most recent call last): File "/root/letsencrypt.sh-ovh/ovhdns.py", line 42, in
target=token) File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 375, in post return self.call('POST', _target, kwargs, _need_auth) File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 436, in call response=result) ovh.exceptions.InvalidCredential: This credential is not valid OVH-Query-ID: FR.ws-2.58ff13c9.3236.2138 --- snap --- What could be the cause?
TIA Christoph.
maggick - 2017
Yeah you must replace the "consumer_key" parameter with the output of "./ovhdns.py --init". It should fix your problem.
Christoph Haas - 2017
after validating the token, I progressed a little bit:
- Responding to challenge for host1.intern.somewithovhhos......
- Responding to challenge for host2.intern.somewithovhhos......
- Challenge is valid!
- Requesting certificate...
- ERROR: An error occurred while sending post-request to acme-v01.api.letsen... (Status 403)
Details: { "type": "urn:acme:error:unauthorized", "detail": "Error creating new cert :: authorizations for these names not found or expired: host2.intern.somewithovhhos...", "status": 403 }
Traceback (most recent call last): File "/root/letsencrypt.sh-ovh/ovhdns.py", line 56, in
client.delete('/domain/zone/%s/record/%s' % (basedomain, id_record)) File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 385, in delete return self.call('DELETE', _target, None, _need_auth) File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 441, in call response=result) ovh.exceptions.ResourceNotFoundError: This service does not exist nor certificate for "host1.intern.somewithovhhos..." nor for "host2.intern.somewithovhhos..." is generated. Christoph.
maggick - 2017
I just test the process again. It still work. According to the error message you cannot modify the DNS. If you follow the process you should have the permissions.