iptablesDROP vs REJECT: Choosing the Right Firewall Response
The most surprising thing about DROP and REJECT in iptables is that REJECT often looks more helpful, but DROP is usually the more secure and efficient choice for packet filtering.
Let’s see what that looks like in practice. Imagine a simple firewall rule that blocks incoming SSH (port 22) from anywhere.
First, the DROP scenario. When a packet arrives destined for port 22, the iptables rule matches, and the packet is silently discarded. The sender gets no notification.
# Rule to DROP all incoming SSH traffic
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
On the client attempting to connect, this often manifests as a connection timeout. The client sends its SYN packet, but gets no SYN-ACK in response. After a period, the TCP stack on the client gives up.
Now, the REJECT scenario. When a packet arrives destined for port 22, the iptables rule matches. This time, iptables sends back an ICMP "destination unreachable" message (specifically, "port unreachable") to the sender.
# Rule to REJECT all incoming SSH traffic
sudo iptables -A INPUT -p tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
On the client attempting to connect, this is much faster. The client immediately receives the ICMP rejection, and its TCP stack knows the port is closed or unreachable.
The System in Action: How Packets are Handled
iptables operates as a stateful packet filtering firewall. When a packet arrives on an interface, it’s processed against a series of tables (filter, nat, mangle) and chains within those tables (INPUT, OUTPUT, FORWARD). Each rule in a chain consists of a set of conditions (protocol, source/destination IP, port, interface, etc.) and a target action. The target is what iptables does with the packet if all conditions in the rule are met. DROP and REJECT are two such target actions.
DROP: When a packet matches a DROP rule, iptables simply discards the packet. It’s as if the packet never existed. No acknowledgment is sent back to the sender. This is a "stealthy" approach.
REJECT: When a packet matches a REJECT rule, iptables discards the packet and sends an ICMP error message back to the sender. The specific ICMP message depends on the type of rejection (e.g., icmp-port-unreachable, icmp-net-unreachable, icmp-host-prohibited). This tells the sender that the packet was received but cannot be delivered.
Building the Mental Model: Security, Performance, and Information Leakage
The choice between DROP and REJECT hinges on a few key considerations:
-
Security:
DROPis generally considered more secure. By not sending any response, it makes it harder for an attacker to probe your network. An attacker trying to scan ports on aDROPfirewall will see those ports as "filtered" or "unreachable" after a timeout, but they won’t know for sure if the port is actively closed or if the firewall is just silently discarding packets. This obscures your network topology and running services.REJECT, on the other hand, immediately tells the sender that a host exists and that the port is specifically closed or unreachable, which can be valuable information for an attacker. -
Performance:
REJECTincurs a small overhead because the firewall has to generate and send an ICMP response packet for every rejected packet. For high-traffic scenarios or denial-of-service attacks, this can add up.DROPis more efficient as it just discards the packet without further processing or response generation. -
Usability and Debugging:
REJECTcan be more user-friendly for legitimate network traffic. If a legitimate user is trying to connect to a service that is intentionally blocked or not running, aREJECTresponse provides immediate feedback, leading to a quicker connection attempt failure rather than a frustrating timeout. This can be helpful for debugging network configurations. However, for external-facing firewalls, this immediate feedback can be a security risk. -
Network Behavior: Some network devices, like load balancers or routers, might not handle ICMP error messages gracefully or might have specific behaviors related to them. In rare cases, using
REJECTcould lead to unexpected network issues.DROPis generally more predictable in its lack of interaction.
The Lever You Control: -j DROP vs. -j REJECT
The primary lever is the target action you specify in your iptables rules.
-
To silently discard packets: Use
-j DROP. This is the default target for theINPUT,FORWARD, andOUTPUTchains in many defaultiptablesconfigurations and is often recommended for external interfaces where you want to hide your network’s presence.# Example: Drop all incoming traffic on eth0 that isn't already established sudo iptables -A INPUT -i eth0 ! -m state --state ESTABLISHED,RELATED -j DROP -
To send an ICMP error message: Use
-j REJECT. You can specify the type of ICMP error to send. The most common isicmp-port-unreachablefor TCP/UDP traffic.# Example: Reject all incoming traffic on eth1 destined for port 80 sudo iptables -A INPUT -i eth1 -p tcp --dport 80 -j REJECT --reject-with icmp-port-unreachable
When deciding, ask yourself: "Do I want the sender to know this packet was received but blocked, or do I want them to think it never arrived?" For most security-conscious scenarios, especially on internet-facing interfaces, the answer is the latter.
A common misconception is that REJECT is always "nicer" because it gives immediate feedback. However, in the context of network security, immediate feedback to an unknown sender is rarely desirable. It helps attackers fingerprint your network and identify active versus inactive hosts or services more quickly.
The next conceptual hurdle you’ll encounter is understanding how iptables handles stateful connections, particularly the ESTABLISHED,RELATED state, and how that interacts with your DROP or REJECT rules.