Solution overview
ACME (Automatic Certificate Management Environment) is a protocol used to automate the process of issuing, renewing, and managing digital certificates. It enables servers and certificate authorities to communicate securely, allowing website owners to prove domain control and obtain trusted TLS certificates without manual intervention. This automation simplifies deploying HTTPS, improving security by ensuring certificates are always up to date.
Keyfactor’s EJBCA PKI can serve as a registration authority (RA) that supports the ACME protocol and full Certbot compatibility. This guide provides instructions on how to:
- Configure EJBCA profiles (end entity and certificate) to serve Certbot compliant certificates.
- Configure EJBCA as an ACME server to process requests from Certbot.
- Install and configure Certbot on Linux machines to get certificates from EJBCA via the ACME protocol.
The ACME protocol is used to automatically prove control over a domain so that a certificate authority can issue a trusted certificate. To validate ownership, ACME defines different types of “challenges.” A challenge is essentially a test that the certificate authority asks you to complete, demonstrating that you really control the domain name you are requesting a certificate for. The most common challenges are http-01, dns-01, and tls-alpn-01.
-
http-01. In the
http-01challenge, the ACME client, like Certbot, creates a special file with a unique token in a well-known location on your web server. The certificate authority then makes an HTTP request tohttp://yourdomain/.well-known/acme-challenge/<token>to retrieve and verify the file. If the server responds correctly with the expected contents, it proves that you control the web server for the domain. -
dns-01. The
dns-01challenge works differently. Instead of serving a file over HTTP, a special DNS TXT record is created under your domain containing a unique token. The EJBCA queries the DNS records and verifies that the TXT record is present with the correct value. For automation, this requires creating scripts to automate the DNS record, and is more problematic. -
tls-alpn-01. The
tls-alpn-01challenge uses a dedicated TLS handshake to prove control. In this method, the server must respond to a connection on port 443 with a specific TLS certificate extension containing the validation token. This approach is a bit more advanced and requires precise server configuration.
Among all three, automating with Certbot is easiest using http-01 because Certbot can automatically create and remove the challenge file on your web server without needing DNS access or special TLS configuration. This example explains how to set up this challenge-response.
Prerequisites
System prerequisites
This guide assumes the following:
- EJBCA is installed and has a PKI chain (root, policy, issuing, etc. CAs are configured).
- The user has administration capabilities on EJBCA for:
- RA configuration
- System configuration
- End entity profile creation
- Certificate profile creation
- The user has superadmin privileges on the Linux server.
- There is a Linux server target (Debian or RHEL based) for Certbot to be installed on.
Determine your Linux distribution type
This guide assumes a Debian-based or RHEL-based distribution of Linux. To verify your distribution, use the following command.
cat /etc/os-release | grep ID_LIKE
Example output
ID_LIKE="rhel centos fedora" for a RHEL-based build. ID_LIKE=debian for a Debian-based build.
Procedure
Step 1: EJBCA setup
Step 1.a.: Configure certificate profile
- Log in to your management CA’s adminweb.
- Select CA Functions > Certificate Profiles. The Manage Certificate Profiles page displays a list of available profiles.
- Click Clone next to the SERVER template to use that as a basis for creating your new profile.
- Name the new certificate profile, and then click Create from template.
- On the Edit page, verify that the type is End Entity, and then update the following:
- For Signature Algorithm, verify that Inherit from Issuing CA is selected.
- For Validity or end date of the certificate, specify
47dfor 47-day certs. - Expiration Restrictions: Enable to only allow certificates to expire on Tuesdays, Wednesdays, and Thursdays to avoid certificates expiring close to a weekend.
- Under Permissions, make sure the following items are checked.
- Allow Subject DN Override by End Entity Information
- Use Certificate Storage
- Store Certificate Data
- The X.509v3 extensions section allows you to define the extensions added to the certificate:
- For Key Usage, verify that Digital Signature and Key encipherment are the only items selected.
- For Extended Key Usage, verify that Server Authentication is selected.
- For X.509v3 extensions - Names, verify that Subject Alternative Name is selected and clear the Issuer Alternative Name.
- Under X.509v3 extensions - Validation data:
- Enable CRL Distribution Points to allow validation later on.
- Enable Use CA defined CRL Distribution Point to use the value preconfigured in the CA.
- Enable Authority Information Access to use the locations configured in your CA settings.
- Enable Use CA defined OCSP locator for where the OCSP services are available.
- Enable Use CA defined CA issuer for where the issuing CA certificate can be retrieved from.
- Under Other Data, update the following:
- Clear LDAP DN order to disable the LDAP ordering of the DN attributes and use the standard X.509 ordering instead.
- For Available CAs select the Issuing CA that is associated with ACME requests.
- Click Save to store the certificate profile.
Step 1.b.: Configure end entity profile
- Select RA Functions > End Entity Profiles to view a list of all certificate profiles.
- In the Add Profile field, add a name for the new profile, and then click Add profile.
- Select the newly created profile, and then click Edit End Entity Profile to update the profile.
- Verify or update the following items.
- For Type select Default.
- For Batch generation (clear text pwd storage) make sure Use… is checked.
- For End Entity E-Mail make sure:
- Use… is checked.
- Required is unchecked.
- Modifiable is checked.
- For the Subject CN Attributes, verify that CN, Common Name is Required and Modifiable.
The default CSR that Certbot creates only uses the CN attribute. If any other attributes are required, we can have EJBCA add them to the certificate. To implement this, select the attribute you want to use [for example O, Organization] and then click Add.
Make sure both Required and Modifiable are unchecked and that the box has a default value entered [for example, Keyfactor].
- For the Other Subject Attributes, make sure that DNS Name is showing and that only Modifiable is checked.
- For Main Certificate Data, make sure that:
- The Default Certificate Profile and the Available Certificate Profiles have only the certificate profile created above selected.
- The Default CA and the Available CAs have only the Issuing ACME CA selected.
- The Default Token and the Available Tokens only have User Generated selected, as Certbot is sending a PKCS#10 [CSR] request to EJBCA.
- Select the Save button at the bottom of the page to save the end entity profile.
Step 1.c.: Configure ACME alias / endpoint
In EJBCA, select System Configuration > ACME Configuration to manage the ACME aliases. In EJBCA, multiple ACME aliases can be created for different use cases. Each alias is tied to an end entity profile.
- Under List of ACME Aliases, click Add.
- In the configuration screen, add or update the following:
- For Name, enter the name to use for the endpoint. This name is used to call this endpoint via
/ejbca/acme/<name>/directory. For example, if your server is located atejbca.example.comthen the URL for an endpoint named my-acme would behttps://ejbca.example.com/ejbca/acme/my-acme/directory. - For RA Name Generation Scheme, use the radio button to select the end entity name that the endpoint generates when fulfilling an ACME certificate request select DN.
DN takes a part of the PKCS#10 [CSR] subject and creates the end entity username from that. CN (Common Name) is already selected; therefore, only select the DN radio button.
- For Name, enter the name to use for the endpoint. This name is used to call this endpoint via
- For End Entity Profile, select the profile created above.
- For DNS identifier challenge types, select http-01. Refer to the Solution overview for more information.
- Require client approval for Terms of Service changes should be unchecked to ease automation efforts.
- Agree to new Terms of Service allowed should be checked to ease automation.
- All other fields can remain the default.
- Select Save to save the alias to EJBCA.
Step 2: Enable the ACME protocol in EJBCA
In EJBCA, select System Configuration > System Configuration > Protocol Configuration to get to the list of protocols enabled in EJBCA.
For the ACME row, make sure Status is Enabled. If it isn’t, select the Enable button.
Step 3: Linux setup and installation for Certbot
Debian and RHEL Linux distributions use different tools for package management, and as a result will use different commands for installation.
Below are some common Debian and RHEL-based distributions and their respective package manager commands to update and install prerequisites.
To find your distribution, run the following command from the command prompt.
cat /etc/os-release
| Debian-based distributions | RHEL-based distributions |
|---|---|
| Ubuntu | CentOS Stream |
| Kali Linux | Fedora |
| Linux Mint | Rocky Linux |
| Pop!_OS | AlmaLinux |
| MX Linux | Oracle Linux |
| Parrot OS | ClearOS |
| Deepin | Scientific Linux |
| Tails | EuroLinux |
| Raspberry Pi OS | Red Hat OpenShift (CoreOS base) |
| Devuan | Amazon Linux 2 (partially RHEL-based) |
| Springdale Linux |
Debian builds
Execute the following commands to update and install Certbot.
sudo apt update && sudo apt upgrade -y sudo apt install -y certbot
RHEL builds
Execute the following command to update and install Certbot.
sudo dnf update -y sudo dnf install -y certbot
Step 4: Update the Linux trust store
The Linux machine must trust the EJBCA endpoint. To do this, we must update the trust store on the machine. There are differences between Debian-based and RHEL-based installations. However, both start the same way.
- Download the Management CA certificate from EJBCA.
- Log in to the EJBCA RA Web interface by navigating to the
https://<ra-url>/ejbca/ra/page. - At the top of the page, select CA Certificates and CRLs.
- Under the Certificate column, select PEM for the row associated with your EJBCA’s management CA.
- Rename the file to end in
.crtfor capability. - Copy the file to the Linux machine.
-
Install the certificate on the machine.
For RHEL-based distributions:sudo cp <my-ejbca-cert.crt> /etc/pki/ca-trust/source/anchors/ sudo update-ca-trust extractFor Debian-based distributions:
sudo cp <my-ejbca-cert.crt> /usr/local/ca-certificates/ sudo update-ca-certificates --fresh
Step 5: Run Certbot to get a certificate
Run the following command to get an RSA/2048 certificate (the default).
sudo certbot certonly --standalone --preferred-challenges http \ --server https://<ejbca-ra-url>/ejbca/acme/<alias-name>/directory \ --pre-hook "systemctl stop <webserver>" \ --post-hook "systemctl start <webserver>" \ --non-interactive --agree-tos --email <email-address> \ -d <FQDN>
systemctl stop and systemctl start are required if there is a process already bound to port 80. Certbot needs access to that port for the http-01 challenge-response.
For example, to register against the EJBCA instance ejbca.example.com and the alias acme-http and the FQDN of myserver.example.com and the web server of nginx, the command would look like the following:
sudo certbot certonly --standalone --preferred-challenges http \ --server https://ejbca.example.com/ejbca/acme/acme-http/directory \ --pre-hook "systemctl stop nginx" \ --post-hook "systemctl start nginx" \ --non-interactive --agree-tos --email keyfactor@example.com \ -d myserver.example.com
Other options
Different RSA key size
If a different key size is required (e.g., 4096) with RSA, then add the following flag right after the email address and the FQDN.
--rsa-key-size <keysize>
In the example above, this would look like the following:
sudo certbot certonly --standalone --preferred-challenges http \ --server https://ejbca.example.com/ejbca/acme/acme-http/directory \ --pre-hook "systemctl stop nginx" \ --post-hook "systemctl start nginx" \ --non-interactive --agree-tos --email keyfactor@example.com \ --rsa-key-size 4096 \ -d myserver.example.com
Different ECC key and curve
If ECDSA is required, then add the following between email and FQDN.
--key-type ecdsa --elliptic-curve <curve-selection>
In the example above, this would look like the following (ECC Key with a secp384r1 curve):
sudo certbot certonly --standalone --preferred-challenges http \ --server https://ejbca.example.com/ejbca/acme/acme-http/directory \ --pre-hook "systemctl stop nginx" \ --post-hook "systemctl start nginx" \ --non-interactive --agree-tos --email keyfactor@example.com \ --key-type ecdsa --elliptic-curve secp384r1 \ -d myserver.example.com
Update your application to consume the key, cert, and cert-chain as required. The files are located here /etc/letsencrypt/live/<FQDN>/.
Example nginx configuration
Assume you have this default nginx configuration, and your website is www.example.com.
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}To get it to use your certificate and key, you need to make it look like the following:
# Here is the http server, let's redirect everything to https
server {
listen 80;
server_name www.example.com;
# Redirect everything to https://
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
server_name www.example.com;
root /var/www/html;
index index.html;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
# Recommended SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ =404;
}
}After updating the configuration, verify it is ok by running the following:
sudo nginx -t
If the configuration has no errors, then restart nginx to apply the new configuration.
sudo systemctl restart nginx
Step 6: Verify configuration
Certbot places the key, cert, and cert-chain into the following location.
/etc/letsencrypt/live/<FQDN>/
To verify the certificate’s contents, use openSSL, as follows:
sudo openssl x509 -noout -text \ -in /etc/letsencrypt/live/<FQDN>/cert.pem
For example, if the <FQDN> is www.example.com, the command becomes:
sudo openssl x509 -noout -text \ -in /etc/letsencrypt/live/www.example.com/cert.pem
The output should show a valid certificate.
For a web server, the simplest verification is to navigate to the web site and prove that the connection is trusted!
Add comment
Please sign in to leave a comment.