Installing an NGINX Proxy Over a Secure Connection
Configuring your NGINX server to use a strong encryption for client connections provides you with secure servers requests, preventing outside parties from gaining access to your traffic.
The Node.js platform that SQreamDB uses with our Studio user interface is susceptible to web exposure. This page describes how to implement HTTPS access on your proxy server to establish a secure connection.
TLS (Transport Layer Security), and its predecessor SSL (Secure Sockets Layer), are standard web protocols used for wrapping normal traffic in a protected, encrypted wrapper. This technology prevents the interception of server-client traffic. It also uses a certificate system for helping users verify the identity of sites they visit. The Installing an NGINX Proxy Over a Secure Connection guide describes how to set up a self-signed SSL certificate for use with an NGINX web server on a RHEL server.
Note
A self-signed certificate encrypts communication between your server and any clients. However, because it is not signed by trusted certificate authorities included with web browsers, you cannot use the certificate to automatically validate the identity of your server.
A self-signed certificate may be appropriate if your domain name is not associated with your server, and in cases where your encrypted web interface is not user-facing. If you do have a domain name, using a CA-signed certificate is generally preferable.
Prerequisites
The following prerequisites are required for installing an NGINX proxy over a secure connection:
Super user privileges
A domain name to create a certificate for
Installing NGINX and Adjusting the Firewall
After verifying that you have the above prerequisites, you must verify that the NGINX web server has been installed on your machine.
Though NGINX is not available in the default RHEL repositories, it is available from the EPEL (Extra Packages for Enterprise Linux) repository.
To install NGINX and adjust the firewall:
Enable the EPEL repository to enable server access to the NGINX package:
sudo yum install epel-release
Install NGINX:
sudo yum install nginx
Start the NGINX service:
sudo systemctl start nginx
Verify that the service is running:
systemctl status nginx
The following is an example of the correct output:
Output● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2017-01-06 17:27:50 UTC; 28s ago
Enable NGINX to start when your server boots up:
sudo systemctl enable nginx
Verify that access to ports 80 and 443 are not blocked by a firewall.
Do one of the following:
If you are not using a firewall, skip to Creating Your SSL Certificate.
If you have a running firewall, open ports 80 and 443:
sudo firewall-cmd --add-service=http sudo firewall-cmd --add-service=https sudo firewall-cmd --runtime-to-permanent
If you have a running iptables firewall, for a basic rule set, add HTTP and HTTPS access:
sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
Note
The commands in Step 8 above are highly dependent on your current rule set.
Verify that you can access the default NGINX page from a web browser.
Creating Your SSL Certificate
After installing NGINX and adjusting your firewall, you must create your SSL certificate.
TLS/SSL combines public certificates with private keys. The SSL key, kept private on your server, is used to encrypt content sent to clients, while the SSL certificate is publicly shared with anyone requesting content. In addition, the SSL certificate can be used to decrypt the content signed by the associated SSL key. Your public certificate is located in the /etc/ssl/certs directory on your server.
This section describes how to create your /etc/ssl/private directory, used for storing your private key file. Because the privacy of this key is essential for security, the permissions must be locked down to prevent unauthorized access:
To create your SSL certificate:
Set the following permissions to private:
sudo mkdir /etc/ssl/private sudo chmod 700 /etc/ssl/private
Create a self-signed key and certificate pair with OpenSSL with the following command:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
The following list describes the elements in the command above:
openssl - The basic command line tool used for creating and managing OpenSSL certificates, keys, and other files.
req - A subcommand for using the X.509 Certificate Signing Request (CSR) management. A public key infrastructure standard, SSL and TLS adhere X.509 key and certificate management regulations.
-x509 - Used for modifying the previous subcommand by overriding the default functionality of generating a certificate signing request with making a self-signed certificate.
-nodes - Sets OpenSSL to skip the option of securing our certificate with a passphrase, letting NGINX read the file without user intervention when the server is activated. If you don’t use -nodes you must enter your passphrase after every restart.
-days 365 - Sets the certificate’s validation duration to one year.
-newkey rsa:2048 - Simultaneously generates a new certificate and new key. Because the key required to sign the certificate was not created in the previous step, it must be created along with the certificate. The rsa:2048 generates an RSA 2048 bits long.
-keyout - Determines the location of the generated private key file.
-out - Determines the location of the certificate.
After creating a self-signed key and certificate pair with OpenSSL, a series of prompts about your server is presented to correctly embed the information you provided in the certificate.
Provide the information requested by the prompts.
The most important piece of information is the Common Name, which is either the server FQDN or your name. You must enter the domain name associated with your server or your server’s public IP address.
The following is an example of a filled out set of prompts:
OutputCountry Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc. Organizational Unit Name (eg, section) []:Ministry of Water Slides Common Name (e.g. server FQDN or YOUR name) []:server_IP_address Email Address []:admin@your_domain.com
Both files you create are stored in their own subdirectories of the /etc/ssl directory.
Although SQreamDB uses OpenSSL, in addition we recommend creating a strong Diffie-Hellman group, used for negotiating Perfect Forward Secrecy with clients.
Create a strong Diffie-Hellman group:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Creating a Diffie-Hellman group takes a few minutes, which is stored as the dhparam.pem file in the /etc/ssl/certs directory. This file can use in the configuration.
Configuring NGINX to use SSL
After creating your SSL certificate, you must configure NGINX to use SSL.
The default RHEL NGINX configuration is fairly unstructured, with the default HTTP server block located in the main configuration file. NGINX checks for files ending in .conf in the /etc/nginx/conf.d directory for additional configuration.
SQreamDB creates a new file in the /etc/nginx/conf.d directory to configure a server block. This block serves content using the certificate files we generated. In addition, the default server block can be optionally configured to redirect HTTP requests to HTTPS.
Note
The example on this page uses the IP address 127.0.0.1, which you should replace with your machine’s IP address.
To configure NGINX to use SSL:
Create and open a file called ssl.conf in the /etc/nginx/conf.d directory:
sudo vi /etc/nginx/conf.d/ssl.conf
In the file you created in Step 1 above, open a server block:
Listen to port 443, which is the TLS/SSL default port.
Set the
server_name
to the server’s domain name or IP address you used as the Common Name when generating your certificate.Use the
ssl_certificate
,ssl_certificate_key
, andssl_dhparam
directives to set the location of the SSL files you generated, as shown in the /etc/nginx/conf.d/ssl.conf file below:
upstream ui { server 127.0.0.1:8080; } server { listen 443 http2 ssl; listen [::]:443 http2 ssl; server_name nginx.sq.l; ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; ssl_dhparam /etc/ssl/certs/dhparam.pem; root /usr/share/nginx/html; # location / { # } location / { proxy_pass http://ui; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; add_header Front-End-Https on; add_header X-Cache-Status $upstream_cache_status; proxy_cache off; proxy_cache_revalidate off; proxy_cache_min_uses 1; proxy_cache_valid 200 302 1h; proxy_cache_valid 404 3s; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_no_cache $cookie_nocache $arg_nocache $arg_comment $http_pragma $http_authorization; proxy_redirect default; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffering on; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_intercept_errors on; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
Open and modify the nginx.conf file located in the /etc/nginx/conf.d directory as follows:
sudo vi /etc/nginx/conf.d/nginx.conf
server { listen 80; listen [::]:80; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
Redirecting Studio Access from HTTP to HTTPS
After configuring NGINX to use SSL, you must redirect Studio access from HTTP to HTTPS.
According to your current configuration, NGINX responds with encrypted content for requests on port 443, but with unencrypted content for requests on port 80. This means that our site offers encryption, but does not enforce its usage. This may be fine for some use cases, but it is usually better to require encryption. This is especially important when confidential data like passwords may be transferred between the browser and the server.
The default NGINX configuration file allows us to easily add directives to the default port 80 server block by adding files in the /etc/nginx/default.d directory.
To create a redirect from HTTP to HTTPS:
Create a new file called ssl-redirect.conf and open it for editing:
sudo vi /etc/nginx/default.d/ssl-redirect.conf
Copy and paste this line:
return 301 https://$host$request_uri:8080/;
Activating Your NGINX Configuration
After redirecting from HTTP to HTTPs, you must restart NGINX to activate your new configuration.
To activate your NGINX configuration:
Verify that your files contain no syntax errors:
sudo nginx -t
The following output is generated if your files contain no syntax errors:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart NGINX to activate your configuration:
sudo systemctl restart nginx
Verifying that NGINX is Running
After activating your NGINX configuration, you must verify that NGINX is running correctly.
To verify that NGINX is running correctly:
Check that the service is up and running:
systemctl status nginx
The following is an example of the correct output:
Output● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2017-01-06 17:27:50 UTC; 28s ago
Run the following command:
sudo netstat -nltp |grep nginx
The following is an example of the correct output:
[sqream@dorb-pc etc]$ sudo netstat -nltp |grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 15486/nginx: master tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 15486/nginx: master tcp6 0 0 :::80 :::* LISTEN 15486/nginx: master tcp6 0 0 :::443 :::* LISTEN 15486/nginx: master