Recently we switched over to HTTPS (secure channel) on our website bwdmedia.net and we had trouble finding support for our server which was CentOS 6 running Apache. This will be a short guide if you’re looking to get an ssl certificate for your website and want to know how to install it on your server. Best of all, it’s completely free and just as secure as any other domain validated certificate you can buy commercially.
The service I’ll be using is Let’s Encrypt which went out of beta this year. Let’s Encrypt is an open certificate authority that can issue SSL certificates for your domain automatically and for free. The public service organization was founded by two Mozilla employees Josh Aas and Eric Rescorla
Enough said about history and introductions, let’s dive right into it.
Getting In There
To start with, you need root access to your server which is done through SSH. If you don’t know what it is, I suggest you get familiar with it first. It’s a command line interface (CLI) for interacting with your server remotely. Getting root access depends greatly on your hosting provider so consult them if you’re having trouble.
After you’ve logged in, let’s get the certbot package. I assume you’re using CentOS/RHEL and Apache. If you don’t know which version you’re using, execute the following command and read the output
If you have CentOS/RHEL 7, scroll below to see the easy method of doing it. If it doesn’t work or If you have CentOS/RHEL 6, certbot as of right now doesn’t have an automated script so certificate issuance will have to be done manually. Here’s how…
- Enable the EPEL (Extra Packages for Enterprise Linux) repository
$ sudo yum install epel-release
- Get the package
wget https://dl.eff.org/certbot-auto chmod a+x certbot-auto
- Certbot is installed, time to issue a certificate. While still in root, run
./certbot-auto certonly --webroot -w [location of public_html] -d [domain of that location] -m [email]
Let me explain:
- ./certbot-auto: invokes the certbot script
- certonly: instructs the script to only issue the certficate since automation tasks are not supported on this OS
- –webroot: We’re using the webroot method which doesn’t disable the server while issuing the certificate. It will place a file in your public_html and ca will try to access it. If it happens, you’ll be verified. If it doesn’t work try using the standalone (–standalone) method. This method will bind to Port 80 (http) and Port 443 (https) so your websites on the server will not respond while you’re issuing the certificate. Refer to Documentation for more details.
- -w: this modifier points to the relative location of your public_html folder where the files of the website reside for which you are issuing the certificate. For me it was
- -d: this modifier tells the script which domains to include in the certificate. Those domains will be authorized to use this particular certificate.
- -m: this modifier is used to input the email address which will be used to contact you for several reasons, if your certificates are about to expire for instance.
Do note that the arguments -w and -d can be used multiple times in a command to issue a certificate for multiple domains, for example
./certbot-auto certonly --webroot -w /home/user/public_html/ -d example.com -d www.example.com -w /home/user2/public_html/ -d example2.com -d www.example2.com
You can omit the -m argument and certbot will ask you for it later.
- Certbot will present a blue screen and ask you to agree to terms of service and any other information which will be required and not included in the command executed above.
- Next you should receive a success message similar to this
Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem. Your cert will expire on 2016–10–01. To obtain a new version of the certificate in the future, simply run Let’s Encrypt again.
- Your certificate is now issued. To install it though, you’ll have to execute another step, that is to configure your server to redirect http traffic to https and appropriate configuration for https.
Head over to the location of your httpd.conf file which is the main configuration file of apache. For my server, it was located at
- Open the file
and navigate to the VirtualHost container of your domain. It’ll look something similar to this
<VirtualHost 184.108.40.206:80> ... ServerName example.com ServerAlias www.example.com ... </VirtualHost>
You’re not supposed to modify this file directly because the changes will be overwritten by Apache sooner or later. To modify this container, there should be an include file at the end
which means it’ll include any
.conffile in the specified directory. Head over to that directory, if there’s a file there open it, else create one with any name. To create a new file in SSH, use
Add the following lines to redirect all http traffic to https
ServerName example.com ServerAlias www.example.com Redirect 301 "/" "https://www.example.com/"
This code will override anything in the
httpd.conffile so you don’t have to worry about what’s in that file
- Configure your server for https traffic.
httpd.confhas two other global files that are included at the very top and bottom of the file and are called
post_virtualhost_global.conf. Names may vary so read your own
httpd.conffile. Once you’ve located your include file (preferably in the post file, i.e. the file included towards the end of
httpd.conffile) add the following code
<VirtualHost 220.127.116.11:443> ServerName example.com ServerAlias www.example.com DocumentRoot /home/user/public_html SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem# HSTS (mod_headers is required) (15768000 seconds = 6 months) # HSTS (mod_headers is required) (15768000 seconds = 6 months) # Header always set Strict-Transport-Security "max-age=15768000; includeSubdomains;" SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES2$ SSLHonorCipherOrder on ... </VirtualHost>
Let’s see what we did there:
- <VirtualHost 18.104.22.168:443>: this is the ip address you originally had, you need to input that. 443 is the default port for communicating over https so this container takes effect when your website is accessed over https
- These next lines are self explanatory, the domains that will be used to access your site goes here and
DocumentRootspecifies where on the server the files of this domain are.
ServerName example.com ServerAlias www.example.com DocumentRoot /home/user/public_html
- Turn SSL on:
SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
It turns the
SSLEngineon and ready to use, next directives specify the location of your certificate files which were generated in Step 3 through 5. You have to specify a certificate file, a key file and a chain file which should all be in
Note: certbot generates two kinds of chain file:
fullchain.pem. The difference is that
fullchain.pemis the combination of certificate and chain file in one. Use the above method if your apache is 2.4 or older and if it’s 2.4 or newer, you can instead use
SSLEngine on SSLCertificateChainFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
To find out which version of Apache you’re using, execute
# Header always set Strict-Transport-Security "max-age=15768000; includeSubdomains;"
This line denoted by a hashtag in front is a comment which means it won’t have any effect. This is to enable HSTS (HTTP Strict Transfer Protocol). If you enable this header, your website will not work with http for the next 6 months. This is like a commitment to https. I suggest you have https up and running and remove the hashtag (enable directive) when you’re sure you’ll stick with it.
- Configure Cipher Suites:
SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES2$ SSLHonorCipherOrder on
Next, you define the protocols that will be used for communication with the website. These protocols will determine which and how many browsers and operating systems will be able to access your website. If a browser doesn’t find a supported Cipher in this list, it’ll reject communication and you get a handshake failure.
- So when I said ‘add the following code’ in step 8, I don’t mean copy and paste it directly. What you should do is copy your VirtualHost container for the http version and add the https parts to it. You should keep the directive as close to the original as possible to ensure stability.
- Configurations vary, especially the CipherSuite, which one you use is a major question that occurs to everyone. The above mentioned is the Modern set according to Mozilla and will support only the latest of devices. It won’t support IE8 or older, Android 4.3 or older, etc (see image above). Which one should you choose is based on your preference and audience so I can’t give you a right answer but I can tell you what it means – refer to Mozilla’s Recommended Configuration and Configuration Generator for right results for you.
- Restart your server: After making configuration changes you can save your files and restart the server and changes will take place immediately.
The Automatic Way
If you’re running CentOS/RHEL 7, life’s much easier for you as the fully automatic method is supported for you. Execute the following commands:
$ sudo yum install epel-release $ sudo yum install python-certbot-apache
Certbot is now installed and ready to use, run the command
$ certbot --apache
certbot will ask your for necessary information, issue the certificate and set up your server along with auto renewal cron jobs
After you’re done gloating over what you’ve achieved, take a test to find out if everything works properly. This test will also point out any vulnerabilities on your server, if there are any. To test your configuration go to SSLLabs and enter your domain. You should get something like this
Ain’t that satifisfaction?!
After enabling HSTS, you should get an A+ provided there are no vulnerabilities on the server. As you can see, we haven’t done that yet. It’s coming though!
This has been a lot of information, so take your time to soak it in. In the coming weeks I’ll show you how to manually renew your certificate and set up a cron job to auto renew your certificate when they are about to expire. Let’s Encrypt certificates expires every 3 months so it’s something that’s best automated.