Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
ACME.js is a low-level client for Let's Encrypt.
Looking for an easy, high-level client? Check out Greenlock.js.
| 15k gzipped | 55k minified | 88k (2,500 loc) source with comments |
Supports the latest (Nov 2019) release of Let's Encrypt in a small, lightweight, Vanilla JS package.
.中国
)* Although we use async/await
in the examples,
the codebase is written entirely in Common JS.
The public API encapsulates the three high-level steps of the ACME protocol:
The core API can be show in just four functions:
ACME.create({ maintainerEmail, packageAgent, notify });
acme.init(directoryUrl);
acme.accounts.create({ subscriberEmail, agreeToTerms, accountKey });
acme.certificates.create({
customerEmail, // do not use
account,
accountKey,
csr,
domains,
challenges
});
Helper Functions
ACME.computeChallenge({
accountKey,
hostname: 'example.com',
challenge: { type: 'dns-01', token: 'xxxx' }
});
Parameter | Description |
---|---|
account | an object containing the Let's Encrypt Account ID as "kid" (misnomer, not actually a key id/thumbprint) |
accountKey | an RSA or EC public/private keypair in JWK format |
agreeToTerms | set to true to agree to the Let's Encrypt Subscriber Agreement |
challenges | the 'http-01', 'alpn-01', and/or 'dns-01' challenge plugins (get , set , and remove callbacks) to use |
csr | a Certificate Signing Request (CSR), which may be generated with @root/csr , openssl, or another |
customerEmail | Don't use this. Given as an example to differentiate between Maintainer, Subscriber, and End-User |
directoryUrl | should be the Let's Encrypt Directory URLhttps://acme-staging-v02.api.letsencrypt.org/directory |
domains | the list of altnames (subject first) that are listed in the CSR and will be listed on the certificate |
maintainerEmail | should be a contact for the author of the code to receive critical bug and security notices |
notify | all callback for logging events and errors in the form function (ev, args) { ... } |
packageAgent | should be an RFC72321-style user-agent string to append to the ACME client (ex: mypackage/v1.1.1) |
skipChallengeTests | do not do a self-check that the ACME-issued challenges will pass (not recommended) |
skipDryRun: false | do not do a self-check with self-issued challenges (not recommended) |
subscriberEmail | should be a contact for the service provider to receive renewal failure notices and manage the ACME account |
Maintainer vs Subscriber vs Customer
maintainerEmail
should be the email address of the author of the code.
This person will receive critical security and API change notifications.subscriberEmail
should be the email of the admin of the hosting service.
This person agrees to the Let's Encrypt Terms of Service and will be notified
when a certificate fails to renew.customerEmail
should be the email of individual who owns the domain.
This is optional (not currently implemented).Generally speaking YOU are the maintainer and you or your employer is the subscriber.
If you (or your employer) is running any type of service you SHOULD NOT pass the customer email as the subscriber email.
If you are not running a service (you may be building a CLI, for example), then you should prompt the user for their email address, and they are the subscriber.
These notify
events are intended for logging and debugging, NOT as a data API.
Event Name | Example Message |
---|---|
certificate_order | { subject: 'example.com', altnames: ['...'], account: { key: { kid: '...' } } } |
challenge_select | { altname: '*.example.com', type: 'dns-01' } |
challenge_status | { altname: '*.example.com', type: 'dns-01', status: 'pending' } |
challenge_remove | { altname: '*.example.com', type: 'dns-01' } |
certificate_status | { subject: 'example.com', status: 'valid' } |
warning | { message: 'what went wrong', description: 'what action to take about it' } |
error | { message: 'a background process failed, and it may have side-effects' } |
Note: DO NOT rely on undocumented properties. They are experimental and will break. If you have a use case for a particular property open an issue - we can lock it down and document it.
A basic example includes the following:
To make it easy to generate, encode, and decode keys and certificates, ACME.js uses Keypairs.js and CSR.js
npm install --save acme
var ACME = require('acme');
<meta charset="UTF-8" />
(necessary in case the webserver headers don't specify plain/text; charset="UTF-8"
)
var ACME = require('acme');
<meta charset="UTF-8" />
(necessary in case the webserver headers don't specify plain/text; charset="UTF-8"
)
<script src="https://unpkg.com/@root/acme@3.0.0/dist/acme.all.js"></script>
acme.min.js
<script src="https://unpkg.com/@root/acme@3.0.0/dist/acme.all.min.js"></script>
Use
var ACME = window['@root/acme'];
The challenge callbacks are documented in the test suite, essentially:
function create(options) {
var plugin = {
init: async function(deps) {
// for http requests
plugin.request = deps.request;
},
zones: async function(args) {
// list zones relevant to the altnames
},
set: async function(args) {
// set TXT record
},
get: async function(args) {
// get TXT records
},
remove: async function(args) {
// remove TXT record
},
// how long to wait after *all* TXT records are set
// before presenting them for validation
propagationDelay: 5000
};
return plugin;
}
The http-01
plugin is similar, but without zones
or propagationDelay
.
Many challenge plugins are already available for popular platforms.
Search acme-http-01-
or acme-dns-01-
on npm to find more.
Type | Service | Plugin |
---|---|---|
dns-01 | CloudFlare | acme-dns-01-cloudflare |
dns-01 | Digital Ocean | acme-dns-01-digitalocean |
dns-01 | DNSimple | acme-dns-01-dnsimple |
dns-01 | DuckDNS | acme-dns-01-duckdns |
http-01 | File System / Web Root | acme-http-01-webroot |
dns-01 | GoDaddy | acme-dns-01-godaddy |
dns-01 | Gandi | acme-dns-01-gandi |
dns-01 | NameCheap | acme-dns-01-namecheap |
dns-01 | Name.com | acme-dns-01-namedotcom |
dns-01 | Route53 (AWS) | acme-dns-01-route53 |
http-01 | S3 (AWS, Digital Ocean, Scaleway) | acme-http-01-s3 |
dns-01 | Vultr | acme-dns-01-vultr |
dns-01 | Build your own | acme-dns-01-test |
http-01 | Build your own | acme-http-01-test |
tls-alpn-01 | Contact us | - |
npm test
Although you can run the tests from a public facing server, its easiest to do so using a dns-01 challenge.
You will need to use one of the acme-dns-01-*
plugins
to run the test locally.
ENV=DEV
MAINTAINER_EMAIL=letsencrypt+staging@example.com
SUBSCRIBER_EMAIL=letsencrypt+staging@example.com
BASE_DOMAIN=test.example.com
CHALLENGE_TYPE=dns-01
CHALLENGE_PLUGIN=acme-dns-01-digitalocean
CHALLENGE_OPTIONS='{"token":"xxxxxxxxxxxx"}'
# Get the repo and change directories into it
git clone https://git.rootprojects.org/root/acme.js
pushd acme.js/
# Install the challenge plugin you'll use for the tests
npm install --save-dev acme-dns-01-digitalocean
.env
configYou'll need a .env
in the project root that looks something like the one in examples/example.env
:
# Copy the sample .env file
rsync -av examples/example.env .env
# Edit the config file to use a domain in your account, and your API token
#vim .env
code .env
# Run the tests
node tests/index.js
Did this project save you some time? Maybe make your day? Even save the day?
Please say "thanks" via Paypal or Patreon:
Where does your contribution go?
Root is a collection of experts who trust each other and enjoy working together on deep-tech, Indie Web projects.
Our goal is to operate as a sustainable community.
Your contributions - both in code and especially monetarily - help to not just this project, but also our broader work of projects that fuel the Indie Web.
Also, we chat on Keybase in #rootprojects
Do you need...
You're welcome to contact us in regards to IoT, On-Prem, Enterprise, and Internal installations, integrations, and deployments.
We have both commercial support and commercial licensing available.
We also offer consulting for all-things-ACME and Let's Encrypt.
ACME.jsk™ is a trademark of AJ ONeal
The rule of thumb is "attribute, but don't confuse". For example:
Please contact us if have any questions in regards to our trademark, attribution, and/or visible source policies. We want to build great software and a great community.
ACME.js | MPL-2.0 | Terms of Use | Privacy Policy
FAQs
Free SSL certificates for Node.js and Browsers. Issued via Let's Encrypt
The npm package acme-v2 receives a total of 2,394 weekly downloads. As such, acme-v2 popularity was classified as popular.
We found that acme-v2 demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.