How To Secure Apache With Lets Encrypt on CentOS 7

How To Secure Apache With Let's Encrypt on CentOS 7

Let’s Encrypt is a free and open CA (Certificate Authority) that offers free SSL certificates for TLS encryption, run by Internet Security Research Group, launched in April 2016.

The SSL certificate is valid for 90 days and must be renewed after that. The renewal can take place anytime during 90 days.

Not only they provide free SSL certificate. They made the whole process of securing websites a lot easier by providing Certbot ACME client which takes care of

  1. Creating certificates for your domain.
  2. Updating web server configuration to use the created certificate.
  3. Creating redirection to your https site.
  4. Renewing your installed certificates
Run all commands as the root user.

Prerequisites

Install Apache Web Server

Before proceeding further, you must have Apache Web server on your machine, be it the standalone web server or installed as part of the LAMP stack.

LAMP Stack

READ: How To Install LAMP Stack on CentOS 7

Standalone

Install Apache web server with SSL module package using yum command.

yum install -y httpd mod_ssl
systemctl start httpd
systemctl enable httpd

Configure EPEL Repository

Certbot is available in EPEL repository for CentOS 7. So, set up EPEL repository on to your system by installing its repository configuration rpm.

yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

Install Certbot

Install the certbot client with yum command.

yum install -y certbot python2-certbot-apache

Create Apache Virtual Host

Let’s create a virtual host to host a website for your domain. Virtual hosts will help us host multiple websites on a single Apache web server.

Here, I will share the virtual host configuration file for both the main domain and subdomain. Depending upon your requirement, you can configure Apache web server.

Main Domain (www.example.com)

vi /etc/httpd/conf.d/www.linuxbees.com.conf

Virtual Host Configuration:

<VirtualHost *:80>
       ServerName linuxbees.com
       ServerAlias www.linuxbees.com
       ServerAdmin webmaster@linuxbees.com
       DocumentRoot /var/www/www.linuxbees.com/public_html      

       <Directory /var/www/ww.linuxbees.com/public_html>
             Options -Indexes +FollowSymLinks
             AllowOverride All
      </Directory>

      ErrorLog /var/log/httpd/www.linuxbees.com-error.log
      CustomLog /var/log/httpd/www.linuxbees.com-access.log combined
</VirtualHost>

Sub Domain (sub.example.com)

vi /etc/httpd/conf.d/site.linuxbees.com.conf

Virtual Host Configuration:

<VirtualHost *:80>
       ServerName site.linuxbees.com
       ServerAlias site.linuxbees.com
       ServerAdmin webmaster@linuxbees.com
       DocumentRoot /var/www/site.linuxbees.com/public_html

      <Directory /var/www/site.linuxbees.com/public_html>
             Options -Indexes +FollowSymLinks
             AllowOverride All
      </Directory>

      ErrorLog /var/log/httpd/site.linuxbees.com-error.log
      CustomLog /var/log/httpd/site.linuxbees.com-access.log combined
</VirtualHost>

For this demo, I am going with the subdomain.

Create a document root to place the website files.

mkdir -p /var/www/site.linuxbees.com/public_html

Place a sample HTML file on your document root.

cat <<'EOF' >>  /var/www/site.linuxbees.com/public_html/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Welcome to site.LinuxBees.com</title>
  </head>
  <body>
    <h1>You Have Successfully Configured Apache Virtual Host!!!</h1>
  </body>
</html>
EOF

Restart the Apache web service.

systemctl restart httpd

After you restart the Apache service, check its status.

systemctl status httpd
Output
● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2019-04-02 02:26:38 UTC; 3s ago Docs: man:httpd(8) man:apachectl(8) Process: 3480 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS) Main PID: 3484 (httpd) Status: "Processing requests..." CGroup: /system.slice/httpd.service ├─3484 /usr/sbin/httpd -DFOREGROUND ├─3485 /usr/sbin/httpd -DFOREGROUND ├─3486 /usr/sbin/httpd -DFOREGROUND ├─3487 /usr/sbin/httpd -DFOREGROUND ├─3488 /usr/sbin/httpd -DFOREGROUND └─3489 /usr/sbin/httpd -DFOREGROUND

Apr 02 02:26:38 site.linuxbees.com systemd[1]: Stopped The Apache HTTP Server. Apr 02 02:26:38 site.linuxbees.com systemd[1]: Starting The Apache HTTP Server… Apr 02 02:26:38 site.linuxbees.com systemd[1]: Started The Apache HTTP Server.

