Let's Encrypt Free SSL

Automated free SSL/TLS certificates with Let's Encrypt integration via acmetool.sh for Centmin Mod Nginx.

On this page

Overview

Free SSL certificates for Nginx HTTP/2 based SSL are available on Centmin Mod LEMP web stack thanks to Let's Encrypt. Let's Encrypt is a free, automated, and open Certificate Authority (CA) that provides Domain Validation (DV) SSL/TLS certificates at no cost.

Centmin Mod integrates Let's Encrypt through the addons/acmetool.sh addon script, which wraps the acme.sh client. This integration supports multiple Certificate Authority providers including Let's Encrypt, ZeroSSL, and Google Public CA.

If your Centmin Mod Nginx domain is behind Cloudflare's orange cloud proxy with Full or Full Strict SSL mode enabled, use the Cloudflare DNS API domain validation method for issuing SSL certificates on your origin server.

Key features of the Let's Encrypt integration:

  • Automated SSL certificate issuance and configuration for Nginx vhosts
  • Support for dual RSA 2048-bit + ECC 256-bit ECDSA certificates
  • DNS-based domain validation via Cloudflare DNS API
  • Webroot-based domain validation (default method)
  • Automatic certificate renewal via cron
  • Alternative CA providers: ZeroSSL and Google Public CA

Prerequisites

Domain DNS Requirements

To use Let's Encrypt SSL certificate support in Centmin Mod Nginx, ensure your domain name's DNS A records for the apex domain.com, www.domain.com, and/or any subdomain.domain.com point to your Centmin Mod server's IP address.

DNS propagation can take up to 24-48 hours. Verify your DNS records resolve correctly before attempting to issue SSL certificates. Let's Encrypt must be able to reach your server on port 80 for webroot validation.

By default, Let's Encrypt domain validation is done via the webroot authentication method, where the client automatically generates a challenge file at:

https://yourdomain.com/.well-known/acme-challenge/*

For domains behind a CDN or proxy, use DNS-based validation instead.

Issuing SSL Certificate

Enable Let's Encrypt Support

To enable native Let's Encrypt SSL certificate support, set the following variable in the persistent config file /etc/centminmod/custom_config.inc (create the file if it does not already exist):

LETSENCRYPT_DETECT='y'

This allows Centmin Mod Nginx's vhost creation routines to use addons/acmetool.sh to obtain free Let's Encrypt SSL certificates for the desired Nginx vhost domain name.

If LETSENCRYPT_DETECT is not set, Nginx vhost generation will default to creating self-signed SSL certificates. These are not browser-trusted but are useful for development testing without entries appearing in public SSL certificate transparency logs.

Using acmetool.sh

The primary tool for managing Let's Encrypt certificates is the acmetool.sh addon script located at:

/usr/local/src/centminmod/addons/acmetool.sh

For full details on usage, refer to the official community forum discussion thread.

Dual RSA + ECDSA Certificates

Centmin Mod Nginx uses OpenSSL 1.1.1+ which supports dual RSA 2048-bit + ECC 256-bit ECDSA SSL certificates. When enabled, two SSL certificates are issued: one RSA 2048-bit and one ECC 256-bit. Nginx will serve the ECC certificate to browsers that support it (better performance), falling back to RSA for browsers that don't.

To enable dual certificate support, add both variables to /etc/centminmod/custom_config.inc:

LETSENCRYPT_DETECT='y'
DUALCERTS='y'

ECC 256-bit ECDSA certificates offer smaller key sizes and faster TLS handshakes compared to RSA, improving site performance for modern browsers. See the Security Headers and SSL Testing sections below for more on SSL/TLS configuration.

ZeroSSL Alternative

ZeroSSL is an alternative free CA provider supported by Centmin Mod's acmetool.sh. Key differences from Let's Encrypt:

  • No rate limits for SSL certificate issuance
  • GUI-based management console for issued certificates
  • Better backward compatibility with older devices via cross-signed root certificates

Switching to ZeroSSL

Step 1. Register an account at ZeroSSL.com and obtain EAB credentials from app.zerossl.com/developer. Alternatively, register directly via the command line with your email:

acme.sh --register-account -m myemail@example.com --server zerossl

Step 2. If you obtained EAB credentials manually, register them with the acme.sh client:

acme.sh --register-account --server zerossl \
  --eab-kid xxxxxxxxxxxx \
  --eab-hmac-key xxxxxxxxx

Step 3. Set ZeroSSL as the default CA in /etc/centminmod/custom_config.inc:

ACME_DEFAULT_CA='zerossl'

To switch back to Let's Encrypt, remove the variable or set it explicitly:

ACME_DEFAULT_CA='letsencrypt'

