Skip to content

Instantly share code, notes, and snippets.

@clemlatz
Last active April 22, 2024 12:30
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save clemlatz/579b547cc04f205b929d32e4f243d4f9 to your computer and use it in GitHub Desktop.
Save clemlatz/579b547cc04f205b929d32e4f243d4f9 to your computer and use it in GitHub Desktop.
Setup a self-signed SSL certificate with Nginx (server and browser)

1. Configure server: Nginx

Create the certificate:

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

Create a strong Diffie-Hellman group:

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Create a new configuration snippet file for Nginx:

$ sudo vim /etc/nginx/snippets/self-signed.conf

Add:

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

Create a configuration snippet with strong encryption settings:

$ sudo vim /etc/nginx/snippets/ssl-params.conf

Add:

# 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.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line 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;

Configure Nginx site to use certificate:

server {

    listen 443 ssl;
    server_name example.com;
    include snippets/self-signed.conf;
    include snippets/ssl-params.conf;

    #...
}

2. Configure computer: macOS

From local computer, download the certificate:

$ scp user@host:/etc/ssl/certs/nginx-selfsigned.crt ~/cert.crt

Open the file with the Keychain Access utility:

$ open cert.crt
  1. Add the certificate to the System keychain (not login), authenticate.
  2. After it has been added, double-click it, authenticate again.
  3. Expand the "Trust" section.
  4. Set "When using this certificate" to "Always Trust"

That's it! Close Keychain Access and restart Chrome, and your self-signed certificate should be recognized now by the browser.

Sources :

@uniruddh
Copy link

Nice consolidated details.

@codecakes
Copy link

Need something that works for mobile browsing too

@nicolasembleton
Copy link

@codecakes Adding trusted certificate on mobile will fix it. But I'd personally recommend avoiding this and using letsencrypt with dev-only domain name.

@IAlwaysBeCoding
Copy link

Why use nano and vim and not just use one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment