You’ve been using firewalls wrong
The way most people typically use a Firewall is to open and close access to ports; in fact, many people install a firewall and leave it in a default state. As applications are installed, ports are opened for that application. However, this is pointless. If all you are doing is opening and closing ports on a firewall based on applications running on the system, then do not run the application and you are just as safe.
When someone makes a connection to your system, they are doing so over a port. If your system does not have any ports open on your system, then there’s nothing for someone to make a connection to. Your system is not magically open for someone to enter your system just because you don’t have a firewall. If you have no intentions on doing the things I list in this article — filtering inbound and outbound traffic — then just don’t expose ports on your system and you will be just as safe.
What is the Purpose
The purpose of a firewall is to provide you with the ability to filter and control the flow of traffic. If you are able, you could utilize fancier next generation firewalls that provide deep packet inspection. You would then be able to determine the type of traffic. Filtering allows you to expose ports and control who can access it, mostly allowing for internal use and restricting outsiders. This is mostly seen when you have a public facing server — particularly in the cloud. You could allow your companies IP range to access certain ports, while denying everyone else. That would be a simple and easy way to configure access. However, many cloud providers provide out-of-band (VPN) access to a private network, then you would just allow that range.
Traffic flow, specifically outbound, allow you to control who applications on your systems can talk to. This is useful when trying to ensure that sensitive systems are communicating with the correct systems. For example, you could ensure that your Dev application only talks to the Dev DB. An attacker, or misconfiguration, would not be able to pivot or extract data from systems by proxy. If a system is supposed to be internal, then you should ensure that it’s communications are internal. This also assumes an attacker is not able to escalate privileges to a level that has control of the firewall.
Filtering Inbound
So, let’s assume we are installing a web application on our system. For this system, we need to install Nginx, MySQL, and it lives in a cloud provider. We need to allow all of our customers to connect into the web server. However, they don’t need access to the MySQL database. With a firewall, we can allow everyone access to the web server. However, we need to only allow access to company IP addresses. While you can configure the database to not allow authentication to IP addresses outside your company, I would not recommend that. A database is not something the world needs access to, if a vulnerability exists in the database, this access could still allow an exploit. By using a firewall to allow everyone access to the web server, but filtering database traffic to only your companies network, you’re protecting the application from unauthorized access.
Filtering Outbound
Many people use a firewall to control the flow of traffic into a system. You can, and should, control the flow of traffic out of the system too. Controlling the flow of traffic outside your system allows you to control who your system communicates with. This can be useful when trying to determine behavior of a system, and ensuring it behaves in that way. Let’s take the web application as an example again. Let’s say your web application was exploited and an attacker was able to run code on your system to steal data. This attack utilizes remote code execution (unprivileged), and allows the attacker to run Bash commands. However, the firewall is designed to only allow established connections outbound, and all new connections can only be made to pre-defined IP ranges. This is completely possible with IPTables. When the attacker’s code attempts to open a new connection to attackerserver.com, the server is able to resolve the DNS name, because the DNS server is within that pre-defined IP range; however, the attacker’s server is not. Thus it is blocked.
This of course is one layer, and many layers of security need to be used to reduce the risk. While the risk of exploitation has been realized, the risk of data exfiltration has not. This is also a very simple example, and doesn’t mean you’d never have data exfiltration, attackers can be creative… so you need to be too.
Exception to the Rule
There is one exception to the rule of removing the firewall if you are not filtering traffic. Restricting applications from opening ports you haven’t authorized is one benefit. For this to work, you need your firewall enabled, and it needs to be configured with a default deny. If you are using the Windows firewall, you will see this when an application attempts to open ports on your system. For example, running Node.JS, Windows will request that you open a port on your system. If you’re using Linux, well, by default IPTables is going to default to accept, so you would need to change that for the INPUT chain.
Assuming the above is true, you can prevent an application in your environment from opening (listening) ports on your systems. This works for both users running applications that haven’t been approved, and potentially malicious applications trying to open ports on your system. The latter is probably less common, the former happens all the time.