In this article, you will learn how to enable SSL/TLS support for websites using either the Apache or NGINX server, with the help of acme.sh and Let’s Encrypt.

Search engines prefer websites with a valid SSL certificate. An SSL certificate secures user data, verifies website ownership, prevents fraudsters from creating fake versions of your site, and builds user trust. That is why it is essential to secure your website with a valid SSL certificate.

Install Required Applications

To obtain a Let’s Encrypt certificate, you’ll need to install ACME client software. There are several third-party ACME clients available, such as Certbot, acme.sh, and others. In this guide, we’ll be using acme.sh because it’s lightweight and written purely in shell, with no dependencies on other programming languages.

To install acme.sh, run the following command:

curl https://get.acme.sh

If you are an Alpine Linux user, make sure you install the apache2-ssl package. Use the following command to install this package:

apk add apache2-ssl --no-cache

Command to Issue a Certificate

acme.sh supports various RFC8555-compliant Certificate Authorities (CA), such as ZeroSSL (default) and Let’s Encrypt. In this guide, we’ll use Let’s Encrypt as the certificate authority because it is widely trusted and provides free SSL certificates. The following script switches the default CA in acme.sh to Let’s Encrypt.

# Switch to root user
sudo su
# Navigate to user's home directory
cd ~
# Create a hidden folder .acme.sh
mkdir .acme.sh

export email=your_email@example.com

# Set Let's Encrypt as the default CA
acme.sh --set-default-ca --server letsencrypt

Issuing a Certificate for Multiple Domains

Obtaining an SSL certificate using acme.sh is straightforward. You only need to execute one command, and the certificate authority will issue an SSL certificate for your domain(s). Before running the command, ensure that your domain name is accessible on port 80, as this is necessary for acme verification (HTTP-01 challenge). The following commands issue an SSL certificate for multiple domains and install the generated SSL certificates in the /etc/ssl directory.

# Command for NGINX Users
acme.sh --issue -d example.com -d www.example.com --nginx --keylength ec-256 --ecc --cert-file /etc/ssl/nginx/letsencrypt.ecc.pem --key-file /etc/ssl/nginx/mydomain.ecc.key --fullchain-file /etc/ssl/nginx/mydomain.ecc.pem --reloadcmd "systemctl reload nginx"

Command for Apache2 Users
acme.sh --issue -d example.com -d www.example.com --apache --keylength ec-256 --ecc --cert-file /etc/ssl/apache2/letsencrypt.ecc.pem --key-file /etc/ssl/apache2/mydomain.ecc.key --fullchain-file /etc/ssl/apache2/mydomain.ecc.pem --reloadcmd "systemctl reload apache2"

You can add the --ocsp-must-staple flag to enable the OCSP Must-Staple extension on a certificate. However, Let’s Encrypt has announced the end of OCSP (Online Certificate Status Protocol) support, so if you rely on OCSP, keep up-to-date with Let’s Encrypt’s latest announcements regarding this feature.

Note: OCSP provides real-time information about a certificate’s revocation status. It has security features, such as nonce values and digital signatures, to prevent forgery and replay attacks.

Automatic DNS API Integration

If your DNS provider supports API access, acme.sh can use it to automatically issue certificates. acme.sh supports Cloudflare and many other domain providers. Since Cloudflare is one of the most widely used DNS providers, we’ll use it to issue a global certificate for a domain. Using a wildcard certificate is more efficient than issuing separate certificates for multiple subdomains. You can read our post on configuring Cloudflare to set it as your domain provider.

# Add Cloudflare global API key to environment variables
export CF_Key="763eac4f1bcebd8b5c95e9fc50d010b4"

# Command to issue a wildcard certificate for the NGINX server
acme.sh --issue -d diversifyindia.in -d '*.diversifyindia.in' --dns dns_cf --keylength ec-256 --ecc --cert-file /etc/ssl/nginx/letsencrypt.ecc.pem --key-file /etc/ssl/nginx/mydomain.ecc.key --fullchain-file /etc/ssl/nginx/mydomain.ecc.pem --reloadcmd "systemctl reload nginx"

# Command to issue a wildcard certificate for the Apache server
acme.sh --issue -d diversifyindia.in -d '*.diversifyindia.in' --dns dns_cf --keylength ec-256 --ecc --cert-file /etc/ssl/apache2/letsencrypt.ecc.pem --key-file /etc/ssl/apache2/mydomain.ecc.key --fullchain-file /etc/ssl/apache2/mydomain.ecc.pem --reloadcmd "systemctl reload apache2"

Adding a Cron Job

After successfully installing SSL certificates, it’s essential to add a cron job to automatically renew your certificates before they expire. Let’s Encrypt certificates expire every 90 days, so regular renewal is necessary. Use the following acme.sh command to set up a cron job for automatic renewal:

acme.sh --install-cronjob

Note: You can inspect and modify your cron job if necessary to ensure that the renewal happens as expected. If your system’s cron setup differs, make sure to adjust accordingly.

acme.sh Parameters

