ndilieto / uacme

ACMEv2 client written in plain C with minimal dependencies
GNU General Public License v3.0
430 stars 37 forks source link
acme-client acme-protocol acme-v2 challenge letsencrypt letsencrypt-cli rcf8555 ssl-certificate tls-certificate uacme ualpn

uacme manual

uacme

lightweight client for the RFC8555 ACMEv2 protocol, written in plain C with minimal dependencies (libcurl and one of GnuTLS, OpenSSL or mbedTLS). The ACMEv2 protocol allows a Certificate Authority (Let's Encrypt is a popular one) and an applicant to automate the process of verification and certificate issuance. The protocol also provides facilities for other certificate management functions, such as certificate revocation.

Features

Installation

Note: pristine releases are in the upstream/latest branch, tagged as upstream/x.x.x

mkdir uacme
wget -O - https://github.com/ndilieto/uacme/archive/upstream/latest.tar.gz | tar zx -C uacme --strip-components=1
cd uacme
./configure --disable-maintainer-mode
make install

If you just want to check out the latest pristine release from github:

git clone -b upstream/latest https://github.com/ndilieto/uacme

uacme is included in several distributions:

Getting started

Once you have obtained uacme (see Installation above) the next step is creating an ACME account:

uacme -v -c /path/to/uacme.d new

The configuration directory and account private key should have been created:

/path/to/uacme.d/private/key.pem

You can then issue a certificate for your domain by doing

uacme -v -c /path/to/uacme.d issue www.your.domain.com

If everything goes well uacme asks you to set up a challenge, for example

uacme: challenge=http-01 ident=www.your.domain.com token=kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4
key_auth=kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4.2evcXalKLhAybRuxxE-HkSUihdzQ7ZDAKA9EZYrTXwU

Note the challenge type in the example is http-01 which means you should set up your web server to serve a URL based on the token:

http://www.your.domain.com/.well-known/acme-challenge/kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4

The URL must return a text file containing a single line with the key authorization:

kZjqYgAss_sl4XXDfFq-jeQV1_lqsE76v2BoCGegFk4.2evcXalKLhAybRuxxE-HkSUihdzQ7ZDAKA9EZYrTXwU

After setting up the web server you can then type 'y' followed by a newline. This notifies the ACME server that it can proceed with the challenge verification. If the procedure is successful uacme saves the certificate and the key at:

/path/to/uacme.d/www.your.domain.com/cert.pem
/path/to/uacme.d/private/www.your.domain.com/key.pem

Note several challenge types are possible. If you type anything other than 'y', uacme skips the challenge and proposes a different one. The easiest is http-01 but any other type can be dealt with. Keep in mind that challenge types may be served in random order by the server. Do not make any assumptions and read what uacme outputs carefully.

Automating updates

Use the -h flag to manage the challenge with a hook script:

uacme -v -c /path/to/uacme.d -h /usr/share/uacme/uacme.sh issue www.your.domain.com

or (depending on your installation)

uacme -v -c /path/to/uacme.d -h /usr/local/share/uacme/uacme.sh issue www.your.domain.com

This will use the example uacme.sh hook script included in the distribution to manage http-01 challenges. You might need to edit the script to match your webserver's environment.

Once everything works correctly you can also set up cron, for example

6 15 * * * /usr/bin/uacme -c /path/to/uacme.d -h /usr/share/uacme/uacme.sh issue www.your.domain.com 

The cron job will automatically update the certificate when needed. Note the absence of -v flag, this makes uacme only produce output upon errors.

Note also that you will need to restart or reload any service that uses the certificate, to make sure it uses the renewed one. This is system and installation dependent. I normally put the necessary instructions in another script (for example /usr/share/uacme/reload.sh) that is executed by cron when uacme returns 0 (indicating the certificate has been reissued).

6 15 * * * /usr/bin/uacme -c /path/to/uacme.d -h /usr/share/uacme/uacme.sh issue www.your.domain.com && /usr/share/uacme/reload.sh

Check https://github.com/jirutka/muacme for a complete, ready-to-go solution.

dns-01 challenge support

The nsupdate.sh hook script included in the distribution allows managing dns-01 challenges with nsupdate. This only works if your name server supports RFC2136 (bind does, nsd doesn't).

https://gitlab.alpinelinux.org/alpine/infra/docker/uacme-nsd-wildcard is another example that works with nsd.

https://gist.github.com/Gowee/e756f925cfcbd5ab32d564ee3c795786 shows how to integrate with Cloudflare API.

https://github.com/tdy91/uacme-gandi-hook works with gandi.net.

https://sr.ht/~jacksonchen666/uacme-desec-hook/ works with deSEC.io.

tls-alpn-01 challenge support

ualpn is a lightweight proxying tls-alpn-01 challenge responder, designed to handle incoming HTTPS connections on port 443. Most of the time it just transparently proxies connections to the real web server (which can be on either another machine, or a different TCP port on the same machine). When a tls-alpn-01 challenge handshake comes in ualpn handles it on the fly instead of proxying it to the webserver. This means that unlike other available tls-alpn-01 responders, ualpn does not require your webserver to stop during the challenge (zero downtime).

The high performance event-driven implementation is based on libev which considerably reduces the cost of context switches and memory usage. In addition on systems such as Linux supporting the splice() system call, ualpn is able to move network data entirely in kernel memory without a round trip to user space, which further enhances performance.

ualpn also listens to a UNIX domain socket so that it can be fed the necessary tls-alpn-01 key authorizations for the domains being validated by the ACME server. ualpn was designed to be easy to integrate with not only uacme (check the example ualpn.sh hook script) but also other ACME clients. A certbot plugin is also available.

To get started with ualpn:

Documentation

There are regular unix man pages in the distribution, also available in HTML: uacme ualpn

Bugs and suggestions

If you believe you have found a bug, please log it at https://github.com/ndilieto/uacme/issues

If you have any suggestions for improvements, pull requests are welcome.