acme-bot
v1.4.2
Published
Automatic Certificate Management Environment (ACME) for Node.js with minimal dependecies
Downloads
9
Maintainers
Readme
ACME Bot (JS)
Lightning fast, lightweight Bot for Automatic Certificate Management Environment (ACME) written in JavaScript for Node.js with minimal dependencies Based on node-acme-client.
Features
- [x] Lightweight: no strict dependencies: easy to audit the codebase
- [x] Multi-platform (Linux / Windows / Mac OS)
- [x] Supports all types of challenges:
http-01
,dns-01
,tls-alpn-01
- [x] Single continuous
http2
session when communicating to ACME server (faster comms + lower load on public infrastructure) - [x] Automatically updates particular cert(s) when less than 30 days left before expiration (configurable)
- [x] Supports
Systemd
timer with related service for auto-update task scheduling (used by default) - [x] Supports
Cron
for auto-update task scheduling (used as fallback ifsystemd
is not present) - [x] Having
root
access is not required, but recommended - [x] Supports both
ECDSA
(default) andRSA
types of certificate and account keys - [x] Standalone mode that doesn't use file system (challenges saved and served directly from RAM)
- [x] Excellent performance due to use of modern
node:crypto
API to access internalopenssl
functionality
Table of contents
Installation
Dependencies
| Node.js | openssl | json5 (optional) | | ------- | ------- | ------------------ | | v16+ | v1.1.1+ | v2+ |
Install from package manager
> npm install -g acme-bot --no-optional
- OR -
> yarn add global acme-bot --ignore-optional
Install using script (into a current directory)
#!/bin/sh
wget https://git.serenity-island.net/sie-foss/acme-bot/archive/master.tar.gz -O acme-bot.tar.gz
tar -xaf acme-bot.tar.gz
chmod u+x acme-bot/acme-bot.js
ln -rs acme-bot/acme-bot.js /usr/local/bin/acme-bot # (optional)
Quick start (standalone mode)
- Add your domain and subdomains (if any)
NOTE: if directory wasn't specified for
http-01
challenge, then certain provisions must be performed (details)
> acme-bot configure
{
bot: {
issuer: "letsencrypt",
certs_root_dir: "/etc/letsencrypt",
},
commands: {
stop_on_error: false,
// Stop reverse proxy (if there is one) while requesting and receiving certs
pre: [ "systemctl stop nginx" ],
post: [ "systemctl start nginx" ]
},
domains: {
'example.org': {
sub_domains: "www",
challenge_cfg: [ { type: 'http-01' } ]
}
},
}
- Check if everything works as expected by requesting a non-trusted certificate using staging environment
> acme-bot --standalone test
- If test passed without errors, request trusted certificate from production environment and allow
acme-bot
to run automatically on schedule from now on
> acme-bot --standalone --issue enable
Uninstall
before actually removing the package, it is recommended to clear the auto-renewal task schedule manually using disable
action, since npm doesn't support uninstall scripts:
> acme-bot disable
> npm uninstall -g acme-bot
Usage
Actions and order of the arguments
When acme-bot
is expected to perform certain action (e.g. configure
, enable
, disable
, status
, etc), order of arguments matters, since 'action' must be the last argument.
# Order of the arguments matters
> acme-bot --debug --config-file /home/user/.local/acme-bot.json configure
Using internal ACME challenge server
If directory was not specified for the http-01
challenge
- Either
--standalone
option must be specified and existing http server or reverse proxy would have to be stopped for the duration of runningacme-bot
- OR reverse proxy would have to be configured to interact with bot's internal ACME challenge server via a
tcp port
orunix socket
Example of using internal ACME challenge server WITH reverse proxy
/etc/nginx/sites-available/default
upstream acme_bot { server unix:/run/acme-bot-http.sock; server 127.0.0.1:8080 backup; }
server {
server_name example.org www.example.org;
listen 80;
listen [::]:80;
location /.well-known/acme-challenge/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://acme_bot;
}
}
/etc/acme-bot/config.json5
{
commands: { post: [ "systemctl reload nginx" ] },
bot: {
issuer: "letsencrypt",
certs_root_dir: "/etc/letsencrypt",
// NOTE: if both 'port' and 'path' are specified, 'path' will be used
acme_challenge_server: { http_01: { port: 8080, path: "/run/acme-bot-http.sock" } },
},
domains: {
'example.org': {
sub_domains: "www",
challenge_cfg: [ { type: 'http-01' } ]
}
},
}
Command:
> acme-bot --standalone test
Download certificate(s) manually:
To force issuing, downloading and overwriting existing certificate(s), use --force
option.
# normal mode: renew only if necessary
> acme-bot
- OR -
# forced mode: renew regardless of validity of the current cert(s)
> acme-bot --force
Configuration
Default location of the configuration file is /etc/acme-bot/config.json5
, however, it is possible to point acme-bot
to use other config file with --config-file
option.
On the first run acme-bot needs to be configured. Following command will open configuration file in a text editor.
If configuration file not found, it will be created from template.
> acme-bot configure
- OR -
> acme-bot --config-file /path/to/custom_config.json configure
Testing
To ensure the bot is ready to receive and store actual trusted certificates after (re-)configuring the bot, it is highly recommended to run a test to reduce the chance of running up against rate limits of the certificate issuer.
During the test, acme-bot
will use issuer's staging environment (if available), and a separate directory to store account data, runtime data, and received certificates.
> acme-bot test
If test completes without issues, you can allow acme-bot
to run automatically .
Automatic Task Scheduling
Following command will attempt to schedule execution of acme-bot
once every 2 weeks at randomized time for automatic certificate renewal (when necessary):
Depending on the target system and environment, this command will either create a pair of service
and timer
for systemd
OR a cron
job. If neither found, it will just print error.
> acme-bot enable
To request certificate(s) immediately after successfully scheduling automatic renewal task execution add --issue
option.
> acme-bot --issue enable
Check status
> acme-bot status
Expected output (if systemd
is used)
● acme-bot.timer - Automatic Certificate Management Environment (ACME) - Timer
Loaded: loaded (/etc/systemd/system/acme-bot.timer; enabled; preset: enabled)
Active: active (waiting) since XXX XXXX-XX-XX XX:XX:XX XXX;
Trigger: XXX XXXX-XX-XX XX:XX:XX XXX; 1 week 5 days left
Triggers: ● acme-bot.service
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon XXXX-XX-XX XX:XX:XX EDT 1 week 5 days left - - acme-bot.timer acme-bot.service
1 timers listed.
Pass --all to see loaded but inactive timers, too.
Free ACME Servers
acme-bot
comes with several built-in issuers' directory URLs.
[source]
{
letsencrypt: "https://acme-v02.api.letsencrypt.org/directory",
letsencrypt_test: "https://acme-staging-v02.api.letsencrypt.org/directory",
buypass: "https://api.buypass.com/acme/directory",
buypass_test: "https://api.test4.buypass.no/acme/directory",
zerossl: "https://acme.zerossl.com/v2/DV90",
sslcom: "https://acme.ssl.com/sslcom-dv-ecc"
}
Challenge priority
When ordering certificate for a particular domain, acme-bot
uses priorities when selecting challenges.
E.g. if supported challenges received from issuer are http-01
, dns-01
, tls-alpn-01
and configured challenges for particular domain are: [ 'dns-01':{ ... }, 'http-01':{...} ]
, then dns-01
will be selected.
E.g. if supported challenge received from issuer is only http-01
then http-01
will be selected as a fallback option.
Please note that wildcard certificates can only be validated through dns-01
challenge, which is not fully implemented on the acme-bot
at the moment.
More information about challenge types can be found here.
Local challenge verification
To minimize load on public infrastructure, acme-bot
will attempt to validate that it is possible to satisfy challenges locally, before telling ACME server to finalize validation the challenge.
In some cases (firewalls, etc) this internal challenge verification might not be possible to complete.
In this case, it is possible to disable this mechanism by setting skip_local_challenge_check
option to true
inside bot config. E.g.:
{
// ....
bot: {
issuer: "letsencrypt",
certs_root_dir: "/etc/letsencrypt",
skip_local_challenge_check: true,
},
// ....
}
Help and usage:
(currently, under construction)
> acme-bot help
Debugging
To suppress most of the details use --silent
option (only warnings and errors will be logged)
> acme-bot --silent
To see more details of what acme-bot
is doing, use --debug
option
> acme-bot --debug
To see even more details, set environment variable NODE_DEBUG=*
along with the --debug
option
> NODE_DEBUG=* acme-bot --debug
TODO
Active
- [x] Parse existing certs to determine and check actual expiration date, match altnames, etc
- [x] Finish transition from
jsrsasign
to system-wide ssl libraries.- [x]
openssl
supported v1.1.1+ (incl. v3.0+) - [ ] automatic availability detection and dynamic API selection
- [ ]
mbedTLS
- [ ]
GnuTLS
- [ ]
LibreSSL
- [ ]
wolfSSL
- [x]
- [x] Implement acme http challenge server for
standalone
mode - [x] Finish implementation of infrastructure for
dns-01
challenge - [x] Implement
tls-alpn-01
challenge - [ ] Write detailed man pages for the program and config file
- [ ] (?) Implement manual procedure for
dns-01
challenge (when noadd
anddel
scripts specified) (defeats 'A' in ACME, but okay for tests) - [ ] (?) Implement 'interview' on clean install to simplify initial configuration
- [ ] (?) Test automated task execution and scheduling as a non-priviledged user, document limitations
- [ ] (?) Implement local verification mechanism for
tls-alpn-01
challenge - [ ] (?) Implement running
acme-bot
incertbot
style, i.e. using only command line arguments - [ ] (?) Implement keeping defined amount of most recent certs in the archive
- [ ] (?) Test running on Mac OS
Suspended
Even though RFC permits those, the actual ACME server implementations should also support them. But unfortunately they don't, yet.
- [ ] Support EdDSA series keys for signing certificates (ref)
- [ ] Support EdDSA series keys as account key