SSLmentor

Quality TLS/SSL certificates for websites and internet projects.

Certbot

Certbot

ACME client Certbot

A detailed guide for complete deployment of a DV ACME SSL certificate on Debian (Apache) VPS with automatic renewal via the default Certbot timer. The guide describes deployment of a single-domain or multi-domain DV certificate, for example example.com and www.example.com. For standard deployments, we recommend using the standard Certbot directory /etc/letsencrypt. This way, renewals are handled by the default system timer certbot.timer.
This guide does not cover wildcard WildCard SSL certificates, which require DNS validation and a DNS API for automatic renewal.

Basic concepts

  • ACME – Protocol for automated issuance and renewal of SSL/TLS certificates.
  • Certbot – An ACME client that communicates with the certification authority and can deploy a certificate to Apache.
  • kid + hmac – External Account Binding (EAB) credentials from the certification authority. They link Certbot to an account or product.
    kid and hmac do not verify domain ownership, they bind the ACME client to a CA account. The domain is verified separately via ACME challenge. hmac is a sensitive value — do not share it publicly or store it in shared guides.
  • http-01 – Domain validation via a temporary file accessible at the domain's HTTP address.
  • dns-01 – Validation via DNS TXT record. Required for wildcard certificates.

In the examples, replace example.com with your own domain.

Apache, webroot

Basic Apache and domain configuration on the server.

›› Show/Hide section

Creating a separate webroot for the domain and a simple test page. Apache on Debian uses the www-data user by default.

apt update
apt install -y apache2
systemctl enable --now apache2
a2enmod rewrite headers ssl
systemctl reload apache2
Command What it does
apt update Updates the package list from Debian repositories.
apt install -y apache2 Installs the Apache web server. The -y parameter automatically confirms the installation.
systemctl enable --now apache2 Enables Apache at server startup and starts it immediately.
a2enmod rewrite headers ssl Enables common Apache modules for redirects, headers, and HTTPS.
systemctl reload apache2 Reloads the Apache configuration without a full service restart.

Preparing the webroot

DOMAIN="example.com"

mkdir -p /var/www/$DOMAIN/public
chown -R www-data:www-data /var/www/$DOMAIN
chmod -R 755 /var/www/$DOMAIN
echo "OK $DOMAIN" > /var/www/$DOMAIN/public/index.html

Creating an Apache virtual host


cat > /etc/apache2/sites-available/$DOMAIN.conf <<EOF
<VirtualHost *:80>
    ServerName $DOMAIN
    ServerAlias www.$DOMAIN

    DocumentRoot /var/www/$DOMAIN/public

    <Directory /var/www/$DOMAIN/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
    CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
</VirtualHost>
EOF
            

Activating the Apache site and HTTP check
Before issuing the certificate, the domain must respond via HTTP. This is required for ACME http-01 validation.

a2ensite $DOMAIN.conf
apache2ctl configtest
systemctl reload apache2

curl -I http://$DOMAIN
curl http://$DOMAIN

Installing Certbot + issuing a certificate

Installing Certbot from Debian repositories. The python3-certbot-apache package allows Certbot to modify the Apache configuration, perform validation, and deploy the issued certificate.

apt install -y certbot python3-certbot-apache
certbot --version

Certbot supports a wide range of systems and web servers. We recommend checking Certbot Instructions for the specific procedure for your chosen web server.

ACME account registration

To issue a certificate, you need to have an ACME account with the certification authority. In this guide, we will use ACME certificates from CA Certum.
You will obtain the EAB credentials (kid + hmac) in the order details.

certbot register \
--server https://acme.certum.pl/directory \
--email certum@example.com \
--agree-tos \
--eab-kid 'KID' \
--eab-hmac-key 'HMAC'
Parameter Meaning
--server Specifies the particular ACME endpoint. Without this parameter, Certbot would use the default ACME server.
CA DigiCert: https://one.digicert.com/mpki/api/v1/acme/v2/directory
CA Sectigo: https://acme.sectigo.com/v2/DV
--email Contact email for the ACME account.
--agree-tos Acceptance of the terms of service.
--eab-kid KID identifier.
--eab-hmac-key Secret HMAC EAB key.

Issuing an ACME certificate

certbot --apache \
--server https://acme.certum.pl/directory \
--cert-name $DOMAIN \
-d $DOMAIN \
-d www.$DOMAIN

The --cert-name parameter is especially important when managing multiple certificates on one server. Each individual certificate should have its own unique name.

