Setting up LetsEncrypt on a CentOS 7 NginX proxy
-
So I decided to take a shot at setting up Let's Encrpyt on my NginX proxy that runs on CentOS 7. I am not sure how I want to handle the hand off between the proxy and the servers behind yet. Currently all the certificates are manually setup on both after they are generated. But that is for another day..
Important: You must turn off CloudFlare CDN functionality (make the cloud Grey instead of Orange) if you have the SSL features of CloudFlare enabled.
NginX is not fully supported for full automation at this time. That will be rectified soon and these directions will be outdated, but for now.
I started with the core instructions from here and also this [support thread]( yum install python python-devel python-pip python-setuptools python-tools python-virtualenv).
The first thing I noticed if that they tell you to just run the
git
command. Well guess what,git
is not part of CentOS 7 minimal.The EPEL is also required, but I believe their core script checks for that. As I already had the EPEL enabled, it did nothing else. Additionally, there are Python tools missing in the dependency chain.
yum -y install git python-tools python-pip
Now on to the install. I do not want this in my home directory, so i first switched over to /etc.
cd /etc
Then I ran their git command to pull down the code.
git clone https://github.com/letsencrypt/letsencrypt
Change directories, and run the setup script.
cd letsencrypt
./letsencrypt-auto --help
With Let's Encrypt now installed, it is time to generate the certs.
Unfortunately, NginX is not currently (as of Dec 6, 2015) supported for automatic installation, though I am not sure if I will ever use the full automatic install because I rarely have a simple single vHost setup going.The prefered method of install for Let's Encrypt seems to be the
--standalone
plugin over the--webroot
plugin. The webroot solution looks like the better method, but I did not test it.You have to stop NginX because the
--standalone
plugin will stand up its own temp webserver to answer the domain verification challenge.
systemctl stop nginx
Run Let's Encrypt to get the SSL certificates.
Note: The first time you execute Let's Encrypt it will interactively ask you for an email address and also to accept the ToS. You can include that information in the request with
--email [email protected]
and--agree-tos
./letsencrypt-auto certonly --standalone --email [email protected] --agree-tos -d jaredbusch.com -d www.jaredbusch.com
If you ever run this again, even for another domain on the same server, leave the email and ToS acceptance out of the script. Like this.
./letsencrypt-auto certonly --standalone -d jaredbusch.com -d www.jaredbusch.com
Assuming you did everything right, you should see this.
Updating letsencrypt and virtual environment dependencies....... Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --standalone --email [email protected] --agree-tos -d jaredbusch.com -d www.jaredbusch.com IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/jaredbusch.com/fullchain.pem. Your cert will expire on 2016-03-06. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Now start NginX back up because you do not need to keep your website down while you update the vHost files.
systemctl start nginx
You can see in the success message, that it told you where to find the certificate chain. It always save everything in a directory named after the first passed domain to the command. Check out what it does.
ls -l /etc/letsencrypt/live/jaredbusch.com
total 0 lrwxrwxrwx. 1 root root 34 Dec 7 00:29 cert.pem -> ../../archive/jaredbusch.com/cert1.pem lrwxrwxrwx. 1 root root 35 Dec 7 00:29 chain.pem -> ../../archive/jaredbusch.com/chain1.pem lrwxrwxrwx. 1 root root 39 Dec 7 00:29 fullchain.pem -> ../../archive/jaredbusch.com/fullchain1.pem lrwxrwxrwx. 1 root root 37 Dec 7 00:29 privkey.pem -> ../../archive/jaredbusch.com/privkey1.pem
It symlinks everything so when you rerun this in 2 months to renew the certificates, you never have to edit your config files again. The renew process will create new files leaving the old ones in place.
Now you edit your NginX server (vHost) conf files. Mine exist in /etc/nginx/conf.d/
nano /etc/nginx/conf.d/jaredbusch.com.conf
My existing config just used a self signed cert and these two lines.
ssl_certificate /etc/ssl/cacert.pem; ssl_certificate_key /etc/ssl/privkey.pem;
Those need updated to point to the new Let's Encrypt certificates. Additionally, with real certificates, I followed the other guide's suggestion and enabled a couple other SSL options.
ssl_certificate /etc/letsencrypt/live/jaredbusch.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/jaredbusch.com/privkey.pem; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
Save and close nano, then test the nginx config
nginx -t
If it is successful, restart NginX.
systemctl restart nginx
Load your page up and check your certificate.
https://i.imgur.com/wDzpfQF.jpg
https://i.imgur.com/m7SS42N.jpg
https://i.imgur.com/UBrkHyr.jpg -
I ran into an error almost immediately.
./letsencrypt-auto --help
resulted in this.Complete! Creating virtual environment... Updating letsencrypt and virtual environment dependencies...../root/.local/share/letsencrypt/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning. InsecurePlatformWarning ./root/.local/share/letsencrypt/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning. InsecurePlatformWarning .
Searching their website did not turnup anythin specific about this, but I did find a thread about Python 2.7 and Centos 6. Comparing the workaround for that (prior to CentOS 6 being supported again). I noticed that not all the Python pieces that the workaround noted were install on my box,
python-tools
andpython-pip
.I reverted my VM and then added those to the yum install for git. Now Let's Encrypt build correctly.
[root@nginxproxy letsencrypt]# ./letsencrypt-auto --help Updating letsencrypt and virtual environment dependencies....... Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt --help letsencrypt [SUBCOMMAND] [options] [-d domain] [-d domain] ... The Let's Encrypt agent can obtain and install HTTPS/TLS/SSL certificates. By default, it will attempt to use a webserver both for obtaining and installing the cert. Major SUBCOMMANDS are: (default) run Obtain & install a cert in your current webserver certonly Obtain cert, but do not install it (aka "auth") install Install a previously obtained cert in a server revoke Revoke a previously obtained certificate rollback Rollback server configuration changes made during install config_changes Show changes made to server config during installation plugins Display information about installed plugins Choice of server plugins for obtaining and installing cert: --apache Use the Apache plugin for authentication & installation --standalone Run a standalone webserver for authentication (nginx support is experimental, buggy, and not installed by default) --webroot Place files in a server's webroot folder for authentication OR use different plugins to obtain (authenticate) the cert and then install it: --authenticator standalone --installer apache More detailed help: -h, --help [topic] print this message, or detailed help on a topic; the available topics are: all, automation, paths, security, testing, or any of the subcommands or plugins (certonly, install, nginx, apache, standalone, webroot, etc) [root@nginxproxy letsencrypt]#
-
If you use a Free CloudFlare account and have the SSL features enabled, you must disable them prior to starting this because CloudFlare is basically acting as a MITM and breaking that SSL validation chain.
Prior to Let's Encrypt this was actually a really useful tool. I have almost all sites setup with CloudFlare and the SSL enabled in "Full" mode. This let my visitors get a trusted SSL and CloudFlare did not care what SSL I had on the backend as long as it was an expired certificate. For personal stuff I just used Self Signed.
Anyway, Let's Encrypt (rightly) does not accept that when validating.
Updating letsencrypt and virtual environment dependencies....... Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --standalone --email [email protected] --agree-tos -d jaredbusch.com -d www.jaredbusch.com Failed authorization procedure. jaredbusch.com (tls-sni-01): urn:acme:error:tls :: The server experienced a TLS error during DV :: Failed to connect to host for DVSNI challenge IMPORTANT NOTES: - The following 'urn:acme:error:tls' errors were reported by the server: Domains: jaredbusch.com Error: The server experienced a TLS error during DV [root@nginxproxy letsencrypt]#
-
Here is my
/etc/nginx/conf.d/jaredbusch.com.conf
in whole for reference.server { client_max_body_size 40M; listen 443 ssl; server_name www.jaredbusch.com jaredbusch.com; ssl on; ssl_certificate /etc/letsencrypt/live/jaredbusch.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/jaredbusch.com/privkey.pem; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=31536000; includeSubdomains"; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass https://10.254.0.101:443; proxy_redirect off; } } server { client_max_body_size 40M; listen 80; server_name www.jaredbusch.com jaredbusch.com; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://10.254.0.101:80; proxy_redirect off; } }
-
Now, I just need to get these certificates shipped off to the server behind. Why? Because while I know I do not have to encrypt after the proxy, I still want it all 100% encrypted.
-
Are you still renewing by hand?
-
Any updates to this?
-
@aaronstuder said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
Are you still renewing by hand?
I am at least.
-
I'm using cron with the old letsencrypt script. I haven't migrated over to certbot yet.
-
@dafyre said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
I'm using cron with the old letsencrypt script. I haven't migrated over to certbot yet.
Same.
-
@aaronstuder said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
Any updates to this?
Use Certbot never this method. keep your life simpler.
-
@JaredBusch said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
@aaronstuder said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
Any updates to this?
Use Certbot never this method. keep your life simpler.
Yeah. If the old way is working, that should keep working. However, certbot is easier to use.
-
@travisdh1 said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
@JaredBusch said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
@aaronstuder said in Setting up LetsEncrypt on a CentOS 7 NginX proxy:
Any updates to this?
Use Certbot never this method. keep your life simpler.
Yeah. If the old way is working, that should keep working. However, certbot is easier to use.
When my system came up for renew after certbot was out, I installed certbot and renewed that way. everything is in the same pace. nothing had to be changed in the config files.