Enable HTTPS on localhost with NGINX
# Enable HTTPS on localhost with NGINX
From: [digitalocean](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04)
# 1. Create a self-signed key and certificate pair
```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.cer
# Note: digitalocean use extension .crt not .cer.
```
*[req](# 'We want to use X.509 certificate signing request (CSR) management.'). [X.509](# 'Is a public key infrastructure standard. It specifies that we want to make a self-signed certificate instead of generating a certificate signing request'). [nodes](# 'Stop encrypting certificate with a passphrase. We need Nginx to be able to read the file, without user intervention'). [days](# 'Valid days before expire.'). [newkey](# 'Generate a new certificate and a new key at the same time.'). [rsa:2048](# 'To make an RSA key that is 2048 bits long.'). [keyout](# 'Path to save the private key.'). [out](# 'Path to save the certificate.').*
Prompt: `Common Name (e.g. server FQDN or YOUR name):`
[FQDN](# 'A Fully Qualified Domain Name has the format: [hostname].[domain].[tld] . e.g. "shop.a.com", "*.a.com", or "*.a.com/CN=a.com", or IP(LAN or WAN).').
# 2. Enable perfect forward secrecy
Create a strong Diffie-Hellman group, which is used in negotiating Perfect Forward Secrecy with clients. This may take a few minutes.
```bash
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
```
*[Perfect Forward Secrecy](# 'Protect past sessions even though long-term secret keys or passwords are compromised in the future.'). [dhparam](# '(Generation and management of) Diffie-Hellman Parameters.').*
# 3. Create a reusable configuration snippet pointing to key and cer
```bash
sudo nano /etc/nginx/snippets/self-signed.conf
```
```
# /etc/nginx/snippets/self-signed.conf
ssl_certificate /etc/ssl/certs/nginx-selfsigned.cer;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
```
# 4. Create a reusable configuration snippet with encryption settings
```bash
sudo nano /etc/nginx/snippets/ssl-params.conf
```
```
# /etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line below
# that includes the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
```
Nginx will simply output a warning because we are using a self-signed certificate, so the SSL stapling will not be used.
# 5. Now ready to adjust the nginx configuration to use SSL
We use server block file named "default", adjust the keyword if you use another file.
```bash
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
sudo nano /etc/nginx/sites-available/default
```
```
# /etc/nginx/sites-available/default
# server 1, ignore illegal requests from server_name _ (won't match)
server {
listen 80 deferred;
listen [::]:80;
server_name _;
return 444;
}
# server 2, redirect http (80) to https (443)
server {
listen 80;
listen [::]:80;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
# 302 code (temporarily redirect) for testing.
# TODO: change to "301" if test finished and https works.
}
# server 3, our real server finally.
server {
# SSL configuration
listen 443 ssl http2 default_server; # default_server must be <= 1.
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
# ... other configurations ...
```
Alternative: allow both HTTP and HTTPS traffic (not recommended if it can be avoided)
```
# server 1
server {
listen 80 deferred;
listen [::]:80;
server_name _;
return 444;
}
# Server 2 and 3 combined, serve both 80 and 443 ports, no redirect.
server {
listen 80 default_server;
listen 443 ssl http2 default_server;
listen [::]:80 default_server;
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
# ... other configurations ...
```
# 6. Adjust the firewall
Make sure [ufw](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04 'is an interface to iptables that is geared towards simplifying the process of configuring a firewall, for beginners') is active by:
```bash
sudo ufw status verbose
# If not active, set it up and enable it:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw enable
# reconnected via ssh.
sudo ufw status verbose
sudo ufw allow http
sudo ufw allow https
# sudo ufw deny from 15.15.15.51 # ban someone
```
Allow the "Nginx Full" profile:
```bash
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
```
# 7. Apply changes in nginx
Syntax errors testing:
```bash
sudo nginx -t
```
*nginx: [warn] "ssl_stapling"* means self-signed certificate can't use SSL stapling.
If no other errors, restart nginx:
```bash
sudo systemctl restart nginx
```
# 8. Testing
Visit `https://server_domain_or_IP`. Connection not private? You are not worth trusting. Only certificate issued by trusted authority is trusted. Of course you can trust yourself.
Now test http redirection: `http://server_domain_or_IP`
# 9. Change temp redirect to a permanent redirect 301
```bash
sudo nano /etc/nginx/sites-available/default
```
```
# /etc/nginx/sites-available/default
# server 2
server {
# ...
return 301 https://$server_name$request_uri;
# ...
}
```
Test syntax, restart, visit page.
```bash
sudo nginx -t
sudo systemctl restart nginx
```
# 10. DONE.
From: [digitalocean](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04)
# 1. Create a self-signed key and certificate pair
```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.cer
# Note: digitalocean use extension .crt not .cer.
```
*[req](# 'We want to use X.509 certificate signing request (CSR) management.'). [X.509](# 'Is a public key infrastructure standard. It specifies that we want to make a self-signed certificate instead of generating a certificate signing request'). [nodes](# 'Stop encrypting certificate with a passphrase. We need Nginx to be able to read the file, without user intervention'). [days](# 'Valid days before expire.'). [newkey](# 'Generate a new certificate and a new key at the same time.'). [rsa:2048](# 'To make an RSA key that is 2048 bits long.'). [keyout](# 'Path to save the private key.'). [out](# 'Path to save the certificate.').*
Prompt: `Common Name (e.g. server FQDN or YOUR name):`
[FQDN](# 'A Fully Qualified Domain Name has the format: [hostname].[domain].[tld] . e.g. "shop.a.com", "*.a.com", or "*.a.com/CN=a.com", or IP(LAN or WAN).').
# 2. Enable perfect forward secrecy
Create a strong Diffie-Hellman group, which is used in negotiating Perfect Forward Secrecy with clients. This may take a few minutes.
```bash
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
```
*[Perfect Forward Secrecy](# 'Protect past sessions even though long-term secret keys or passwords are compromised in the future.'). [dhparam](# '(Generation and management of) Diffie-Hellman Parameters.').*
# 3. Create a reusable configuration snippet pointing to key and cer
```bash
sudo nano /etc/nginx/snippets/self-signed.conf
```
```
# /etc/nginx/snippets/self-signed.conf
ssl_certificate /etc/ssl/certs/nginx-selfsigned.cer;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
```
# 4. Create a reusable configuration snippet with encryption settings
```bash
sudo nano /etc/nginx/snippets/ssl-params.conf
```
```
# /etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line below
# that includes the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
```
Nginx will simply output a warning because we are using a self-signed certificate, so the SSL stapling will not be used.
# 5. Now ready to adjust the nginx configuration to use SSL
We use server block file named "default", adjust the keyword if you use another file.
```bash
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
sudo nano /etc/nginx/sites-available/default
```
```
# /etc/nginx/sites-available/default
# server 1, ignore illegal requests from server_name _ (won't match)
server {
listen 80 deferred;
listen [::]:80;
server_name _;
return 444;
}
# server 2, redirect http (80) to https (443)
server {
listen 80;
listen [::]:80;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
# 302 code (temporarily redirect) for testing.
# TODO: change to "301" if test finished and https works.
}
# server 3, our real server finally.
server {
# SSL configuration
listen 443 ssl http2 default_server; # default_server must be <= 1.
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
# ... other configurations ...
```
Alternative: allow both HTTP and HTTPS traffic (not recommended if it can be avoided)
```
# server 1
server {
listen 80 deferred;
listen [::]:80;
server_name _;
return 444;
}
# Server 2 and 3 combined, serve both 80 and 443 ports, no redirect.
server {
listen 80 default_server;
listen 443 ssl http2 default_server;
listen [::]:80 default_server;
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
# ... other configurations ...
```
# 6. Adjust the firewall
Make sure [ufw](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04 'is an interface to iptables that is geared towards simplifying the process of configuring a firewall, for beginners') is active by:
```bash
sudo ufw status verbose
# If not active, set it up and enable it:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw enable
# reconnected via ssh.
sudo ufw status verbose
sudo ufw allow http
sudo ufw allow https
# sudo ufw deny from 15.15.15.51 # ban someone
```
Allow the "Nginx Full" profile:
```bash
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
```
# 7. Apply changes in nginx
Syntax errors testing:
```bash
sudo nginx -t
```
*nginx: [warn] "ssl_stapling"* means self-signed certificate can't use SSL stapling.
If no other errors, restart nginx:
```bash
sudo systemctl restart nginx
```
# 8. Testing
Visit `https://server_domain_or_IP`. Connection not private? You are not worth trusting. Only certificate issued by trusted authority is trusted. Of course you can trust yourself.
Now test http redirection: `http://server_domain_or_IP`
# 9. Change temp redirect to a permanent redirect 301
```bash
sudo nano /etc/nginx/sites-available/default
```
```
# /etc/nginx/sites-available/default
# server 2
server {
# ...
return 301 https://$server_name$request_uri;
# ...
}
```
Test syntax, restart, visit page.
```bash
sudo nginx -t
sudo systemctl restart nginx
```
# 10. DONE.
评论
发表评论