{"id":387,"date":"2019-06-10T17:19:04","date_gmt":"2019-06-10T17:19:04","guid":{"rendered":"https:\/\/blog.iabsolute.com\/?p=387"},"modified":"2019-06-10T17:19:04","modified_gmt":"2019-06-11T00:19:04","slug":"how-to-secure-apache-with-lets-encrypt-on-centos-7","status":"publish","type":"post","link":"https:\/\/blog.iabsolute.com\/?p=387","title":{"rendered":"How To Secure Apache with Let&#8217;s Encrypt on CentOS 7"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"step-1-\u2014-installing-the-certbot-let-39-s-encrypt-client\">Step 1 \u2014 Installing the Certbot Let&#8217;s Encrypt Client<\/h2>\n\n\n\n<p>To use Let&#8217;s Encrypt to obtain an SSL certificate, you first need to install Certbot and <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_ssl.html\"><code>mod_ssl<\/code><\/a>, an Apache module that provides support for SSL v3 encryption.<\/p>\n\n\n\n<p>The <code>certbot<\/code> package is not available through the package manager by default. You will need to enable the <a href=\"https:\/\/fedoraproject.org\/wiki\/EPEL\">EPEL<\/a> repository to install Certbot.<\/p>\n\n\n\n<p>To add the CentOS 7 EPEL repository, run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo yum install epel-release\n<\/code><\/pre>\n\n\n\n<p>Now that you have access to the repository, install all of the required packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo yum install certbot python2-certbot-apache mod_ssl\n<\/code><\/pre>\n\n\n\n<p>During the installation process you will be asked about importing a GPG key. This key will verify the authenticity of the package you are installing. To allow the installation to finish, accept the GPG key by typing <code>y<\/code> and pressing <code>ENTER<\/code> when prompted to do so.<\/p>\n\n\n\n<p>With these services installed, you&#8217;re now ready to run Certbot and fetch your certificates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-2-\u2014-obtaining-a-certificate\">Step 2 \u2014 Obtaining a Certificate<\/h2>\n\n\n\n<p>Now that Certbot is installed, you can use it to request an SSL certificate for your domain.<\/p>\n\n\n\n<p>Using the <code>certbot<\/code> Let\u2019s Encrypt client to generate the SSL Certificate for Apache automates many of the steps in the process. The client will automatically obtain and install a new SSL certificate that is valid for the domains you provide as parameters.<\/p>\n\n\n\n<p>To execute the interactive installation and obtain a certificate that covers only a single domain, run the <code>certbot<\/code> command with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot --apache -d example.com\n<\/code><\/pre>\n\n\n\n<p>This runs <code>certbot<\/code> with the <code>--apache<\/code> plugin and specifies the domain to configure the certificate for with the <code>-d<\/code> flag.<\/p>\n\n\n\n<p>If you want to install a single certificate that is valid for multiple domains or subdomains, you can pass them as additional parameters to the command, tagging each new domain or subdomain with the <code>-d<\/code> flag. The first domain name in the list of parameters will be the <strong>base<\/strong> domain used by Let\u2019s Encrypt to create the certificate. For this reason, pass the base domain name as first in the list, followed by any additional subdomains or aliases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot --apache -d example.com -d www.example.com\n<\/code><\/pre>\n\n\n\n<p>The base domain in this example is <code>example.com<\/code>. <\/p>\n\n\n\n<p>The <code>certbot<\/code> utility can also prompt you for domain information during the certificate request procedure. To use this functionality, call <code>certbot<\/code> without any domains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot --apache\n<\/code><\/pre>\n\n\n\n<p>The program will present you with a step-by-step guide to customize your certificate options. It will ask you to provide an email address for lost key recovery and notices, and then prompt you to agree to the terms of service. If you did not specify your domains on the command line, you will be prompted for that as well. If your Virtual Host files do not specify the domain they serve explicitly using the <code>ServerName<\/code> directive, you will be asked to choose the virtual host file. In most cases, the default <code>ssl.conf<\/code> file will work.<\/p>\n\n\n\n<p>You will also be able to choose between enabling both <code>http<\/code> and <code>https<\/code> access or forcing all requests to redirect to <code>https<\/code>. For better security, it is recommended to choose the option <code>2: Redirect<\/code> if you do not have any special need to allow unencrypted connections. Select your choice then hit <code>ENTER<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OutputPlease choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n1: No redirect - Make no further changes to the webserver configuration.\n2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for\nnew sites, or if you're confident your site works on HTTPS. You can undo this\nchange by editing your web server's configuration.\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nSelect the appropriate number [1-2] then [enter] (press 'c' to cancel):2\n<\/code><\/pre>\n\n\n\n<p>When the installation is successfully finished, you will see a message similar to this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OutputIMPORTANT NOTES:\n - Congratulations! Your certificate and chain have been saved at:\n   \/etc\/letsencrypt\/live\/example.com\/fullchain.pem\n   Your key file has been saved at:\n   \/etc\/letsencrypt\/live\/example.com\/privkey.pem\n   Your cert will expire on 2019-08-14. To obtain a new or tweaked\n   version of this certificate in the future, simply run certbot again\n   with the \"certonly\" option. To non-interactively renew *all* of\n   your certificates, run \"certbot renew\"\n - If you like Certbot, please consider supporting our work by:\n\n   Donating to ISRG \/ Let's Encrypt:   https:\/\/letsencrypt.org\/donate\n   Donating to EFF:                    https:\/\/eff.org\/donate-le\n\n<\/code><\/pre>\n\n\n\n<p>The generated certificate files will be available within a subdirectory named after your base domain in the <code>\/etc\/letsencrypt\/live<\/code> directory.<\/p>\n\n\n\n<p>Now that your certificates are downloaded, installed, and loaded, you can check your SSL certificate status to make sure that everything is working.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-3-\u2014-checking-your-certificate-status\">Step 3 \u2014 Checking your Certificate Status<\/h2>\n\n\n\n<p>At this point, you can ensure that Certbot created your SSL certificate correctly by using the <a href=\"https:\/\/www.ssllabs.com\/ssltest\/\">SSL Server Test<\/a> from the cloud security company <a href=\"https:\/\/www.qualys.com\/\">Qualys<\/a>.<\/p>\n\n\n\n<p>Open the following link in your preferred web browser, replacing <code>example.com<\/code> with your <strong>base<\/strong> domain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:\/\/www.ssllabs.com\/ssltest\/analyze.html?d=example.com\n<\/code><\/pre>\n\n\n\n<p>You will land on a page that immediately begins testing the SSL connection to your server:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/LE_CentOS7_66505\/SSL_Server_Test.png\" alt=\"SSL Server Test\"\/><\/figure>\n\n\n\n<p>Once the test starts running, it may take a few minutes to complete. The status of the test will update in your browser.<\/p>\n\n\n\n<p>When the testing finishes, the page will display a letter grade that rates the security and quality of your server&#8217;s configuration. At the time of this writing, default settings will give an <strong>A<\/strong> rating:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/LE_CentOS7_66505\/SSL_Report_A.png\" alt=\"SSL Report - A\"\/><\/figure>\n\n\n\n<p>For more information about how SSL Labs determines these grades, check out the <a href=\"https:\/\/community.qualys.com\/docs\/DOC-6321-ssl-labs-grading-2018\">SSL Labs Grading post<\/a> detailing the updates made to the grading scheme in January, 2018.<\/p>\n\n\n\n<p>Try reloading your website using <code>https:\/\/<\/code> and notice your browser&#8217;s security indicator. It will now indicate that the site is properly secured, usually with a green lock icon.<\/p>\n\n\n\n<p>With your SSL certificate up and verified, the next step is to set up auto-renewal for your certificate to keep your certificate valid.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-4-\u2014-setting-up-auto-renewal\">Step 4 \u2014 Setting Up Auto Renewal<\/h2>\n\n\n\n<p>Let\u2019s Encrypt certificates are valid for 90 days, but it\u2019s recommended that you renew the certificates every 60 days to allow a margin of error. Because of this, it is a best practice to automate this process to periodically check and renew the certificate.<\/p>\n\n\n\n<p>First, let&#8217;s examine the command that you will use to renew the certificate. The <code>certbot<\/code> Let&#8217;s Encrypt client has a <code>renew<\/code> command that automatically checks the currently installed certificates and tries to renew them if they are less than 30 days away from the expiration date. By using the <code>--dry-run<\/code> option, you can run a simulation of this task to test how <code>renew<\/code> works:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot renew --dry-run\n<\/code><\/pre>\n\n\n\n<p>The output should look similar to this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OutputSaving debug log to \/var\/log\/letsencrypt\/letsencrypt.log\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nProcessing \/etc\/letsencrypt\/renewal\/example.com.conf\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nCert not due for renewal, but simulating renewal for dry run\nPlugins selected: Authenticator apache, Installer apache\nStarting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org\nRenewing an existing certificate\nPerforming the following challenges:\nhttp-01 challenge for example.com\nhttp-01 challenge for www.example.com\nWaiting for verification...\nCleaning up challenges\nResetting dropped connection: acme-staging-v02.api.letsencrypt.org\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nnew certificate deployed with reload of apache server; fullchain is\n\/etc\/letsencrypt\/live\/example.com\/fullchain.pem\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n** DRY RUN: simulating 'certbot renew' close to cert expiry\n**          (The test certificates below have not been saved.)\n\nCongratulations, all renewals succeeded. The following certs have been renewed:\n  \/etc\/letsencrypt\/live\/example.com\/fullchain.pem (success)\n...\n<\/code><\/pre>\n\n\n\n<p>Notice that if you created a bundled certificate with multiple domains, only the base domain name will be shown in the output, but the renewal will be valid for all domains included in this certificate.<\/p>\n\n\n\n<p>A practical way to ensure your certificates will not get outdated is to create a <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-use-cron-to-automate-tasks-on-a-vps\">cron job<\/a> that will periodically execute the automatic renewal command for you. Since the renewal first checks for the expiration date and only executes the renewal if the certificate is less than 30 days away from expiration, it is safe to create a cron job that runs every week or even every day.<\/p>\n\n\n\n<p>The <a href=\"https:\/\/certbot.eff.org\/lets-encrypt\/centosrhel7-apache\">official Certbot documentation<\/a> recommends running <code>cron<\/code> twice per day. This will ensure that, in case Let&#8217;s Encrypt initiates a certificate revocation, there will be no more than half a day before Certbot renews your certificate.<\/p>\n\n\n\n<p>Edit the <code>crontab<\/code> to create a new job that will run the renewal twice per day. To edit the <code>crontab<\/code> for the <strong>root<\/strong> user, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo crontab -e\n<\/code><\/pre>\n\n\n\n<p>Your text editor will open the default <code>crontab<\/code> which is an empty text file at this point. This tutorial will use the vi text editor. To learn more about this text editor and its successor <em>vim<\/em>, check out our <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/installing-and-using-the-vim-text-editor-on-a-cloud-server#managing-documents\">Installing and Using the Vim Text Editor on a Cloud Server<\/a> tutorial.<\/p>\n\n\n\n<p>Enter insert mode by pressing <code>i<\/code> and add in the following line:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>crontab0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' &amp;&amp; certbot renew\n<\/code><\/pre>\n\n\n\n<p>When you&#8217;re finished, press <code>ESC<\/code> to leave insert mode, then <code>:wq<\/code> and <code>ENTER<\/code> to save and exit the file. This will create a new cron job that will execute at noon and midnight every day. Adding an element of randomness to your cron jobs will ensure that hourly jobs do not all happen at the same minute, causing a server spike; <code>python -c 'import random; import time; time.sleep(random.random() * 3600)'<\/code> will select a random minute within the hour for your renewal tasks.<\/p>\n\n\n\n<p>For more information on how to create and schedule cron jobs, you can check our <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-use-cron-to-automate-tasks-on-a-vps\">How to Use Cron to Automate Tasks in a VPS<\/a> guide. More detailed information about renewal can be found in the <a href=\"https:\/\/certbot.eff.org\/docs\/using.html#renewal\">Certbot documentation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Step 1 \u2014 Installing the Certbot Let&#8217;s Encrypt Client To use Let&#8217;s Encrypt to obtain an SSL certificate, you first need to install Certbot and mod_ssl, an Apache module that provides support for SSL v3 encryption. The certbot package is &hellip; <a href=\"https:\/\/blog.iabsolute.com\/?p=387\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,26,2,21],"tags":[],"class_list":["post-387","post","type-post","status-publish","format-standard","hentry","category-apache","category-lets-encrypted","category-my-linux","category-ssl"],"_links":{"self":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=387"}],"version-history":[{"count":1,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/387\/revisions"}],"predecessor-version":[{"id":388,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/387\/revisions\/388"}],"wp:attachment":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}