Official Power Up Hosting Blog

Everything about Linux, Windows, and hosting ;)

Selvakumar
Author

I am an Online Marketer and technology lover. I like to learn new things and share that with people.

Share


Our Newsletter


Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Tags


Twitter


Official Power Up Hosting Blog

How To Secure (Certbot) HAProxy with Let's Encrypt on CentOS 7

SelvakumarSelvakumar

Introduction

Anyone who has the site also needs the SSL certificate. Improving the security is one of the important things.

If you don't use SSL, then there is a big chance for the attacker to easily hack. It is like just closing the door and not locking it.

Anyone can easily enter the room. So, it is always necessary to put a lock. Here, the lock for your server can be a very Good SSL.

There are a lot of free SSL service provider out there in the market.

But:

Let's Encrypt is the best one among them and it is recommended by most of the people.

Let's Encrypt SSL is free and you can obtain the certificate through requesting the Let's Encrypt API.

Configuring an SSL in a server is a complicated task. Configuring the SSL with a web server requires some deep knowledge.

However:

The Let's encrypt has a client called Certbot. This Certbot will help you in obtaining the SSL certificate by automating the most of the task.

Let us see the requirement here.

Prerequisites

  • You should have configured the CentOS 7 operating system on your server according to this CentOS initial server setup guide.

  • You should have a domain name registered and pointing to your server.

  • You should configure your domain name to directly point your server. Don't use any CDN. Add your server providers name server details in the domain name service provider control panel.

Once you are done with all these steps, then the next step is installing the Certbot client.

Install the Certbot

You have to install the Certbot software to obtain the SSL. The first thing you have to do is enabling the access to the EPEL repository.

To enable access to the EPL repository, use the below command.

$ sudo yum install epel-release

After installing the repository, you have to install the certbot. Use the below command to install the Certbot.

$ sudo yum install certbot

After that, you can use the Certbot.

Obtaining a Certificate

There are a lot of ways to obtain an SSL certificate from Let's encrypt.

Many plugins are available to obtain SSL certificate from Let's Encrypt.

You have to configure them to be used by the web servers. The Plugins only obtain the SSL certificate and don't install them on the servers are called authenticators.

They are named authenticators as they are only used to validate and authenticate whether a server can be given the SSL certificate.

Here, in this tutorial, we are going to use the Standalone plugin for our Job.

Verify the port 80

This standalone plugin will use the port 80 by running a small web server on your server so that the Let's Encrypt CA can establish the connection with the server to validate it.

Here:

Your normal web server might be running on port 80. So, you have to make sure that the normal web server has been stopped using that port.

In case you are using the HAproxy, you can use the below command to stop haproxy.

$ sudo systemctl stop haproxy

If you want to make sure that the port 80 is not used by any other service, just use the below command.

$ netstat -na | grep ':80.*LISTEN'

If you do not receive any output, then you can use the Standalone plugin.

Start Running the Certbot

Execute the below command to obtain the certificate.

$ sudo certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d example.com -d www.example.com

Now:

You will be asked to enter your email address and agree to the terms and service of Let's Encrypt.

The HTTP challenge will run and if everything is ok, then you will get the following output.

Output:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your cert
will expire on 2017-09-06. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. 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

You have to note the path and expiration date of the certificate.

Files in the Certificate Explained

cert.pem: This is the certificate for your domain

chain.pem: This is the Let's Encrypt chain certificate

fullchain.pem: It is the combination of cert.pem and chain.pem.

privkey.pem: This is the private key of your certificate.

You should know the location of the certificates to use them in the web server configuration.

The files will be stored in the location /etc/letsencrypt/archive by default.

But:

The certbot will store the latest files in the /etc/letsencrypt/live/your_domain_name location.

To see whether the file is existing, use the below command.

$ sudo ls /etc/letsencrypt/live/your_domain_name

Combining the fullchain.pem and privkey.pem

You have to combine both fullchain.pem and privkey.pem in order to make the HAproxy perform the SSL termination.

To combine them, first create a folder where you will store the combined file.

Create the directory at /etc/haproxy/certs

$ sudo mkdir -p /etc/haproxy/certs

You have to create a combined file using the cat command.

$ DOMAIN='example.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'

Now, you have to restrict the access to the combined file as it has the private key.

Use below command for that.

$ sudo chmod -R go-rwx /etc/haproxy/certs

Now, you can use the SSL cert and private key

Installing the HAproxy

If you don't have the HAproxy installed on your server, then follow this step. HAproxy can be installed using the below command.

$ sudo yum install haproxy

Now you have installed the HAproxy but you have to configure it.

Configuring the HAproxy

Here, you are going to see how to configure the HAproxy with the SSL. We will also see, How to setup the auto-renew for the HAproxy.

First, open the HAproxy configuration file using an editor.

$ sudo vi /etc/haproxy/haproxy.cfg

Don't close this file as we need to edit it many times.

Change in Global Section

You have to add the following line in the global section to allocate the maximum amount of memory for the DHE key.

           haproxy.cfg — 1 of 5

tune.ssl.default-dh-param 2048

