Reverse Proxy for Enabling SSL

What is a Reverse Proxy?

A reverse proxy is a server that typically sits behind the firewall in a private network and directs client request to the appropriate backend server. It provides additional level of abstraction and ensure smooth flow of traffic between client and server. Reverse proxy is effective in protecting the system from web vulnerabilities.

What is SSL?

SSL stands for Secure Sockets Layer which is the standard technology used to secure the data transferred between two systems by using encryption algorithm. The algorithm scramble the data in transit and prevent the hackers from reading/modifying any information. The information could be anything sensitive or personal like credit card details, any financial information, personal details.

Steps to enable SSL using Reverse Proxy

1. Basic configuration to Install Nginx

Nginx is used as a reverse proxy to get all the requests on DNS or IP on port 80 and 433 to your application.
To install Nginx:
sudo apt-get install nginx
sudo service nginx start
Check service is running:
sudo service nginx status
To start Nginx when the server boots, Enable Nginx:
sudo systemctl enable nginx
Add the following rules in the IP tables of your servers
sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT

2. SSL Certificate creation

SSL is the combination of a Public certificate and a private key. The SSL key is kept on the server secretly while the SSL certificate is publicly shared with anyone requesting the content.
The SSL key encrypt the content sent to client and the SSL certificate decrypt the content signed by the associate SSL key.
The directory to hold the public certificate should already exist on the server and below is the path
Below are the steps to create the path to hold the private key files with security to prevent any unauthorized access:
sudo mkdir /etc/ssl/private
sudo chmod 700 /etc/ssl/private
Command to create self-signed key and certificate pair with OpenSSL
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
Above Parameter Description
To Use OpenSSL , a strong Diffie-Hellman group should be created as it will be used while negotiating Perfect Forward Secrecy with clients. Below Command is used for creating dh group:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

3. Configure Nginx to use SSL

create a new file in the below directory to configure a server block that serves content using the certificate files we generated. We can then optionally configure the default server block to redirect HTTP requests to HTTPS.
Create and open a file called ssl.conf in the /etc/nginx/conf.d directory:
sudo vi /etc/nginx/conf.d/ssl.conf
Place below content in the file ssl.conf

4. Configure Nginx to redirect all HTTP to HTTPs

With this configuration, for any requests Nginx responds on port 433 with encrypted content while on port 80 responds with unencrypted content. This means that our site requires better encryption which is important while transferring any confidential data between the client and server.
Thankfully, the default Nginx configuration file allows to add directives to the default port 80 server by adding files in the below directory
/etc/nginx/default.d #direcoty
Create a new file called ssl-redirect.conf and open it using the below command
sudo vi /etc/nginx/default.d/ssl-redirect.conf
#Paste the below line in ssl-redirect.conf file#
return 301 https://$host$request_uri/;

5. Configuring Reverse proxy for the application

In the location /etc/nginx/conf.d/ssl.conf file, the configuration should be added to reverse proxy to your application. Remember that the proxy must go through HTTP and not HTTPs, as it is handled by Nginx.
When the TCP/IP packets go through the Public internet it has to be encrypted in the middle of way which is considered as the "dangerous path", when it reaches Nginx the server will have the private key to decrypt that packet and everything is secured.
Though there is no perfect security architecture, there is an option to enhance the security and make Nginx reverse proxy to HTTPs for application with proper configuration.
Example: if you have a node express server running, you would need a HTTPS configuration with the proper SSL certificates set up on it. This adds another level of security, and it’s good to man in the middle attacks.
With HTTP only approach, in the below file location add the following data and remember to change the port:
#file Location
#Add the below content in the conf file
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://localhost:<the-port-where-your-application-runs>;
proxy_read_timeout 90;

6. Configure Support to WebSockets

The websockets support is a little configuration in the location section of the file /etc/nginx/conf.d/ssl.conf file. Add the below data
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
The final ssl.conf file will be the below data,

7. Create Trusted Certificates

When multiple people using the system, this configuration for HTTPs work for development purposes while WSS might not work in Test/Prod environment.
When self signed certificate is used by WSS the below error might occur,
WebSocket connection to 'wss://…' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
To correct this error some trusted certificate is required and Nginx configuration must have .pem trusted certificate files only.
Use certbot with reachable domain to generate the trusted certificate. The below command is used to generate the required trusted certificates. Add the certificate to Nginx configuration replacing the self-signed certificates.
certonly --webroot --webroot-path=/var/www/html --email <your-email> --agree-tos --no-eff-email --staging -d <your-domain> -d www.<your-domain>
Restart Nginx to reflect the changes,
sudo service nginx restart