Verifying the certificate and automatic renewal

certbot certificates
systemctl list-timers | grep certbot
certbot renew --dry-run
curl -I https://$DOMAIN
Command Purpose
certbot certificates Displays certificates managed by Certbot.
systemctl list-timers | grep certbot Verifies that the default automatic renewal timer is running.
certbot renew --dry-run Simulates certificate renewal without replacing the production certificate. Correct output: "all simulated renewals succeeded".
curl -I https://$DOMAIN Verifies the HTTPS response of the domain.

Multiple certificates on one server

Certbot can manage multiple certificates in the standard /etc/letsencrypt directory. This model is the simplest for customer deployments because it uses the default certbot.timer.

  • Create a separate Apache vhost
    Each domain should have its own file in /etc/apache2/sites-available/ and its own webroot.
  • Issue a certificate with a unique --cert-name
    Do not use the same certificate name for a different individual certificate.
  • Verify renewal of all certificates
    The certbot renew --dry-run command must pass for all entries in /etc/letsencrypt/renewal/.

Sample command for an additional domain example.net:


DOMAIN="example.net"

mkdir -p /var/www/$DOMAIN/public
chown -R www-data:www-data /var/www/$DOMAIN
chmod -R 755 /var/www/$DOMAIN
echo "OK $DOMAIN" > /var/www/$DOMAIN/public/index.html

cat > /etc/apache2/sites-available/$DOMAIN.conf <<EOF
<VirtualHost *:80>
    ServerName $DOMAIN
    ServerAlias www.$DOMAIN

    DocumentRoot /var/www/$DOMAIN/public

    <Directory /var/www/$DOMAIN/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
    CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
</VirtualHost>
EOF

a2ensite $DOMAIN.conf
apache2ctl configtest
systemctl reload apache2
curl -I http://$DOMAIN

certbot --apache \
--server https://acme.certum.pl/directory \
--cert-name $DOMAIN \
-d $DOMAIN
-d www.$DOMAIN

certbot renew --dry-run
        

Workaround for multiple EAB accounts

At the certification authority, each product may have its own EAB values. If a CA ACME account is already registered on the server, another registration for the same ACME server may result in an error:

There is an existing account; registration of a duplicate account with this command is currently unsupported.In such a situation, stay in the standard /etc/letsencrypt, but register the new account using the following workaround. After issuance, use the specific --account ACCOUNT_ID.

Temporarily moving existing accounts
ACME_ACCOUNT_DIR="/etc/letsencrypt/accounts/acme.certum.pl/directory"
BACKUP_DIR="/root/certbot-certum-accounts-backup-$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"
find "$ACME_ACCOUNT_DIR" -mindepth 1 -maxdepth 1 -type d -exec mv {} "$BACKUP_DIR"/ \;
Registering a new EAB account
certbot register \ --server https://acme.certum.pl/directory \ --email certum@example.com \ --agree-tos \ --eab-kid 'KID' \ --eab-hmac-key 'HMAC'
Finding the new account ID
ls -1 "$ACME_ACCOUNT_DIR"

The output of this command is the new ACCOUNT_ID. Use this value when issuing the certificate.

Restoring the original accounts
find "$BACKUP_DIR" -mindepth 1 -maxdepth 1 -type d -exec mv {} "$ACME_ACCOUNT_DIR"/ \;
Issuing a certificate via a specific account
certbot --apache \ --server https://acme.certum.pl/directory \ --account ACCOUNT_ID \ --cert-name example.net \ -d example.net \ -d www.example.net
Why the workaround is needed What it solves
Certbot refuses to register a duplicate account for the same ACME server. Temporarily moving accounts allows registration of a new EAB account.
The standard /etc/letsencrypt should remain on the server. The default certbot.timer then renews all certificates without a custom cron.
Each CA product may have its own EAB binding. The --account parameter forces the correct CA account during issuance.
Verification checklist
  • apache2ctl configtest returns Syntax OK.
  • curl -I http://example.com responds via HTTP.
  • curl -I https://example.com responds via HTTPS.
  • certbot certificates displays the expected certificate.
  • certbot renew --dry-run passes without error.
  • systemctl list-timers | grep certbot shows an active certbot.timer.

Back to Help
Found an error or don't understand something? Write us!

CA Sectigo
CA RapidSSL
CA Thawte
CA GeoTrust
CA DigiCert
CA Certum