Below is a brief description of each command-line argument used with acme.sh:

  • --issue: Requests a new SSL certificate.
  • -d example.com: Specifies the primary domain for the certificate (in this case, example.com).
  • -d www.example.com: Adds an additional domain or subdomain to the certificate (in this case, www.example.com).
  • -d '*.example.com': Issues a wildcard certificate, which is valid for all subdomains of example.com (e.g., www.example.com, blog.example.com, etc.).
  • --nginx/--apache: Specifies the web server in use, either NGINX or Apache.
  • --keylength ec-256: Sets the encryption strength and type for the private key. ec-256 uses Elliptic Curve Cryptography (ECC) with a 256-bit key.
  • --ecc: Instructs acme.sh to use Elliptic Curve Cryptography (ECC) for the certificate instead of RSA, which is generally more secure and efficient.
  • --cert-file, --key-file, --fullchain-file: Defines the directories where the trusted CA certificates, private key, and full certificate chain will be saved.
  • --reloadcmd: Specifies a command to reload the web server configuration after installing the new certificate.
  • --dns dns_cf: Uses the DNS-01 challenge method with Cloudflare’s DNS service (dns_cf). This method involves creating a DNS record to verify domain ownership, which requires Cloudflare API credentials.

Configure Apache2 to Enable SSL/TLS Support

If you are using an Apache server, add the following VirtualHost directive to your site’s configuration file, pointing to the location of the installed SSL certificates.

# Serve website on port 443
<VirtualHost *:443>
    ServerName www.example.com
    ServerAlias example.com
    DocumentRoot /var/www/html/wordpress

    <IfModule dir_module>
        DirectoryIndex index.php index.html
    </IfModule>

    # Enable SSL engine
    SSLEngine on
    SSLCertificateFile /etc/ssl/apache2/mydomain.ecc.pem
    SSLCertificateKeyFile /etc/ssl/apache2/mydomain.ecc.key

    # Use HTTP/2 protocol
    Protocols h2 http/1.1
</VirtualHost>

# Disable insecure SSL versions
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

# Use strong and efficient ciphers
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder     off
SSLSessionTickets       off

# Uncomment the following if your certificate supports OCSP stapling
# SSLUseStapling On
# SSLStaplingCache "shmcb:/run/apache2/ssl_stapling(32768)"

This SSL configuration is designed to enhance the security and performance of your Apache server. It enables the latest HTTP/2 protocol, which is more efficient, and disables older, insecure encryption protocols while using strong cipher suites.

Note: Make sure that the mod_ssl module is installed and enabled. On most Debian-based distributions, it is enabled by default. If it is not, you can enable it by running the following command:

sudo a2enmod ssl

Configure NGINX to Enable SSL/TLS Support

If you are using an NGINX server, add the following server block to your site’s configuration file. This will enable SSL/TLS encryption for your WordPress website.

server {
    # Listen on port 443 for IPv4 and IPv6 connections
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # Define your domain name
    server_name    www.example.com example.com;
    # Set the root directory for your WordPress site
    root           /var/www/html/wordpress;

    # Specify the index files to be used
    index          index.php index.html;

    # ECDSA certificates
    ssl_certificate /etc/ssl/nginx/mydomain.ecc.pem;
    ssl_certificate_key /etc/ssl/nginx/mydomain.ecc.key;
    ssl_trusted_certificate /etc/ssl/nginx/letsencrypt.ecc.pem;

    # Use strong ciphers
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_buffer_size 8k;

    # Uncomment the following if your certificate supports OCSP stapling
    # ssl_stapling on;
    # ssl_stapling_verify on;

    # Handle PHP files
    location ~ \.php$ {
        include                 fastcgi.conf;
        fastcgi_pass            php_fpm82;
    }

    # Use try_files to handle requests and execute PHP files if needed
    location / {
        try_files         $uri $uri/ /index.php?$args;
    }
}

Conclusion

In this guide, we walked through the step-by-step process to install SSL certificate for websites on Apache and NGINX servers. Enabling SSL/TLS encryption secures the client-server connection and reduces the attack surface. The configurations provided were tested on Linux systems and should work on most setups with only minor adjustments. This is how you can get an SSL certificate for your domain.

You can secure your locally hosted website by checking out our guide on obtaining an SSL certificate for localhost.

Frequently Asked Questions

In which year Google made https compulsory?

Google made HTTPS compulsory for websites in 2018. The company began marking sites that were not using HTTPS as “Not Secure” in the Chrome browser, starting with version 68, which was released in July 2018.

This change was part of Google’s larger effort to encourage HTTPS adoption, which improves security by encrypting data between the user’s browser and the website’s server. Additionally, Google has prioritized secure sites in search rankings, further incentivizing websites to adopt HTTPS.

How to Get Your Cloudflare Global API Key?

Follow these steps to obtain your Cloudflare global API key:

  1. Log in to your Cloudflare account.
  2. Select your website from the Cloudflare dashboard.
  3. In the “Overview” section, scroll down and click the Get your API token link.
  4. In the “API Keys” section, click the View button next to the Global API Key.
  5. Finally, enter your Cloudflare account password to retrieve your key.

What is the full form of ACME?

ACME stands for Automatic Certificate Management Environment. It is a protocol used to automate the process of managing and issuing SSL/TLS certificates. The ACME protocol allows users to interact with a Certificate Authority (CA) like Let’s Encrypt to request, renew, and manage certificates without manual intervention.