Step 4. Reissue existing certificates using ZeroSSL with the reissue-only option (this only touches SSL certificate configuration, leaving the rest of your Nginx vhost config intact):

/usr/local/src/centminmod/addons/acmetool.sh reissue-only yourdomain.com live

DNS Validation

Cloudflare DNS API Validation

Centmin Mod's acmetool.sh supports DNS domain validation via the Cloudflare DNS API. Instead of webroot URL authentication, the client automatically generates a DNS TXT record through your Cloudflare API, and Let's Encrypt reads that record to validate your domain.

This method is recommended if your Centmin Mod Nginx domain is behind Cloudflare's orange cloud proxy with Full or Full Strict SSL mode enabled.

Add these variables to /etc/centminmod/custom_config.inc:

LETSENCRYPT_DETECT='y'
CF_DNSAPI_GLOBAL='y'
CF_Token="YOUR_CF_TOKEN"
CF_Account_ID="YOUR_CF_ACCOUNT_ID"

Creating a Cloudflare API Token

Create your Cloudflare API Token at dash.cloudflare.com/profile/api-tokens with the following permissions:

  • Read access to Zone.Zone
  • Edit/write access to Zone.DNS
  • Apply across all Zones

Your Cloudflare Account ID can be found on any of your Cloudflare domain's main dashboard in the right-side column.

Only one Cloudflare Account is supported per configuration. All intended domains must be within the same Cloudflare Account, unless you have a Cloudflare Account with invited administrator access to other accounts and can generate a CF API Token that includes access to those accounts.

Wildcard Certificates

Wildcard certificates (e.g., *.domain.com) require DNS-based validation. Webroot validation cannot be used for wildcard certificates. Configure the Cloudflare DNS API as described above, then use acmetool.sh to issue the wildcard certificate with DNS validation mode.

DNS propagation for TXT records may take a few minutes. The acme.sh client includes built-in wait and retry logic, but if validation fails, ensure the DNS TXT record has fully propagated before retrying.

Certificate Renewal

Automatic Renewal

Let's Encrypt SSL certificates are valid for 90 days. The acme.sh client installs a cron job that automatically renews certificates before they expire. No manual intervention is required for routine renewals.

The acme.sh cron job runs daily and will attempt renewal when a certificate has fewer than 30 days remaining. Nginx is automatically reloaded after a successful renewal.

Manual Renewal

To manually reissue an existing certificate, use the reissue-only option:

/usr/local/src/centminmod/addons/acmetool.sh reissue-only yourdomain.com live

Checking Certificate Dates

To list all SSL certificates and their expiry dates for all Nginx-configured sites on the server:

/usr/local/src/centminmod/addons/acmetool.sh checkdates

Example output showing both Nginx-installed and acme.sh-obtained certificates with their expiry dates and SHA1 fingerprints:

----------------------------------------------
nginx installed
----------------------------------------------

/usr/local/nginx/conf/ssl/domain.com/domain.com-acme.cer
SHA1 Fingerprint=06FE84519E09ACB75BBE11EDF26F7D41D0Bxxxxx
certificate expires in 83 days on 25 Dec 2021

----------------------------------------------
acme.sh obtained
----------------------------------------------

/root/.acme.sh/domain.com/domain.com.cer
SHA1 Fingerprint=06FE84519E09ACB75BBE11EDF26F7D41D0Bxxxxx
certificate expires in 83 days on 25 Dec 2021

Let's Encrypt has rate limits on certificate issuance. Avoid excessive manual reissuance. The default limit is 50 certificates per registered domain per week. ZeroSSL has no such rate limits.

Troubleshooting

Domain validation fails

Ensure your domain's DNS A record correctly points to your server's IP address. Verify with:

dig +short yourdomain.com A
dig +short www.yourdomain.com A

Port 80 not accessible

For webroot validation, Let's Encrypt needs to reach your server on port 80. Check that your firewall (CSF or iptables) allows incoming connections on port 80 and that Nginx is listening on port 80 for the domain.

Rate limit exceeded

Let's Encrypt limits certificate issuance to 50 per registered domain per week. If you hit this limit, wait for the window to reset or consider switching to ZeroSSL which has no rate limits.

ZeroSSL: "no eab credentials found"

This means you haven't registered your EAB credentials with the acme.sh client. Either register via the command line with your email address or manually provide the EAB key ID and HMAC key from the ZeroSSL developer portal.

Certificate behind Cloudflare proxy

If your domain is behind Cloudflare's orange cloud proxy, webroot validation will fail because requests are intercepted by Cloudflare. Switch to Cloudflare DNS API validation instead.

Certificate not auto-renewing

Check that the acme.sh cron job is installed and running. View the cron job with:

