Web Application Firewall

Configurable Default WAF Plugin

The VNS3 plugin system uses ModSecurity within Nginx as a web application firewall (WAF). This combination was chosen due to simplicity, high performance and proven durability and scale in large deployments such as CloudFlare.

The Nginx:ModSecurity combination is deployed to a VNS3 Controller using the containers mechanism. These instructions cover customization of the container image that will be used so that customer keys and rule sets can be employed.

Please be familiar with the VNS3 Plug-In Configuration Guide.

Getting the Default WAF Plug-In

The Linux Container default plug in is accessible at the following URL:
https://vns3-containers-read-all.s3.amazonaws.com/WAF_modsecurity_Base/WAF_modsecurity_nginx_2-0.tar.gz

This is a read-only Amazon S3 storage location. Only Cohesive Networks can update or modify files stored in this location.

This URL can be used directly in a VNS3 Controller via the Web UI or API to import the container for use into that controller. (General screenshot walkthrough and help available in the plug-in configuration document.)

Getting the Default WAF Plug-In

From the Container —> Images menu item, choose Upload Image.

To use the pre-configured plugin paste the URL into the Image File URL box.

Getting the Default WAF Plug-In When the Image has imported it will say Ready in the Status Column.

To then launch a running WAF container, choose Allocate from the Action menu.

Getting the Default WAF Plug-In

Launching a WAF Container

After selecting Allocate from the Actions menu you then name your container, provide a description and the command used to execute the container.

The name and description should be something meaningful within the context of your organization and its policies.

In MOST cases the command used to run plugin containers will be: /usr/bin/supervisord

However, this may vary with individual containers, please consult each plug-in’s specific documentation.

The command to run the WAF container is: /usr/bin/supervisord

Launching a WAF Container

Confirming the WAF Container is Running

After executing the Allocate operation you will be taken to the Container Display page.

You should see your WAF Container with the name you specified. The Status should be Running and it should have been given an IP address on your internal plug-in subnet (in this case 192.51.100.3).

Confirming the WAF Container is running

Customizing Default WAF Plugin

Accessing the WAF Container

Accessing a Container from the Public Internet or your internal subnets will require additions to the inbound hypervisor firewall rules with the VNS3 Controller as well as VNS3 Firewall.

The following example shows how to access an SSH server running as a Container listening on port 22.

Network Firewall/Security Group Rule

Allow port 22 from your source IP or subnets.

VNS3 Firewall

Enter rules to port forward incoming traffic to the Container Network and Masquerade outgoing traffic off the VNS3 Controller’s outer network interface.

#Let the Container Subnet Access the Internet Via the VNS3 Controller’s Outer or Public IP
MACRO_CUST -o eth0 -s <WAF Container Network IP> -j MASQUERADE
#Port forward port 44 to the WAF Container port 22
PREROUTING_CUST -i eth0 -p tcp -s 0.0.0.0/0 --dport 44 -j DNAT --to <WAF Container Network IP>:22

Accessing the WAF Container

Securing the WAF container

By default the WAF container has the following accounts, configured as described.

“root” - The root account is locked. The root account is not allowed to remote shell into the container. This is our recommended approach. However, if you wish to, you can use the “container_admin” account to unlock root, provide a root password, and edit /etc/ssh/sshd_config to allow remote login by root.

“container_admin” - The default password is container_admin_123! The default demo public key is also installed in the /home/container_admin/.ssh/authorized_keys. PLEASE change this password and this key when configuring, or create a new default WAF image as your base for future use, following your authentication procedures. The account “container_admin” has “sudo” or superuser privileges, and is allowed to remote shell into the container.

Primary files for customization

There are two significant files for securing the WAF container:
/etc/ssh/sshd_config

Please ensure this file is configured to your organization’s best practices.
/home/container_admin/.ssh/authorized_keys

The base container comes with an example public key installed, and private key for use in VNS3 documentation. Please remove after initial use or programmatic configuration.

The following files are the major elements for customizing the WAF container. It is not within the scope of this document to cover all elements of the included Nginx server, nor the Apache mod_security plugin, nor the OWASP rules set.

/etc/nginx/ssl/ssl.key
/etc/nginx/ssl/ssl.crt
Please replace with your own certs either self-generated or from a cert provider. These are default certs provided by Cohesive Networks for demonstration purposes.

If you would like to use Let’s Encrypt as your Certificate Authority, run the following script:

/opt/LetsEncryptSetup.sh

You will be asked for a DNS A record that points to your VNS3 instance, your email address, and the IP of your web/proxy server that is accessible by the VNS3 instance. For this example we have a web server that is on the VNS3 overlay network.

/etc/nginx/nginx.conf
This file determines critical elements on how your WAF will respond at a base level to HTTP and HTTPS protocols. If you want to disallow use of SSLv3 for example, you would change this configuration. It also determines the listening port, and importantly the fact that “modsecurity” is in use.

The nginx.conf file also determines whether to pass the traffic forward using port 80 or 443. Since the WAF Container is the first place the Web Application traffic will hit, it can receive on port 443 and then terminate SSL, passing the traffic on in plain HTTP (port 80). This is secure if the traffic is going to the Overlay network which is encrypted. If the traffic is going to be put into a Cloud or vSphere underlay, one might consider keeping it in HTTPS format.

If you have a webserver running on the VNS3 overlay network and would like to use the WAF container as a reverse proxy you will need to add proxy_pass section into the nginx.conf file:

location / {
     proxy_pass http://100.127.255.193:80;
     proxy_set_header Host $host;

The reverse proxy configuration requires a server to be defined in the nginx.conf file as well as VNS3 firewall rules to direct inbound port 80 and/or port 443(if you are using SSL) to the container IP.

The setting for “upstream appserver” determines the port used to forward the traffic on to the proxy. In the default configuration it is set to: server localhost:80;

/etc/nginx/modsec/modsecurity.conf
Please read about the “modsecurity” capabilities and configuration here.

Key configuration items are:

  • SecRuleEngine - in preconfigured plugin set to “DetectionOnly” (vs. On or Off) means that the WAF will log/alert but will not block web traffic.
  • SecAuditLog - default log location is /var/log/modsec_audit.log, without configuring to send to a syslog this is where alerts can be seen.
  • SecStatusEngine - in preconfigured plugin is set to “Off”. If set to “On” it sends anonymized statistics to the ModSecurity project.

Putting it all together - Getting traffic to your web servers via the VNS3 WAF Plugin

WAF Container Flow

WAF Container Flow

The Web Application traffic arrives at your VNS3 Controller where it is audited by the WAF components and then forwarded to the “true” web servers.

Forwarding Web Traffic to the WAF Container

To forward arriving Web Application traffic to the WAF container uses the same technique as was shown for accessing the WAF container via Remote Shell.

Network Firewall/Security Group Rule

Allow port 443 (or 80) from your source subnet(s).

VNS3 Firewall

Enter rules to port forward incoming traffic to the Container Network and Masquerade outgoing traffic off the VNS3 Controller’s outer network interface.

#Port forward port 443 to the WAF Container port 443
PREROUTING_CUST -i eth0 -p tcp -s 0.0.0.0/0 --dport 443 -j DNAT --to <WAF Container Network IP>:443
#Return the traffic back from the WAF Container via the VNS3 Controller
MACRO_CUST -o eth0 -s <WAF Container Network IP> -j MASQUERADE

Forwarding Web Traffic to the WAF Container

For Developers / DevOps approach

Getting the WAF container source

The Docker image source is distributed as a Dockerfile along with accompanying config files.

To get the source:

git clone https://github.com/cohesive/vns3-container-waf-nginx.git
cd haproxy15-ssl-ssh-waf-syslog

SSH access

Containers launched from the image that will be built use the included authorized_key file to specify who can gain access to the container (as root).

Insert appropriate public keys e.g.:

cp ~/.ssh/id_rsa.pub authorized_keys  
cat ~/.ssh/my_other_key.pub >> authorized_keys

If you need to generate a key then:

ssh-keygen -t rsa

TLS Certificates

Nginx in the container is configured to listen on port 443 and forward to the local HAproxy load balancer.

The ssl.crt and ssl.key files should be replaced with suitable certificates (self signed or generated by a CA).

To generate your own private key:
openssl genrsa -des3 -out ssl.key 1024

To remove the passphrase:
cp ssl.key ssl.key.bak && openssl rsa -in ssl.key.bak -out ssl.key

To generate a Certificate Signing Request (CSR):
openssl req -new -key ssl.key -out ssl.csr

To then make a certificate:
openssl x509 -req -days 3650 -in ssl.csr -signkey ssl.key -out ssl.crt

Export a Container Image

In the event that your VNS3 controller needs to be replaced or upgraded, you will need a copy of your configured WAF Container. We recommend creating and downloading an image of your container as part of the deployment process:

From the Containers page in the VNS3 web UI, select Action > Save as Image for your new WAF Container. Once that process is complete, you’ll be brought to the Images page. Select Action > Export on the new image, and provide a name.

Once Exporting is complete, you will have the option to download the image locally.