Most firewalls come pre-configured to quietly drop traffic rather than reject it. But what’s the difference between the two and is it truly better to drop instead of reject? If you have never given this question much thought, the answer might surprise you.
Firewall traffic control options
Firewalls typically give you three options when interacting with traffic, these are:
- Accept – Let the traffic pass through
- Drop – Remove the packet from the wire and generate no error packet
- Reject – Remove the packet from the wire and return an ICMP “Communication administratively prohibited” (ICMP type 3, code 13) error packet
Some firewalls are customizable when it comes to the reject packet that gets returned. For example Netfilter provides options from making the port look like its closed to tar pitting the connection. For the purpose of this post I’ll stick with just the administratively prohibited message since that’s the most widely deployed.
What happens when you port scan a system
An attacker can identify open versus closed ports on a system because each responds differently to a stimulus packet. When I send a TCP SYN packet to a system, one of the following is going to occur:
- If the port is open a TCP SYN/ACK will be returned
- If the port is closed a TCP RST/ACK will be returned
So if a SYN/ACK is returned, I know the port is open. If a RST (reset)/ACK is returned, I know the port is closed.
Now expand this out to the Internet level and some other possibilities come into play:
- If the host is off-line an ICMP host unreachable will be returned by the upstream router
- If the network the host is connected to is off-line, an ICMP network unreachable will be returned by the upstream router
- If a router or a firewall with a reject rule is blocking the connection, an administratively prohibited error is returned
- If the port is protected by a firewall with a drop rule, nothing is returned
Note that its the final two possibilities that involve traffic control. If we drop traffic, nothing is returned to the scanner. If we reject, then an ICMP error is returned.
The myth of stealthing the firewall
Vendors favor drop rules for two reasons, both of which are incorrect. The first is that dropping traffic helps to “stealth” the firewall. The concept is that since the firewall is returning no data, an attacker will be unable to determine you have a firewall. Look at the above response options again. The only time nothing is returned consistently is when a firewall with a drop rule is in the way. So by dropping traffic you are not stealthing the firewall, you are advertising it. This is why tools like nmap will actually report the probe as “filtered” when nothing comes back.
When I’ve confronted vendors with this fact, the response is either “Huh?” or “They still don’t know your firewall’s IP address so its still stealthed”. The second statement is only partially true in that an attacker would have to perform the additional step of running a tool such as tcptraceroute to determine the IP address of the firewall.
So the concept of being able to stealth a device that interacts with traffic flow is a complete myth. The closest match is probably Netfilter’s ability to reject via host unreachable messages. While this does not hide the IP address of the firewall, it does make the firewall look more like a router and help to mask the network segmentation behind it.
The myth of using less bandwidth
The second reason vendors favor drop rules is they think it generates less traffic on the wire. This makes sense logically unless you understand how TCP/IP communicates. In other words, on the surface this statement seems rational. Keep the ICMP errors off the wire and you are using less bandwidth. The reality however is that TCP tries very hard to be reliable. This means that when the first probe packet is quietly dropped, the source is going to send two, possibly four more packets to try again. If you add up the bits on the wire, you actually end up using more bandwidth when you force the source into retransmission mode.
What do the RFC’s say?
So which method is RFC legal, dropping or rejecting? If we reference RFC 1122 it says:
3.3.8 Error Reporting Wherever practical, hosts MUST return ICMP error datagrams on detection of an error, except in those cases where returning an ICMP error message is specifically prohibited.
“Specifically prohibited” refers to the fact that you should never respond to an error packet with another error packet. Its just too easy to create infinite loops. So if we are prohibiting traffic flow we are suppose to be returning an ICMP error message.
Making your IP range less attractive to spoofing
One of the biggest problems with using drop rules is that you make your IP range more attractive for spoofing. Consider the typical SYN flood attack where an attacker attempts to fill up a server’s TCP connection queue so that legitimate connection requests can not be serviced. The attacker will flood the target with TCP connection requests, typically from multiple zombie hosts. Since the attacker has no intention of completing the TCP three packet handshake, the source IP address is spoofed to help protect the true identity of the zombie.
If an attacker spoofs one of your IP addresses as part of their SYN flood, you will see the server under attack send unsolicited SYN/ACK packets to the spoofed IP address. This is not the server attacking your network, its simply the server responding to a connection request and it has no idea the source IP address was spoofed.
OK, let’s return to the above listed scanning options and combine that with your network setup to see what impact you will have on the attacker’s ability to perform a successful SYN flood attack. If your IP address they are spoofing is:
- Exposed host = RST/ACK returned, connection queue cleared on server in approximately 50 ms.
- Host off-line = Upstream router returns host unreachable in approximately 3 seconds
- Network off-line = Upstream router returns network unreachable in approximately 50 ms
- Reject rule = Firewall/router returns Administratively prohibited message in approximately 50 ms
- Drop rule = Server under attack attempts to respond for 30 seconds or more
The anatomy of a SYN flood
There are two metrics that come into play in making a SYN flood successful. The first is how many SYN packets can the attacker spoof per second. This metric will be determined by the size of the attacker’s zombie army. The second metric however, is something you have control of. That is “How long will each spoofed connection request tie up memory in the server’s connection queue?”.
As you can see in the above responses, when an attacker spoofs an IP address protected by a firewall drop rule, the bogus connection request ties up the server’s connection queue for the greatest amount of time. So let’s say the attacker wants to tie up one connection slot worth of memory for 60 seconds. That would take two spoofed packets protected by a firewall drop rule, or 1,200 spoofed packets if each spoofed IP is protected by a firewall reject rule. So spoofing dropped source IPs means the attacker requires fewer SYN packets per second in order to perform a successful attack. By deploying a drop rule you are inadvertently helping the attacker and making your address space more attractive to IP address spoofing.
Using drop rules to prevent traffic flow is widely deployed. This author feels this has more to do with “everyone following the herd” than with a drop implementation truly being a better security posture than using reject rules. Reject rules are more RFC compliant, generate less traffic on the wire, and make your address space less attractive for IP address spoofing.