HTTPS with Certbot for Nginx on Amazon Linux
Here's how you can configure Certbot for Nginx on Amazon Linux.
Create an EC2 instance on AWS
Make sure that the port 443 (SSL) and 22 (SSH) is open. In this tips, let's assume that we chose to use Amazon Linux.
Install Certbot
$ ssh -i ~/.ssh/my-aws.pem ec2-user@52.193.111.xxx
$ curl -O https://dl.eff.org/certbot-auto
$ chmod +x certbot-auto
$ sudo mv certbot-auto /usr/local/bin/certbot-auto
Install Nginx
$ sudo yum install nginx -y
(Nginx must be stopped during Certbot installation)
$ sudo service nginx stop
Configure your domain to point to the EC2 instance
You can do it with Route53 or any other domain registrars.
Run Certbot
ec2-user
on Amazon Linux sets /usr/local/bin
as a part of $PATH
so let's simply run following command:
(become a root user)
$ sudo su -
(Amazon Linux support is currently experimental, so don't forget to add "--debug" option. This will update the script itself when you run it for the first time)
# certbot-auto certonly --standalone -d example.com
(You'll be asked to enter your email address)
(Finally, you'll get a message like following)
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your cert will
expire on 2016-mm-dd. To obtain a new version of the certificate in
the future, simply run Certbot again.
- 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
Modify Nginx Configuration
Assuming that following commands are executed as root.
# cd /etc/nginx/
# cp nginx.conf nginx.conf.org
(Modify nginx.conf)
# vi nginx.conf
(The diff will be followings)
# diff nginx.conf nginx.conf.org
85,89c85,117
< server {
< listen 443 ssl;
< listen [::]:443 ssl;
< server_name localhost;
< root /usr/share/nginx/html;
---
> # Settings for a TLS enabled server.
> #
> # server {
> # listen 443 ssl;
> # listen [::]:443 ssl;
> # server_name localhost;
> # root /usr/share/nginx/html;
> #
> # ssl_certificate "/etc/pki/nginx/server.crt";
> # ssl_certificate_key "/etc/pki/nginx/private/server.key";
> # # It is *strongly* recommended to generate unique DH parameters
> # # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
> # #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
> # ssl_session_cache shared:SSL:1m;
> # ssl_session_timeout 10m;
> # ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
> # ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
> # ssl_prefer_server_ciphers on;
> #
> # # Load configuration files for the default server block.
> # include /etc/nginx/default.d/*.conf;
> #
> # location / {
> # }
> #
> # error_page 404 /404.html;
> # location = /40x.html {
> # }
> #
> # error_page 500 502 503 504 /50x.html;
> # location = /50x.html {
> # }
> # }
91,115d118
< ssl_certificate "/etc/letsencrypt/live/example.com/fullchain.pem";
< ssl_certificate_key "/etc/letsencrypt/live/example.com/privkey.pem";
< # It is *strongly* recommended to generate unique DH parameters
< # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048
< #ssl_dhparam "/etc/pki/nginx/dhparams.pem";
< ssl_session_cache shared:SSL:1m;
< ssl_session_timeout 10m;
< ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
< ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
< ssl_prefer_server_ciphers on;
<
< # Load configuration files for the default server block.
< include /etc/nginx/default.d/*.conf;
<
< location / {
< }
<
< error_page 404 /404.html;
< location = /40x.html {
< }
<
< error_page 500 502 503 504 /50x.html;
< location = /50x.html {
< }
< }
Let's restart nginx after the change:
# service nginx start
HTTPS is available now!
Let's open https://example.com and check that it's actually working!
Written by aeas44
Related protips
4 Responses
When I run certbot-auto certonly -standalone --debug -d mydomain.com
as root using my domain, I get the following error:
Creating virtual environment...
Installing Python packages...
Installation succeeded.
Traceback (most recent call last):
File "/root/.local/share/letsencrypt/bin/letsencrypt", line 7, in <module>
from certbot.main import main
File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/certbot/main.py", line 12, in <module>
import zope.component
File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/zope/component/init.py", line 16, in <module>
from zope.interface import Interface </code>
Do you have any tips as to what I can try in order to diagnose the problem?
@pstaight I just had the problem you mention when following the above. I didn't have virtualenv
on my system...but I did have virtualenv-2.7
one quick ln -s /usr/bin/virtualenv-2.7 /usr/bin/virtualenv
later and everything else worked beautifully.
Another thing that might be useful to mention is that since letsencrypt certs are only valid for 90 days we will want to auto renew. I played around with certbot-auto renew
and it suggested I use certonly
instead.
So I added the following to root's crontab:
* 3 15 * * /usr/local/bin/certbot-auto certonly -n --debug --pre-hook="service nginx stop" --post-hook="service nginx start" --standalone -d my.domain.example.com
-
--debug
was a requirement for using this on Amazon linux (so certbot-auto told me). -
-n
runs it non-interactively - the entry runs once a month, at 3AM on the 15th of each month. If I was concerned that there might be some outage and the jobs get missed (and I end up with an expired cert) then I could up the frequency. certbot won't do anything until the cert is due for renewal (after 60 days).
- I'm running nginx as a reverse proxy/SSL termination. It was easiest to bounce it so that certbot could authenticate in standalone mode (hence the
--pre-hook
and--post-hook
).
So what happens if we need to tear down the instance and create a new one. Are we just able to copy over the generated certs to a new instance? I assume creating new certs on a new instance would make browsers suspicious.