Protecting your Application Database on the Network Level
By: Bernhard Schandl
Tags: Software Development, Networking, Security, Cloud Computing, Amazon Web Services

In a recent blog post, we outlined different security risks that a database for a Web application may be exposed to. One of these risks is access to the database on the network level: this opens the opportunity to perform Denial-of-Service (DoS) attacks, or to brute-force your database credentials, eventually leading to the possibility of unauthorized access to your and your users’ data.

One of the very basic things you can do to prevent unauthorized access to your database is to not expose it to the public Internet, but instead run it within a private network. Therefore, direct access from anywhere is impossible.

Of course, the servers hosting your application will still need to access the database. If your users (or your mobile apps) connect to these servers directly, they will need to be reachable from the outside. One thing that helps in such a situation is to separate your application across two sub-networks:

a public network where the components reside that are reachable from the Internet (e.g., your application servers), and

a private network that hosts all components that should only be reachable internally (e.g., your database, cache, or file store).

Of course, this requires careful configuration of the routers between these networks, so that the traffic that is required by your application is permitted, but all other traffic is disallowed. For instance, in the private subnet you will need to allow incoming traffic to your database hosts on the right port (say, 3306 for MySQL) but restrict this traffic’s origin to the public subnet.

One thing that helps to increase the segregation even more is the introduction of load balancers. These terminate your client connections and forward them to the application servers, which actually handle and process the requests. In such a scenario, you can move the application servers into the private subnet, too, and therefore close up your private network even more.

The figure below shows such a network setup.

In such a setup, the following traffic would be allowed:

Public Subnet: allows incoming traffic from everywhere on ports 80 and 443; additionally, if needed, allows incoming traffic from origins you trust (e.g., your company network) to port 22 for SSH

Private Subnet: allows incoming traffic from the private subnet on port 80 or 443 (depending on whether you encrypt internal traffic or not) and, if needed, allows incoming traffic to port 22 from the private subnet. All other traffic (in particular, any traffic from the outside) is prohibited.

As you can see, your application servers will not be reachable from the outside. That means, if you need to ssh into them, you need to go through servers in your public subnet. If your Load Balancers do not allow you to ssh into them, you can setup another host in the public subnet that acts as an ssh bridge (also known as “bastion”).

If you, like us, are running on Amazon Web Services, you should use Virtual Private Cloud (VPC) to set up different a private network and the required subnets within that network. (It may be useful to set up multiple subnets in multiple availability zones.) You should configure Network Access Control Lists (NACLs), which basically are sets of rules for incoming and outing traffic. These are applied on the subnet level. Further, you should configure Security Groups; again, these are sets of rules for incoming and outgoing traffic, but this time on the host level.