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:
Configuring Nginx as a reverse-proxy using the self-signed SSL certificate
Example configurations
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/