This guide will help you set up and use Acme.sh to get free SSL certificates for your website. SSL certificates make your website secure (the padlock icon in the browser) and are essential for any modern website.
Before you start: Make sure you have already installed Acme.sh on your server. If you have not, you will need to do that first.
If you use cPanel hosting and have SSH access, this is the easiest way to get started.
a. Log in to your cPanel account, go to the Advanced section, and click on Terminal.
b. Alternatively, if you do not see the Terminal option in cPanel, you can connect using any SSH client (for example, PuTTY or OpenSSH). Use your server's IP address as the Host Name, and enter your cPanel username and password to log in.
* To install acme.sh, please refer to the Installation Guide here: [Link].
| ???? Note In cPanel, acme.sh or any similar tool will be installed in your home directory. |
You need to provide some important information. Copy these lines and replace the XXXX parts with your actual details:
export ACME_SERVER="https://demo.acme-server.com/directory"
export EAB_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export HMAC_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export EMAIL="admin@example.com"
export CF_Token="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
What these mean:
| Variable | Description |
|---|---|
ACME_SERVER | The address of your SSL certificate provider |
EAB_KEY | Your unique identification key (get this from your provider) |
HMAC_KEY | Your secure password key (get this from your provider) |
EMAIL | Your email address for notifications |
CF_Token | Your Cloudflare security token (if using Cloudflare) |
Register with the certificate provider:
acme.sh --register-account \
--server "$ACME_SERVER" \
--eab-kid "$EAB_KEY" \
--eab-hmac-key "$HMAC_KEY"
This creates your account with the SSL certificate provider.
Now get your SSL certificate and install it automatically:
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d cptest.example.com \
--deploy-hook cpanel_uapi
Replace cptest.example.com with your actual domain name.
What happens here:
Your certificate will automatically renew, but you can test it:
acme.sh --renew -d cptest.example.com --force
Check that automatic renewal is set up:
crontab -l | grep acme.sh
You should see a scheduled task that will run automatically to renew your certificate.
acme.sh --deploy -d cptest.demo.com --deploy-hook cpanel_uapi
This command connects to the cPanel Universal API (cpanel_uapi) and deploys the SSL certificate for cptest.demo.com to its respective domain.
???? Note You can run the certificate issue/renew together with the deployment command in a single step: acme.sh --issue --server "$ACME_SERVER" --dns dns_cf -d cptest.example.com --deploy-hook cpanel_uapi |
This is for one website address (like www.example.com):
source ~/.acme.sh/config/acme-server.env
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d demo.example.com
If you want one certificate to cover several related domains:
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d demo.example.com \
-d www.demo.example.com \
-d mail.demo.example.com \
-d api.demo.example.com
Use this when: You have multiple subdomains that belong together (like www, mail, and api).
This covers ALL possible subdomains under your main domain:
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d "*.example.com" \
-d example.com
Use this when: You have many subdomains or create them frequently.
Example: One certificate covers blog.example.com, shop.example.com, mail.example.com, etc.
Combine wildcard with specific domains:
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d "*.example.com" \
-d example.com \
-d www.example.com \
-d mail.example.com
After getting a certificate, Acme.sh saves several files in a folder:
~/.acme.sh/demo.example.com/
??? ca.cer # Intermediate certificate
??? demo.example.com.cer # Your main certificate
??? demo.example.com.key # Private key (KEEP SECRET!)
??? fullchain.cer # Complete certificate chain
??? demo.example.com.conf # Settings file
| File | Description |
|---|---|
fullchain.cer | Use this for most web servers (Apache, Nginx). Contains your complete certificate with all necessary parts. |
demo.example.com.key | KEEP THIS SECRET. This is your private key. Never share it or upload it to public places. |
demo.example.com.cer | Your main certificate only (without intermediate certificates). |
ca.cer | Intermediate certificate from the certificate authority. |
demo.example.com.conf | Acme.sh settings file for this domain (renewal config, hooks, etc.). |
acme.sh --install-cert \
-d demo.example.com \
--cert-file /etc/ssl/certs/demo.example.com.cer \
--key-file /etc/ssl/private/demo.example.com.key \
--fullchain-file /etc/ssl/certs/fullchain.cer \
--reloadcmd "systemctl reload apache2"
This copies your certificate to the right locations and restarts Apache automatically.
This creates a secure website configuration:
sudo tee /etc/apache2/sites-available/demo.example.com-ssl.conf > /dev/null << 'EOF'
<VirtualHost *:443>
ServerName demo.example.com
ServerAdmin admin@demo.example.com
DocumentRoot /var/www/demo.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/demo.example.com.cer
SSLCertificateKeyFile /etc/ssl/private/demo.example.com.key
SSLCertificateChainFile /etc/ssl/certs/fullchain.cer
SSLProtocol -all +TLSv1.2 +TLSv1.3
</VirtualHost>
EOF
sudo a2enmod ssl headers
sudo a2ensite demo.example.com-ssl
sudo systemctl reload apache2
What this does:
acme.sh --install-cert \
-d demo.example.com \
--cert-file /etc/ssl/certs/demo.example.com.cer \
--key-file /etc/ssl/private/demo.example.com.key \
--fullchain-file /etc/ssl/certs/fullchain.cer \
--reloadcmd "systemctl reload nginx"
sudo tee /etc/nginx/sites-available/demo.example.com > /dev/null << 'EOF'
server {
listen 443 ssl http2;
server_name demo.example.com;
ssl_certificate /etc/ssl/certs/fullchain.cer;
ssl_certificate_key /etc/ssl/private/demo.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
}
# HTTP to HTTPS redirect
server {
listen 80;
server_name demo.example.com;
return 301 https://$host$request_uri;
}
EOF
This configuration also automatically redirects visitors from HTTP to HTTPS.
sudo nginx -t
sudo systemctl reload nginx
The first command checks if your configuration is correct. The second restarts Nginx.
acme.sh --list
This shows all domains with certificates and their expiry dates.
acme.sh --info -d demo.example.com
This shows:
echo | openssl s_client -connect demo.example.com:443 -servername demo.example.com 2>/dev/null | openssl x509 -noout -dates
This shows the certificate start and end dates. Example output:
notBefore=Feb 9 10:00:00 2026 GMT
notAfter=May 10 10:00:00 2026 GMT
Acme.sh supports managing multiple EAB accounts using different working directories. If your server hosts multiple websites and you need to install a separate Single Domain SSL certificate for each domain using different EAB accounts, this option is helpful.
To manage multiple EAB accounts on the same web server, you should create separate working directories for acme.sh. This allows each account to store and manage its own certificates independently, keeping everything organized and avoiding conflicts.
export LE_WORKING_DIR="$HOME/.acme.sh.account1"
export EAB_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_account1"
export HMAC_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_account1"
acme.sh --register-account \
--server "$ACME_SERVER" \
--eab-kid "$EAB_KEY" \
--eab-hmac-key "$HMAC_KEY"
export LE_WORKING_DIR="$HOME/.acme.sh.account2"
export EAB_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_account2"
export HMAC_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_account2"
acme.sh --register-account \
--server "$ACME_SERVER" \
--eab-kid "$EAB_KEY" \
--eab-hmac-key "$HMAC_KEY"
export LE_WORKING_DIR="$HOME/.acme.sh.account1"
acme.sh --issue --server "$ACME_SERVER" --dns dns_cf -d example.com
| Symptoms | Certificate fails to issue, DNS errors in logs |
| Solution | Test with detailed debugging — the command below shows exactly what is happening with your DNS provider. |
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d demo.example.com \
--debug 2
| Symptoms | Process takes too long and fails |
| Solution | Increase timeout values using the variables below before running the issue command. |
export Le_HTTPTimeout=600
export Le_DNSSleep=120
acme.sh --issue \
--server "$ACME_SERVER" \
--dns dns_cf \
-d demo.example.com
What these mean:
Le_HTTPTimeout — How long to wait for server responses (600 seconds = 10 minutes)Le_DNSSleep — How long to wait for DNS changes (120 seconds = 2 minutes)Check the scheduled job:
crontab -l | grep acme.sh
If nothing appears, the automatic renewal is not set up.
Test renewal manually with debugging:
acme.sh --cron --force --debug 2
This shows any errors preventing automatic renewal.
Before going live with your SSL certificate, verify everything using the checklist below.
| ? | Acme.sh installed and version shows correctly |
| ? | Configuration variables set up |
| ? | DNS provider credentials working |
| ? | Account registered with certificate provider |
| ? | Test certificate issued successfully |
| ? | Certificate installed on web server |
| ? | Web server configured for HTTPS |
| ? | Website loads with padlock icon |
| ? | Custom deployment scripts created and tested |
| ? | Automatic renewal scheduled (cron job exists) |
| ? | Manual renewal test successful |
| ? | Deployment hooks run correctly |
| ? | Private key files have restricted permissions (600) |
| ? | Certificate files readable by web server |
| ? | HTTPS redirects working |
| ? | Security headers configured |
| Resource | URL |
|---|---|
| Acme.sh GitHub | https://github.com/acmesh-official/acme.sh |
| Complete Documentation | https://github.com/acmesh-official/acme.sh/wiki |
| DNS Provider Setup Guides | https://github.com/acmesh-official/acme.sh/wiki/dnsapi |
| Deployment Examples | https://github.com/acmesh-official/acme.sh/wiki/deployhooks |
| Topic | What Was Covered |
|---|---|
| SSL Certificate Installation | Using Acme.sh to get free, trusted certificates |
| Certificate Types | Single domain, multiple domains, and wildcard certificates |
| Web Server Setup | Installing certificates on Apache and Nginx |
| Automation | Setting up automatic renewal so you never forget |
| Monitoring | Checking certificate health and viewing logs |
| Troubleshooting | Fixing common problems when they occur |
| # | Point | Detail |
|---|---|---|
| 1 | Certificates renew automatically | Acme.sh checks daily and renews 60 days before expiry |
| 2 | Always use fullchain.cer | This file contains everything your web server needs |
| 3 | Keep your private key secret | Never share or publish the .key file |
| 4 | Test renewals regularly | Run manual renewal tests to ensure automation works |
| 5 | Monitor expiry dates | Even with automation, check that certificates stay valid |
| 6 | Backup your configuration | Regularly save your Acme.sh folder |
Once everything is set up:
| ???? Congratulations! You have successfully set up automated SSL certificate management for your website. |
End of Acme.sh SSL Deployment Guide