The Front End Section.

Here, you have to configure the front end of the HA proxy.

The HAproxy configuration has a single front end and multiple backends.

The main function of the HAproxy is to handle the incoming http connection and forwarding it to the backend.

Here, make sure to add the HAproxy server IP address in haproxy_public_IP.

             haproxy.cfg — 2 of 5
frontend www-http
bind haproxy_www_public_IP:80
reqadd X-Forwarded-Proto:\ http
default_backend www-backend

In this step, we will be adding the front end to handle the incoming https traffic.

Here, replace the haproxy_www_public_IP with HAproxy server public IP address.

Additionally, you have to replace example.com with your domain name.

            haproxy.cfg — 3 of 5
frontend www-https
bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem
reqadd X-Forwarded-Proto:\ https
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
default_backend www-backend

ACL(letsencrypt-acl) is used by the frontend to send the Let's Encryption validation requests(/.well-known/acme-challenge) to the backend. It will allow us to renew the certificate without stopping the HAproxy service.

The requests coming to the front end will be forwarded to the www-backend.

The back-end will serve our web application requests.

Backend Sections

Once you are done with the front end, add the following lines to add the www-backend.

Here, I have highlighted the words. You have to replace all of them with corresponding private IP address.

        haproxy.cfg — 4 of 5
backend www-backend
redirect scheme https if !{ ssl_fc }
server www-1 www_1_private_IP:80 check
server www-2 www_2_private_IP:80 check

All the traffic received by this backend will be balanced by the HTTP (Port 80).

At last, add the Let's Encrypt back-end, by adding the below line.

       haproxy.cfg — 5 of 5
 backend letsencrypt-backend
 server letsencrypt 127.0.0.1:54321

This backend only handles the Let's Encrypt ACME challenges. This is used for the certificate request to the Let's Encrypt and certificate renewal.

It sends the traffic to the port 54321.

We won't use the port 80 and port 443 to renew the SSL certificate. Instead, we will use port 54321 for this renewal purpose.

Now, you can start the HAproxy using the below command.

$ sudo systemctl start haproxy

Now, you got the SSL/TLS certificate in place. You have to check whether the SSL is working by visiting your domain.

Setting Up the Auto Renewal

All the Let's Encrypt SSL certificates are valid for ninety days. After that, you have to renew it.

Each time you can't check for the renewal. So, the best way is to create a Cron job to automate the renewal process.

The Certbot will run the Cron job daily to check the expiry date of the SSL certificate. If any certificate has 30 days time to expire, then that will be renewed.

The Certbot will also run the renew-hook script. This script will update the combined .pem file and reloads the HAproxy.

Renewal Script Creation

Now, Open a file at the /usr/local/bin as the root user.

$ sudo vi /usr/local/bin/renew.sh

You will get an empty text file. just copy and paste the below script there and also make sure to replace the highlighted area with your domain name.

#!/bin/sh

SITE=example.com

# move to the correct let's encrypt directory
cd /etc/letsencrypt/live/$SITE

# cat files to make combined .pem for haproxy
cat fullchain.pem privkey.pem > 
/etc/haproxy/certs/$SITE.pem

# reload haproxy
systemctl reload haproxy

After that, save and close the file. This script will combine the two .pem file and reloads the HAproxy.

Then, make the script into executable one.

$ sudo chmod u+x /usr/local/bin/renew.sh

After that, run the script.

$ sudo /usr/local/bin/renew.sh

The script should run without any error. The next task is updating the certbot and then make it run the renewal script.

Update the Certbot Configuration

We will run the certbot renew command to update our certificates.

When you execute this command, it will read the configuration which was created when you ran the certbot for the first time.

We have to open the configuration file and update the port number.

The Cerbot will be listening to port 80 and 443. Update the port number.

First, open the configuration file.

$ sudo vi /etc/letsencrypt/renewal/example.com.conf

Look for the http01_port line and update the port number to 54321.

                    example.com.conf
http01_port = 54321

After that, save and close the file. Then test the renewal process using the --dry-run command.

$ sudo certbot renew --dry-run

Now, the certbot will listen to 54321. The HAproxy will forward the request from port 80 to port 54321.

Cron Job Creation

You have to edit the crontab to make it run the cerbot renew command every day.

Use the below command to edit the cron tab as the root user.

$ sudo crontab -e

Add the below line in that file.

 crontab entry
45 3 * * * /usr/bin/certbot renew --renew-hook "/usr/local/bin/renew.sh" >> /var/log/le-renewal.log

After that, save and exit.

This will make the cerbot renew command to run everyday at 3:45. The output of this command will go to /var/log/le-renewal.log.

If the certificate is renewed, the renew_hook will create the combined.pem file and reload the HAproxy.

Conclusion

In this tutorial, you have learned how to Secure the HAproxy with Let's Encrypt on CentOS.

If you have any doubt, leave them in the comment. We will help you to solve it.

Also, don't forget to signup to receive alert for our next tutorial.

Selvakumar
Author

Selvakumar

I am an Online Marketer and technology lover. I like to learn new things and share that with people.

Comments