Providing End-to-End Encryption for a Web Application Hosted on a Spinup Linux Instance

Web applications are often deployed behind a load balancer or application firewall. This component provides secure encrypted sessions from the internet to the application.

It accomplishes this by listening for requests for the web application on ports exposed to the external environment and forwarding that traffic onto the application’s listening port. This forwarded traffic is often unencrypted.

However, in shared network environments such as Spinup, we highly recommend that traffic from the load balancer to the instance hosting the application be encrypted for conventional Spinup and require it for Secure Spinup.

Implementing encrypted session traffic to a web application hosted on a Spinup Linux instance is accomplished by installing Nginx as proxy on the instance hosting the web application.

This example has been validated on a CentOs 7 instance but is applicable to similar rpm-based distributions.

The procedure involves the following steps:

  1. Generating a self-signed SSL certificate

  2. Installing Nginx

  3. Configuring Nginx as a reverse-proxy using the self-signed SSL certificate

  4. Example configurations

  5. Configuring Nginx to start automatically as a service

  6. Configuring Firewalls

Generating a Self-Signed SSL Certificate

In order to encrypt the connection between the internet-facing load balancer and the instance running your web application, we will need to create and install an SSL certificate.

Since only the load balancer will be connecting to the Nginx proxy, a self-signed certificate is sufficient.

Cut and paste the following shell commands into your remote shell session:

export CERT_KEY='/etc/pki/tls/private/domain.key' # Default CentOS certificate key export CERT='/etc/pki/tls/certs/domain.crt' # Default CentOS certificate path cert_expire=${CERT_EXPIRE:-3650} cert_size=${CERT_SIZE:-rsa:2048} cert_subject=${CERT_SUBJECT:-/CN=localhost} sudo openssl req -x509 -nodes \ -days "${cert_expire}" \ -newkey "${cert_size}" \ -keyout "${CERT_KEY}" \ -out "${CERT}" \ -subj "${cert_subject}"

(Different distributions, use different locations for the key and the certificate. For example, Ubuntu uses the following:

CERT_KEY='/etc/ssl/private' # Default CentOS certificate key CERT='/etc/ssl/certs' # Default CentOS certificate path

)

Installing Nginx

Cut and paste the following shell commands into your remote shell session:

# CentOS sudo yum -y update sudo yum install -y epel-release sudo yum install -y nginx # Amazon Linux 2 # sudo amazon-linux-extras install nginx1.12 # Ubuntu # sudo apt update # sudo apt install nginx

Configuring Nginx as Reverse-Proxy

Configuration of Nginx is modular. Global configuration is located in /etc/nginx/nginx.conf. One could create server blocks in this file. However, a better practice is to separate server definitions in separate configuration files that are sourced into the main configuration when it starts.

Separate [server].conf files can be created under the /etc/nginx/conf.d/ directory which are loaded at start. (Debian and Ubuntu take this even further. These distributions place site configurations in /etc/nginx/sites-available/. To enable a specific site, a symlink to the specific /etc/nginx/sites-available/[server].conf is created in /etc/nginx/sites-enabled/.)

Cut and paste the following

Example Configurations

Example: uWSGI

Example: R Shiny

 

Enable Nginx at Startup

Note for SELinux

On CentOS 7, in order to use Nginx as a proxy service (as we are doing in these examples), it must be allowed access to the network:

sudo setsebool -P httpd_can_network_connect 1

Firewalls

In order to prevent direct access to the web application and force traffic to the TLS listener running in Nginx, you must enable the Space’s firewall for port 443: https://yaleits.atlassian.net/wiki/spaces/spinup/pages/656572438

Additionally, for moderate and low risk CIS OS images, the host based iptables must be modified to allow traffic to port 443.

References

https://www.nginx.com/blog/nginx-ssl/

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-tcp

https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/