Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
acme-dns-tiny
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Adrien Dorsaz
acme-dns-tiny
Commits
b510d2a2
Commit
b510d2a2
authored
Jun 20, 2016
by
Adrien Dorsaz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update README.md for the acme-dns-tiny poject
parent
8fe116d3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
91 additions
and
106 deletions
+91
-106
README.md
README.md
+91
-106
No files found.
README.md
View file @
b510d2a2
# acme-tiny
# acme-
dns-
tiny
[

](https://travis-ci.org/diafygi/acme-tiny
)
[

](https://coveralls.io/github/diafygi/acme-tiny?branch=master
)
[

](#
)
[

](#
)
This is a tiny, auditable script that you can throw on your server to issue
and renew
[
Let's Encrypt
](
https://letsencrypt.org/
)
certificates. Since it has
to be run on your server and have access to your private Let's Encrypt account
key, I tried to make it as tiny as possible (currently less than 200 lines).
The only prerequisites are python and openssl.
and renew
[
Let's Encrypt
](
https://letsencrypt.org/
)
certificates with DNS
authentication.
**PLEASE READ THE SOURCE CODE! YOU MUST TRUST IT WITH YOUR PRIVATE KEYS!**
Since it has to have access to your private ACME account key and the
rights to update the DNS records of your DNS server, this code has been designed
to be as tiny as possible (currently less than 250 lines).
##Donate
The only prerequisites are python (especially the dnspython module) and openssl.
**PLEASE READ THE SOURCE CODE! YOU MUST TRUST IT WITH YOUR ACCOUNT PRIVATE KEYS!**
Note: this script is a fork of the
[
acme-tiny project
](
https://github.com/diafygi/acme-tiny
)
which uses ACME HTTP verification to create signed certificates.
## Donate
If this script is useful to you, please donate to the EFF. I don't work there,
but they do fantastic work.
...
...
@@ -44,11 +51,12 @@ Let's Encrypt client.
The private account key from the Let's Encrypt client is saved in the
[
JWK
](
https://tools.ietf.org/html/rfc7517
)
format.
`acme-tiny`
is using the PEM
key format. To convert the key, you can use the tool
[
conversion script
](
https://gist.github.com/JonLundy/f25c99ee0770e19dc595
)
by JonLundy:
[
conversion script
](
https://gist.github.com/JonLundy/f25c99ee0770e19dc595
)
by JonLundy:
```
sh
# Download the script
wget
-O
-
"https://gist.githubusercontent.com/JonLundy/f25c99ee0770e19dc595/raw/6035c1c8938fae85810de6aad1ecf6e2db663e26/conv.py"
>
conv.py
curl
"https://gist.githubusercontent.com/JonLundy/f25c99ee0770e19dc595/raw/6035c1c8938fae85810de6aad1ecf6e2db663e26/conv.py"
>
conv.py
# Copy your private key to your working directory
cp
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/<
id
>
/private_key.json private_key.json
...
...
@@ -63,8 +71,9 @@ openssl rsa -in private_key.der -inform der > account.key
### Step 2: Create a certificate signing request (CSR) for your domains.
The ACME protocol (what Let's Encrypt uses) requires a CSR file to be submitted
to it, even for renewals. You can use the same CSR for multiple renewals. NOTE:
you can't use your account private key as your domain private key!
to it, even for renewals. You can use the same CSR for multiple renewals.
NOTE: you can't use your account private key as your domain private key!
```
#generate a domain private key (if you haven't already)
...
...
@@ -73,139 +82,115 @@ openssl genrsa 4096 > domain.key
```
#for a single domain
openssl req -new -sha256 -key domain.key -subj "/CN=
yoursite.com
" > domain.csr
openssl req -new -sha256 -key domain.key -subj "/CN=
example.org
" > domain.csr
#for multiple domains (use this one if you want both www.
yoursite.com and yoursite.com
)
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:
yoursite.com,DNS:www.yoursite.com
")) > domain.csr
#for multiple domains (use this one if you want both www.
example.org and example.org
)
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:
example.org,DNS:www.example.org
")) > domain.csr
```
### Step 3: Make your
website host challenge fil
es
### Step 3: Make your
DNS server allow dynamic updat
es
You must prove you own the domains you want a certificate for, so Let's Encrypt
requires you host some files on them. This script will generate and write those
files in the folder you specify, so all you need to do is make sure that this
folder is served under the ".well-known/acme-challenge/" url path. NOTE: Let's
Encrypt will perform a plain HTTP request to port 80 on your server, so you
must serve the challenge files via HTTP (a redirect to HTTPS is fine too).
requires you host some DNS resource records.
```
#make some challenge folder (modify to suit your needs)
mkdir -p /var/www/challenges/
```
This script will generate and write those DNS records to your DNS server by
use of DNS dynamic message updates.
```
nginx
#example for nginx
server
{
listen
80
;
server_name
yoursite.com
www.yoursite.com
;
So you have to configure your DNS server to allow dynamic DNS
updates and create a TSIG key which will give rights to perform updates.
location
/.well-known/acme-challenge/
{
alias
/var/www/challenges/
;
try_files
$uri
=
404
;
}
The configuration of the script will need:
*
the TSIG key name and value
*
the algorithm used for TSIG key (MD5, SHA1, SHA224, SHA256, SHA384 or SHA512)
*
the DNS zone to update
*
the address and the port of the DNS server
...the
rest
of
your
config
}
```
The simplest way to configure the script is to copy the
`example.ini`
file
from this repository and update the values as needed.
**
Be careful! Set permissions correctly on your configuration file, because
it will contain the key authorized to modify your DNS configuration !
**
### Step 4: Get a signed certificate!
Now that you have setup your server and generated all the needed files, run this
script on your server with the permissions needed to write to the above folder
and read your private account key and CSR.
script on a computer containing your private account key, the CSR and the configuration.
```
#run the script on your server
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt
python acme_dns_tiny.py example.ini > ./chain.pem
```
### Step 5: Install the certificate
The signed https certificate that is output by this script can be used along
with your private key to run an https server. You need to include them in the
https settings in your web server's configuration. Here's an example on how to
configure an nginx server:
If every thing was ok, chain.crt contains your signed certificate followed by the
CA's certificate which signed yours.
```
#NOTE: For nginx, you need to append the Let's Encrypt intermediate cert to your cert
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
```
### Step 5: Install the certificate
```
nginx
server
{
listen
443
;
server_name
yoursite.com,
www.yoursite.com
;
ssl
on
;
ssl_certificate
/path/to/chained.pem
;
ssl_certificate_key
/path/to/domain.key
;
ssl_session_timeout
5m
;
ssl_protocols
TLSv1
TLSv1.1
TLSv1.2
;
ssl_ciphers
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA
;
ssl_session_cache
shared:SSL:50m
;
ssl_dhparam
/path/to/server.dhparam
;
ssl_prefer_server_ciphers
on
;
...the
rest
of
your
config
}
server
{
listen
80
;
server_name
yoursite.com,
www.yoursite.com
;
location
/.well-known/acme-challenge/
{
alias
/var/www/challenges/
;
try_files
$uri
=
404
;
}
...the
rest
of
your
config
}
```
The certificate chain that is output by this script can be used along
with your private key to run any service on your server which need TSL encryption.
You need to include both in the TLS settings of your services.
### Step 6: Setup an auto-renew cronjob
Congrats! Your
website is now using https
! Unfortunately, Let's Encrypt
Congrats! Your
server is now using TLS
! Unfortunately, Let's Encrypt
certificates only last for 90 days, so you need to renew them often. No worries!
It's automated! Just make a bash script and add it to your crontab (see below
for example script).
Example of a
`renew_cert.sh`
:
Example of a
skeleton for
`renew_cert.sh`
script
:
```
sh
#!/usr/bin/sh
python /path/to/acme_tiny.py
--account-key
/path/to/account.key
--csr
/path/to/domain.csr
--acme-dir
/var/www/challenges/
>
/tmp/signed.crt
||
exit
wget
-O
- https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem
>
intermediate.pem
cat
/tmp/signed.crt intermediate.pem
>
/path/to/chained.pem
service nginx reload
```
#!/bin/bash
# Configuration
# You should use another directory as /tmp could be destroyed regularly
WORKINGDIR
=
"/tmp/acme-dns-tiny"
# Pre run script: configure a secure workspace using ACL POSIX
mkdir
-p
${
WORKINGDIR
}
setfacl
-m
"default:other:--- , other:---"
${
WORKINGDIR
}
# You should also add code to create backup of older certificates
# You may need code to handle HPKP (key pining in HTTP) updates
# You may need to update DANE (key pining in DNS) too
# With HPKP and DANE, you should also consider your automatic key rollover
# which will need to update the CSR file and/or your DNS DANE records.
# Run the script
python /path/to/acme_dns_tiny.py example.ini
>
${
WORKINGDIR
}
/chain.pem
||
exit
# Post run script
# You should reload each service using TLS
```
#example line in your crontab (runs once per month)
0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log
```
Then you'll need to configure a cron job to execute this script regularly (think
to set random minutes to avoid to DDOS the CA servers).
## Permissions
The biggest problem you'll likely come across while setting up and running this
script is permissions. You want to limit access to your account private key
and
challenge web folder as much as possib
le. I'd recommend creating a user
specifically for handling this script, the account private key,
and the
challenge folder
. Then add the ability for that user to write to your installed
certificate file (e.g.
`/path/to/chain
ed.pem`
) and reload your webserver
. That
way, the cron
script
will do its thing, overwrite your old certificate, and
script is permissions. You want to limit access to your account private key
, your
CSR and your configuration fi
le. I'd recommend creating a user
specifically for handling this script, the account private key,
the CSR and
the DNS key
. Then add the ability for that user to write to your installed
certificate file (e.g.
`/path/to/chain
.pem`
) and reload your services
. That
way, the cron
job
will do its thing, overwrite your old certificate, and
reload your webserver without having permission to do anything else.
**BE SURE TO:**
*
Backup your account private key (e.g.
`account.key`
)
*
Don't allow this script to be able to read your domain private key!
*
Don't allow this script to be run as root!
*
Don't allow this script to be able to read your
*domain*
private key!
*
Don't allow this script to be run as
*root*
!
*
Understand and configure correctly your cron job to do all your needs !
(if you don't know bash, write it in your preferred language to manage your
server)
## Feedback/Contributing
This project has a very, very limited scope and codebase.
I'm happy to receive
bug reports and pull requests, but please don't add any new features. This
script must stay under 200 lines of code to ensure it can be easily audited by
anyone who wants to run it.
This project has a very, very limited scope and codebase.
The project is happy
to receive bug reports and pull requests, but please don't add any new features.
This script must stay under 250 lines of code to ensure it can be easily audited
by
anyone who wants to run it.
If you want to add features for your own setup to make things easier for you,
please do! It's open source, so feel free to fork it and modify as necessary.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment