Skip to content

Instantly share code, notes, and snippets.

@pedrouid
Last active March 7, 2024 14:46
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save pedrouid/4abcc16c0218a46a577cfa8186cb845d to your computer and use it in GitHub Desktop.
Save pedrouid/4abcc16c0218a46a577cfa8186cb845d to your computer and use it in GitHub Desktop.
Setup SSL with NGINX reverse proxy

Get a Free SSL Certificate With Let’s Encrypt

Let’s Encrypt is a free, automated, and open Certificate Authority.

  1. Install tools for using the Let's Encrypt certificates using Certbot
  sudo apt-get update \
  sudo apt-get install software-properties-common
  sudo add-apt-repository ppa:certbot/certbot
  sudo apt-get update
  sudo apt-get install python-certbot-nginx
  1. Configure your domain DNS to point to your droplet's IP

  2. Check if your domain is pointing correctly

    $ dig +short example.com
    > 138.68.174.154
    
  3. Run Certbot to create the SSL certificate

    sudo certbot --nginx certonly
    

Setup Nginx with SSL

  1. Install Nginx

    sudo apt-get install nginx
    
  2. Redirect all traffic traffic to SSL

    # Open the following file
    sudo vim /etc/nginx/sites-enabled/default
    
    # Delete everything and add the following
    server {
        listen 80;
        listen [::]:80 default_server ipv6only=on;
        return 301 https://$host$request_uri;
    }
    
  3. Create a secure Diffie-Hellman group (takes a few minutes)

    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
    
  4. Create a configuration file for SSL

    # Open the following file
    sudo vim /etc/nginx/snippets/ssl-params.conf
    
    # Paste the following from https://cipherli.st/ (follow the link for more info)
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
    ssl_session_timeout  10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off; # Requires nginx >= 1.5.9
    ssl_stapling on; # Requires nginx >= 1.3.7
    ssl_stapling_verify on; # Requires nginx => 1.3.7
    resolver 208.67.222.222 208.67.220.220 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    
    # Paste this at the bottom of the file
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
  5. Configure the server to use SSL

    ATTENTION: Replace all the example.com with your domain

    # Open the following file
    sudo vim /etc/nginx/sites-enabled/default
    
    # Paste the following bellow the existing config
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name example.com; # REPLACE HERE
    
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # REPLACE HERE
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # REPLACE HERE
    
        include snippets/ssl-params.conf;
    
        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_pass http://localhost:5000/;
            proxy_ssl_session_reuse off;
            proxy_set_header Host $http_host;
            proxy_pass_header Server;
            proxy_cache_bypass $http_upgrade;
            proxy_redirect off;
        }
    }
    
  6. Test the Nginx config

    $ sudo nginx -t
    > nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    > nginx: configuration file /etc/nginx/nginx.conf test is successful
    
  7. Start Nginx

    sudo systemctl start nginx
    
  8. Finally, test your app by visiting your domain on your browser!

@sshaikh
Copy link

sshaikh commented Mar 12, 2023

I found this really useful - thanks!

@f2ka07
Copy link

f2ka07 commented Mar 27, 2023

In addition to the aforementioned guide, there exists a graphical user interface (GUI) known as Nginx Proxy Manager, which may appeal to individuals who prefer not to work with code directly. The suggested approach to utilizing the Nginx Proxy Manager involves installing it on Docker and utilizing it to forward traffic to Docker containers within the same network. Following installation, generating SSL certificates is a simple process that can be achieved with a single click.

References:

  1. Nginx Proxy Manager Video
  2. Configure Nginx proxy_pass https

@chokychou
Copy link

For newer OS: sudo apt-get install python3-certbot-nginx

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