Initial security measures for a web facing Linux server

Lesson learned. Even if you are hot-tempered and can't wait to get your application out, do not forget to review your server's security configuration before attaching a public domain to it. Even basic things like leaving a few ports open can become an open door for an attacker to execute an exploit against an application listening on that port. This post covers the measures I took after my newly set up server was attacked. I should have done this before, but I didn't so I had to pay the price for this mistake - my websites were down for a few days and I had to redo the configuration from scratch.

This post will cover the basic measures taken on a web facing Linux server.

Nginx Reverse Proxy Server

Nginx is great not only for serving web content. It also allows to relay traffic to another application which can listen on a different port on the same machine or on a different machine, typically on an internal network, allowing to isolate critical applications from the Internet. Any server block in Nginx that proxies requests can also act as the SSL termination point. The example below shows Nginx virtual host set up as an upstream proxy and SSL termination point for a Tomcat Server deployed on a different host on the private network.

server {  
    listen 443;
    server_name api.bushidowallet.com;  

    ssl on;
    ssl_certificate /etc/nginx/sites-available/cert/bundle.crt;
    ssl_certificate_key /etc/nginx/sites-available/cert/star_bushidowallet_com.key;

    ssl_session_timeout 5m;

        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
        ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://10.128.2.25:8080;
    }       
}

If you run all apps on a single machine, you can still proxy to 127.0.0.1. Credits to Radosław Gruchalski

Firewall setup

Utilizing Nginx as a Reverse Proxy Server allows us to block any incoming traffic to port 8080 on a server that has a direct connection to the Internet. Similar approach can also be used for any HTTP Server - NodeJS fits here perfectly as well. Pretty much you should end up with web facing machine only allowing ports 80 and 443 for incoming traffic.

System Services Security

There is a great article on how to secure services running on Debian Linux here - this pretty much applies to any Linux distribution. I highly recommend reading this document, especially parts about disabling the RPC services and securing the SSH daemon.

Comments

comments powered by Disqus