concorde
is three things:
concorde.shaman
: a fully automated tool designed to sign TLS certificates with minimal setup requiredconcorde.client
: A low-level Python 3 ACME client library thatconcorde.shaman
usesconcorde.cli
: A not-so-user-friendly commandline ACME client tool that usesconcorde.client
for when you need to do something manual.
concorde
has a lightweight dependency footprint: its immediate dependencies
are the cryptography
and requests
libraries. concorde
also completely
defers authenticating authorization challenges to external programs. This
allows it to not require any knowledge of how the authentication is to proceed
and thus does not require any special privileges to run.
shaman
is designed to be a tool that is safe to run repeatedly to keep your
certificates up to date.
Usage:
$ shaman [<profile>]
If <profile>
is not specified, shaman
, defaults to the current directory.
All configuration is read from a file shaman.json
in the profile directory.
shaman
will update this file as necessary.
The minimal file should look something like this:
{
"server": "https://acme-v01.api.letsencrypt.org/directory",
"renewal": 10,
"domains": {
"example.com": {
"authenticators": {
"http-01": "prove-challenge"
}
}
}
}
Each piece in the configuration will be explained, by outlining what shaman
will do:
- look for an
account
block. If:- it doesn't exist:
- generate a new account private key
- create a new account on the specified
server
- print the URL of an agreement if appropriate allowing the user to opt-out before auto-accepting
- save the key path, key type, and registration URL so this step can be skipped in the future
- it doesn't exist:
- for each entry in the
domain
block:- look for an
authorization
entry. If:- it doesn't exist:
- use the
account
key to request an authorization for the given domain - use the available
authenticators
and account public key to respond to the first combination of challenges from the server - save the authorization URL so this step can be skipped in the future.
- use the
- it does exist:
- check if the authorization is still valid.
- if it isn't:
- obtain a new authorization as above.
- if it isn't:
- check if the authorization is still valid.
- it doesn't exist:
- look for a
key
entry. If:- it doesn't exist:
- generate a new private key for the domain as
<domain>_key
- save the key path and key type so this step can be skipped.
- generate a new private key for the domain as
- it doesn't exist:
- look for a
certificate
entry. If:- it doesn't exist:
- generate a new CSR for the domain and request the server to sign it
- save the certificate URL so this step can be skipped
- it does exist:
- check if its expiry is within
renewal
number of days. If:- it is:
- generate a new CSR and obtain a new certificate.
- it is:
- check if its expiry is within
- it doesn't exist:
- look for an
Since shaman
defers to 'authenticators' it doesn't need any special
privileges to prove domain ownership, however it does mean that some additional
set up is required. An authenticator is invoked with no arguments. Data is
supplied to its standard input as follows:
<token>LF
<key_authorization>LF
The authenticator is expected to perform whatever action is appropriate and exit with status code zero. Any other status code is regarded a failure to authenticate.
As an example of an authenticator, the following nginx
server block:
server {
listen 80;
server_name ~(?<vhost>.*);
location ~\/\.well-known\/acme-challenge\/(.*) {
alias /mnt/acme-challenge/$1;
}
}
would make the following bash
script with executable permissions a valid
authenticator:
#!/bin/bash
read token
read key_authorization
echo $key_authorization > /mnt/acme-challenge/$token
shaman
logs its actions to standard output, in cron
jobs, the output is
typically redirected to somewhere appropriate.
The commandline tool is purposefully a stateless and tedious tool to use,
because it does not read any configuration files. It is strongly recommended
to use shaman
and only use the commandline tool if something manual needs to
be done.
The tool has built-in help, but an overview of its commands are listed below:
concorde acct create
concorde acct status <acct>
concorde acct update <acct>
concorde authz create
concorde authz status <authz>
concorde approve <token>
concorde challenge respond <challenge> <key authorization>
concorde cert sign-req <csr>
concorde cert fetch <cert>
concorde cert chain <cert>
concorde cert revoke <cert>
Many of the above commands require additional arguments, they can be some of:
--server <url>
--key-type [ PEM | DER ]
--key <path>
--pubkey <path>
Install the latest tagged release:
$ pip install git+https://github.com/frutiger/concorde.git@latest
This will install the concorde
and shaman
scripts into Python's binary
path.
Copyright (C) 2016 Masud Rahman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.