title | html_title | description |
---|---|---|
ACME Registration Authority for Smallstep Certificate Manager |
ACME Registration Authority for Smallstep Certificate Manager |
How to configure a Smallstep ACME Registration Authority with Certificate Manager. |
When public ACME Certificate Authorities (CA) like Let's Encrypt issue certificates to clients in the Web PKI, the CA depends heavily on DNS for client verification. To get a certificate, a client must prove to the CA that it either directly controls the public DNS records for a domain (for the DNS-01 challenge type)—or that it controls the IP address pointed to by public DNS records (for the HTTP-01 and TLS-ALPN-01 challenge types).
When deploying ACME internally, the same constraints are true: A server that authorizes certificate requests must be able to query internal DNS servers or reach internal hosts. This is why we created a Registration Authority (RA) for Certificate Manager. An RA is a service you run on your own network that authenticates ACME challenges (or other certificate requests). It does not issue certificates or hold CA keys. Instead, it relays authenticated certificate requests to Certificate Manager, which then issues certificates.
In this tutorial, you'll configure a Remote RA that you can run to authenticate requests for Certificate Manager certificates.
You will need:
- An account on the Smallstep platform. Need one? Register here
- An Authority in Certificate Manager that will act as your upstream CA
- A host or Kubernetes cluster where you can run the Registration Authority
Use this form to pre-fill some of the examples with values from your setup.
<DynamicDocForm formFields={[ { label: "Certificate Manager Authority URL", name: "caUrl", placeholder: "https://example.mycompany.ca.smallstep.com", }, { label: "Certificate Manager Authority Fingerprint", name: "fingerprint", placeholder: "b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f5", }, { label: "Certificate Manager JWK Provisioner Name", name: "provisioner", placeholder: "acme-ra-jwk", }, { label: "Registration Authority DNS Names", name: "dns", placeholder: "ra.example.com, ca.example.io", }, { label: "RA Bind Port or Address", name: "address", placeholder: ":443", }, { label: "Registration Authority URL", name: "raUrl", placeholder: "https://ra.example.com", }, ]}/>
Create a JWK provisioner in Certificate Manager. Your RA will use this provisioner to get certificates.
Our setup script will install an RA on a Linux host (Debian-based distros).
The script will:
- Install the
step
andstep-ca
binaries in/usr/bin
- Connect to your Certificate Manager CA
- Help you choose a JWK provisioner on your CA to link your RA to
- Create RA configuration files in
/etc/step-ca
- Create a
step
user and group - Add a systemd service called
step-ca.service
- Enable and start
step-ca.service
- Export a
STEPPATH
variable in/root/.bash_profile
The script has the following requirements:
- It must be run on a machine that uses systemd
- It must be run as
root
- It requires
jq
,curl
, andtar
commands
To run the script:
{({caUrl="https://example.mycompany.ca.smallstep.com", provisioner="acme-ra-jwk", dns="ra.example.com", address=":443", fingerprint="b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f5"}) => ( {`# curl -sSLO https://files.smallstep.com/install-step-ra.sh # bash install-step-ra.sh \\ --ca-url ${caUrl} \\ --fingerprint ${fingerprint} \\ --provisioner-name "${provisioner}" \\ --dns-names "${dns}" \\ --listen-address ${address}`} )}Your RA service should now be running. It is configured with a single ACME provisioner, but you can add other provisioners as needed.
Then follow the prompts to configure and start your RA.
Check that your RA server is running properly:
{({address=":443", fingerprint="b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f5"}) => ( {`# journalctl -fu step-ca.service -- Logs begin at Wed 2021-07-28 18:57:26 UTC. -- Jul 28 19:05:34 ip-172-31-28-100 systemd[1]: Started step-ca service. Jul 28 19:05:35 ip-172-31-28-100 step-ca[2013]: badger 2021/07/28 19:05:35 INFO: All 0 tables opened in 0s Jul 28 19:05:35 ip-172-31-28-100 step-ca[2013]: badger 2021/07/28 19:05:35 INFO: No head keys found Jul 28 19:05:35 ip-172-31-28-100 step-ca[2013]: 2021/07/28 19:05:35 Using root fingerprint '${fingerprint}' Jul 28 19:05:35 ip-172-31-28-100 step-ca[2013]: 2021/07/28 19:05:35 Serving HTTPS on ${address} ...`} )}You have completed the basic setup of your RA.
To download your root certificate from anywhere on your network, run the following, substituting your RA's URL and the root CA fingerprint:
{({caUrl="https://example.mycompany.ca.smallstep.com", fingerprint="b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f5"}) => ( {`$ step ca root root_ca.crt --ca-url ${caUrl} --fingerprint ${fingerprint}`} )}You can then get a certificate manually, using step
with the RA's ACME provisioner:
$ step ca certificate my-hostname.example.com server.crt server.key
We've written a tutorial for configuring popular ACME clients to use internal ACME.
Setting up an RA manually involves the following steps:
-
Create an Authority in Certificate Manager with a JWK provisioner
First, create a hosted Authority in the Certificate Manager dashboard if you haven't already, and configure your local
step
CLI to access this Authority, usingstep ca bootstrap
.Now, as a Super Administrator, add a JWK provisioner to the Authority, and give it a name (eg.
acme-ra-jwk
): {({provisioner="acme-ra-jwk"}) => ( <CodeBlock language="shell-session" copyText={step ca provisioner add ${provisioner} --type JWK --create
}> {$ step ca provisioner add ${provisioner} --type JWK --create
} )}You'll be asked for a password for the JWK encryption key. Provide a strong password and store it somewhere safe. You'll need it later in this setup process.
-
Setup a local instance of
step-ca
that can act as a registration authority (RA).You'll need to configure the RA to work with your hosted Authority in Certificate Manager, using the JWK provisioner you just created for the RA to Authority connection.
Create a
{({caUrl="https://example.mycompany.ca.smallstep.com", provisioner="acme-ra-jwk", dns="ra.example.com", address=":443", fingerprint="b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f5"}) => ( {`{ "address": "${address}", "dnsNames": ["${dns.replace(',', '","')}"], "db": { "type": "badgerV2", "dataSource": "./.step/db" }, "logger": {"format": "text"}, "authority": { "type": "stepcas", "certificateAuthority": "${caUrl}", "certificateAuthorityFingerprint": "${fingerprint}", "certificateIssuer": { "type" : "jwk", "provisioner": "${provisioner}" }, "provisioners": [{ "type": "ACME", "name": "acme" }] }, "tls": { "cipherSuites": [ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" ], "minVersion": 1.2, "maxVersion": 1.3, "renegotiation": false } }`} )}/.step/config/ca.json
configuration file with the following contents:Substitute your own values for the following:
address
: The address and port you would like your RA to listen on (eg.10.20.30.104:9000
or just:443
to bind to0.0.0.0:443
.certificateAuthority
: the URL of your upstream CAcertificateAuthorityFingerprint
: the CA fingerprint of your upstream CAcertificateIssuer.provisioner
: Your JWK provisioner name
-
Next, put the issuing JWK provisioner password into a file (eg.
{`$ step-ca /.step/config/ca.json --issuer-password-file password.txt`}$(step path)/password.txt
). When starting upstep-ca
in RA mode, you must pass the issuing JWK provisioner password filename: -
Distribute your root CA certificate and start issuing certs. 🥳
In another terminal run the following to download your root certificate from anywhere on your network, substituting your RA's URL and the root CA fingerprint: {({raUrl="https://ra.example.com", fingerprint="b4fc6b547ca4610b69cfcc53c6933e7a37170476dfe13EXAMPLE92c403f"}) => ( <CodeBlock language="shell-session" copyText={
step ca root root_ca.crt --ca-url ${raUrl} --fingerprint ${fingerprint}
}> {$ step ca root root_ca.crt --ca-url ${raUrl} --fingerprint ${fingerprint}
} )}You can then get a certificate manually, using
{`$ step ca certificate my-hostname.example.com server.crt server.key`}step
with the RA's ACME provisioner: -
Configure your local ACME clients to use your RA (instead of Let's Encrypt)
We've written a tutorial for configuring popular ACME clients to use internal ACME.
If you're running Kubernetes, you can run an ACME Registration Authority in your cluster. We have a Helm Chart for deploying an RA to Kubernetes.
TL;DR: There's a setup script showing all of the steps together in this README.
-
Create an Authority in Certificate Manager with a JWK provisioner
First, create a hosted Authority in the Certificate Manager dashboard if you haven't already, install the
step
CLI locally (brew install step
), and configurestep
to access your Authority, usingstep ca bootstrap
.Now, as a Super Administrator, add a JWK provisioner to the Authority, and give it a name (eg.
{`$ step ca provisioner add registration-authority --type JWK --create`}registration-authority
):You'll be asked for a password for the JWK encryption key. Provide a strong password and store it somewhere safe. You'll need it later in this setup process.
-
Configure the Helm Chart
Download the
{`$ curl -o step_values.yml -sSL https://raw.githubusercontent.com/smallstep/helm-charts/master/step-certificates/examples/registration_authority/values.yml`}step_values.yml
You will need to change the following fields in this YAML file to match your configuration:
certificateAuthority
— your Certificate Manager Authority URLcertificateAuthorityFingerprint
— your Certificate Manager Authority fingerprintcertificateIssuer.provisioner
— the name of your JWK provisionerdnsNames
— the DNS names you'd like your RA to be available on (these values will be added to the RA's TLS certificate subject)ca-url
— your Certificate Manager Authority URLfingerprint
— your Certificate Manager Authority fingerprintsecrets.certificate_issuer.password
— the base64 encoded JWK encryption key password. (echo 'your-jwk-password-here' | base64
)
-
In Helm, add the Smallstep Helm charts repository
{`$ helm repo add smallstep https://smallstep.github.io/helm-charts/`} {`$ helm repo update smallstep`} -
Install the Helm chart
{`$ helm install -f step_values.yml smallstep/step-certificates`} -
Configure your local ACME clients to use your RA (instead of Let's Encrypt)
We've written a tutorial for configuring popular ACME clients to use internal ACME.