This is an adapted guide from Digital Ocean's How To Secure Nginx with Let's Encrypt on Ubuntu 20.04
Ensure you have your domain name pointing to your server's IP address. The DNS A records should be as follows:
A Record @ 1.1.1.1
A Record www 1.1.1.1
Assuming you've followed this previous guide to setup nginx, in your nginx config file sudo nano /etc/nginx/sites-enabled/myapp
, ensure you have server_name myapp.com www.myapp.com;
sudo apt install certbot python3-certbot-nginx
sudo ufw enable
sudo ufw status
sudo ufw allow 'Nginx Full'
sudo ufw allow 'OpenSSH'
Check that these are the only rules allowed by typing sudo ufw status
:
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
sudo certbot --nginx -d domain.com -d www.domain.com
Run through the certificate generator
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): admin@domain.com
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for domain.com
http-01 challenge for www.domain.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://domain.com and
https://www.domain.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=domain.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.domain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/domain.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/domain.com/privkey.pem
Your cert will expire on 2020-09-26. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. 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
http://domain.com
you should be redirected to https://domain.com/
http://www.domain.com
you should be redirected to https://www.domain.com/
https://www.ssllabs.com/ssltest/analyze.html?d=domain.com
and a SSL report will be generated. This installation method typically scores:Certificate: 100
Protocol Support: 100
Key Exchange: 90
Cipher Strength: 90
Overall Score: A
If you want to ensure users only use the non-www version of your site, you can modify your nginx config file sudo nano /etc/nginx/sites-enabled/myapp
to add redirects. The result will be https://www.myapp.com
, http://www.myapp.com
, http://myapp.com
will all be redirected to https://myapp.com
In your nginx config file you should have two server blocks, one for port 443 (https) and one for port 80 (http). Modify the server blocks to redirect requests to https://myapp.com
For example, you can add in redirect logic into your server block:
# Redirect all www to non-www
if ($host = www.myapp.com) {
return 301 https://myapp.com$request_uri;
}
The result for your /etc/nginx/sites-enabled/myapp
file will be:
server {
# Listen for https traffic
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
server_name myapp.com www.myapp.com;
root /home/deploy/myapp/current/public;
passenger_enabled on;
passenger_app_env production;
location /cable {
passenger_app_group_name myapp_websocket;
passenger_force_max_concurrent_requests_per_process 0;
}
location ~ ^/(assets|packs) {
expires max;
gzip_static on;
}
# Allow uploads up to 100MB in size
client_max_body_size 100m;
ssl_certificate /etc/letsencrypt/live/myapp.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# Redirect all www to non-www
if ($host = www.myapp.com) {
return 301 https://myapp.com$request_uri;
}
}
server {
# Listen for http traffic
listen 80;
listen [::]:80;
server_name myapp.com www.myapp.com;
# Redirect all http traffic to https
return 301 https://myapp.com$request_uri;
}
Afterwards, restart nginx sudo service nginx restart
and ensure it is active sudo service nginx status
. Open a browser and visit https://www.myapp.com
, http://www.myapp.com
, http://myapp.com
, you should be redirected successfully to https://myapp.com
.
Try stopping / starting / restarting nginx
sudo service nginx stop
sudo service nginx start
sudo service nginx restart
sudo service nginx status
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 0000-00-00 00:00:00 UTC; 10s ago
Docs: man:nginx(8)
Process: 61459 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 61475 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
Tailing error nginx logs sudo tail -f /var/log/nginx/error.log
showed:
[emerg] 45851#45851: bind() to [::]:80 failed (98: Address already in use)
[emerg] 45851#45851: bind() to 0.0.0.0:80 failed (98: Address already in use)
Use netstat, if netstat is unavailable, install it using apt install net-tools
Find out which process is running on port 80 sudo netstat -plant | grep 80
Kill the process running on port 80 sudo fuser -k 80/tcp
Start nginx sudo service nginx start