Create DNS Entry

Let's Encrypt requires proper DNS record for your domain to set up SSL certificate. So, craete an A Record something like below. The IP Address would be your server's public IP Address.

Secure Apache With Let's Encrypt on CentOS 7 - Create DNS Entry

The above screenshot is from Cloudflare DNS manager. The look and configuration will be different depends on your ISP / Domain register. If you have trouble screating an A record, you can reach to support team of your ISP / Domain register

Verify Virtual Host

Verify the website by going to your domain.

http://site.linuxbees.com

You should get the welcome page.

Secure Apache With Let's Encrypt on CentOS 7 - Website Without SSL Certificate

Create a certificate for your domain

Use the certbot command to create a Let’s Encrypt certificate.

certbot --apache

Follow the interactive prompt and generate and install the certificate.

Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator apache, Installer apache Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): admin@linuxbees.com <== Email Address to receive renewal notices Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory


(A)gree/(C)ancel: A <== Agree Terms Of Service


Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom.


(Y)es/(N)o: Y <== Subscribe for newsletter Starting new HTTPS connection (1): supporters.eff.org


1: site.linuxbees.com


Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter ‘c’ to cancel): 1 <== Choose Domain Name Obtaining a new certificate Performing the following challenges: http-01 challenge for site.linuxbees.com Waiting for verification… Cleaning up challenges Resetting dropped connection: acme-v02.api.letsencrypt.org Created an SSL vhost at /etc/httpd/conf.d/site.linuxbees.com-le-ssl.conf Deploying Certificate to VirtualHost /etc/httpd/conf.d/site.linuxbees.com-le-ssl.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.


1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration.


Select the appropriate number [1-2] then [enter] (press ‘c’ to cancel): 2 <== HTTPS Redirection Redirecting vhost in /etc/httpd/conf.d/site.linuxbees.com.conf to ssl vhost in /etc/httpd/conf.d/site.linuxbees.com-le-ssl.conf


Congratulations! You have successfully enabled https://site.linuxbees.com

You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=site.linuxbees.com


IMPORTANT NOTES:

  • Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/site.linuxbees.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/site.linuxbees.com/privkey.pem Your cert will expire on 2019-07-01. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the “certonly” option. To non-interactively renew all of your certificates, run “certbot renew”

  • Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.

  • If you like Certbot, please consider supporting our work by:

    Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

Verify SSL Certificate

Verify the Let’s Encrypt certificate by visiting HTTPS version of your domain.

http://your-http-web-site

OR

https://your-https-web-site

You should get HTTPS Padlock sign. Also, clicking on the certificate will display the certificate validity details.

Secure Apache With Let's Encrypt on CentOS 7 - Let's Encrypt with Apache

Test your installed SSL certificate for any issues and its security ratings by going to the below URL.

https://www.ssllabs.com/ssltest/analyze.html?d=site.linuxbees.com

Secure Apache With Let's Encrypt on CentOS 7 - SSL Analysis

Renew Let’s Encrypt Certificate

As you aware, Let’s Encrypt certificates have less validity, about 90 days, and it is highly advisable to configure the cron (Linux Scheduler) job to renew your SSL certificates before they expire.

Before you configure a cron job, do the dry run to simulate automatic renewal of your certificate.

certbot renew --dry-run
Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Processing /etc/letsencrypt/renewal/site.linuxbees.com.conf


Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator apache, Installer apache Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org Renewing an existing certificate Performing the following challenges: http-01 challenge for site.linuxbees.com Waiting for verification… Cleaning up challenges Resetting dropped connection: acme-staging-v02.api.letsencrypt.org


new certificate deployed with reload of apache server; fullchain is /etc/letsencrypt/live/site.linuxbees.com/fullchain.pem



** DRY RUN: simulating ‘certbot renew’ close to cert expiry ** (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/site.linuxbees.com/fullchain.pem (success) ** DRY RUN: simulating ‘certbot renew’ close to cert expiry ** (The test certificates above have not been saved.)


IMPORTANT NOTES:

  • Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.

The above output confirms that the renewal is working correctly.

Now, configure a cron job something like below. Let’s Encrypt recommends configuring a cron job to run twice per day.

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew

Conclusion

You have learned how to secure Apache with Let's Encrypt. Please share your comments and feedbacks.

comments powered by Disqus