crontab -l | grep acme

For additional support, visit the official community forum discussion thread or the Cloudflare DNS API validation thread.

Security Headers

Security headers provide an additional layer of protection for your HTTPS site. Add these headers to your Nginx HTTPS server block to improve security.

HSTS (HTTP Strict Transport Security)

HSTS tells browsers to always use HTTPS for your domain, preventing protocol downgrade attacks and cookie hijacking:

nginx.conf
# max-age=31536000 = 1 year
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

HSTS is difficult to undo

Once HSTS is set with a long max-age, browsers will refuse to load your site over HTTP for that duration. Only enable HSTS when you are committed to HTTPS long-term. Start with a short max-age=300 for testing.

Clearing HSTS for a Domain

If you need to undo HSTS after enabling it, follow these steps. Start with the server-side fix, then clear the cached policy in each browser that visited your site.

Server-Side (Recommended First Step)

Send a header with max-age=0 over HTTPS to immediately expire the cached HSTS policy. Per the MDN specification, this tells browsers to stop enforcing HSTS for your domain.

nginx.conf
# Set max-age=0 to expire HSTS policy immediately
add_header Strict-Transport-Security "max-age=0" always;

The max-age=0 header must be served over HTTPS. Browsers will not accept HSTS headers delivered over plain HTTP by design.

Browser-Specific Clearing

After updating the server header, clear the cached HSTS policy in each browser that has visited your site:

Google Chrome / Chromium

  1. Navigate to chrome://net-internals/#hsts
  2. Under "Delete domain security policies", enter your domain
  3. Click Delete
  4. Restart the browser

Microsoft Edge

  1. Navigate to edge://net-internals/#hsts
  2. Under "Delete domain security policies", enter your domain
  3. Click Delete, then restart the browser

Brave

  1. Navigate to brave://net-internals/#hsts
  2. Under "Delete domain security policies", enter your domain
  3. Click Delete, then restart the browser

Opera

  1. Navigate to opera://net-internals/#hsts
  2. Under "Delete domain security policies", enter your domain
  3. Click Delete, then restart the browser

Firefox

Method 1 — Forget Site:

  1. Open History (Ctrl+Shift+H / Cmd+Shift+H)
  2. Search for your domain
  3. Right-click the entry → Forget About This Site

Method 2 — Edit profile file:

  1. Navigate to about:support → click Open Profile Folder
  2. Close Firefox, then edit SiteSecurityServiceState.txt
  3. Delete the line containing your domain, save the file
  4. Restart Firefox

Safari (macOS)

  1. Close Safari completely
  2. Delete ~/Library/Cookies/HSTS.plist
  3. Reopen Safari

Note: This clears HSTS for all sites, not just your domain.

HSTS Preload List Removal

If your domain was submitted to the HSTS preload list, additional steps are required:

  1. Remove the preload directive from your HSTS header
  2. Submit a removal request at hstspreload.org/removal

Preload list updates ship with browser releases, so removal can take weeks to months to propagate to all users.

Additional Security Headers

Other recommended security headers to add to your HTTPS vhost:

nginx.conf
# Prevent MIME-type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Prevent clickjacking - restrict iframe embedding
add_header X-Frame-Options "SAMEORIGIN" always;

# XSS protection (legacy browsers)
add_header X-XSS-Protection "1; mode=block" always;

# Referrer policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Content Security Policy (customize per your needs)
# add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;

Content Security Policy

CSP headers need to be customized for each site. A misconfigured CSP can break your website. Use Mozilla's CSP documentation as a guide, and test with Content-Security-Policy-Report-Only before enforcing.

SSL Testing

After configuring SSL/TLS, test your setup using these tools to verify your configuration is secure and correctly implemented.

Recommended Testing Tools

  • Qualys SSL Labs — The most comprehensive SSL/TLS test. Aim for an A+ rating. Tests protocol support, cipher suites, key exchange, and certificate chain.
  • GlobalSign SSL Check — Verifies certificate installation and chain completeness.
  • GeoCerts SSL Checker — Quick certificate validity and expiration check.

Achieving an A+ Rating

To get an A+ on SSL Labs, you need: TLS 1.2/1.3 only (no TLS 1.0/1.1), HSTS header with max-age of at least 6 months, forward secrecy cipher suites, and OCSP stapling enabled.

Command-Line Testing

You can also test your SSL configuration directly from the server via SSH:

terminal
# Test TLS connection and view certificate details
openssl s_client -connect domain.com:443 -tls1_2 -tlsextdebug -status

# Check certificate expiration date
echo | openssl s_client -servername domain.com -connect domain.com:443 2>/dev/null | openssl x509 -noout -dates

# Verify Nginx config before restarting
nginx -t