Demonstration
Here is my base iptable INPUT chain:
# iptables -L INPUT -n Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
As you can see, I am dropping all packets except TCP packets on port 22. I am going to open up port 4550:
# iptables -A INPUT -p tcp --dport 4550 -j ACCEPT # iptables -L INPUT -n Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:4550
Here I am using a netcat and an infinite loop as a simple “server” to send “i = $i” when someone connects to port 4550:
# i=0;while :; do echo i = $i | nc -l 192.168.6.20 4550; ((i++)); echo $i;done 1 2 3
In another terminal I have connected to port 4550 three times:
# time nc -w 120 -v 192.168.6.20 4550 Connection to 192.168.6.20 4550 port [tcp/*] succeeded! i = 0 real 0m0.842s user 0m0.001s sys 0m0.014s # time nc -w 120 -v 192.168.6.20 4550 Connection to 192.168.6.20 4550 port [tcp/*] succeeded! i = 1 real 0m0.822s user 0m0.000s sys 0m0.007s # time nc -w 120 -v 192.168.6.20 4550 Connection to 192.168.6.20 4550 port [tcp/*] succeeded! i = 2 real 0m0.526s user 0m0.002s sys 0m0.009s
Now I am going to delete the ACCEPT rule and add a REJECT rule:
# iptables -D INPUT 2 # iptables -A INPUT -p tcp --dport 4550 -j REJECT # iptables -L INPUT -n Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 REJECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:4550 reject-with icmp-port-unreachable
Here is the output of the “client” netcat command after adding the REJECT rule:
# time nc -w 120 -v 192.168.6.20 4550 nc: connect to 192.168.6.20 port 4550 (tcp) failed: Connection refused real 0m1.113s user 0m0.000s sys 0m0.005s
As you can see the command returned after ~1 second with an error. Now I am going to delete the REJECT rule. The default rule, DROP, will now be in effect:
# iptables -D INPUT 2 # iptables -L INPUT -n Chain INPUT (policy DROP) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Here is the output of the “client” program in another terminal session:
# time nc -w 120 -v 192.168.6.20 4550 nc: connect to 192.168.6.20 port 4550 (tcp) timed out: Operation now in progress real 2m0.152s user 0m0.000s sys 0m0.001s
The command took two minutes to return with the error. The -w 120 option causes netcat to timeout if no reply is recieved after 120 seconds.
Explanation
iptables is often used to block a specific ip address or subnet whom are doing something maclious. A REJECT rule will cause the maclicious host to recieve an error shortly after the connection attempt. A DROP rule will act differently. If they have set a client timeout, the malicious host will wait until said timeout is satisfied. Most likely several seconds. This should significantly slow the malicious program. A program without a client timeout will sit for hours waiting for a reply.


March 19th, 2008 at 10:33 am
Another reason to use DROP over REJECT is that REJECT verifies for the attacker that he has found a host to attack, whereas DROP appears as if he has found nothing.
March 19th, 2008 at 10:33 am
That is a great point.
March 19th, 2008 at 11:02 am
It really depends on what you are doing, whether you want to use reject or drop as a target.
If you are filtering outbound traffic from an internal trusted network, you certainly want to use reject, so internal users get a better ‘user experience’, even when you are not allowing the traffic out.
Also, if you use drop, many hosts will continue trying to connect to you. You will receive far more packets than if you use the reject target — the connecting host would likely closed the socket much quicker with a reject target. The tradeoff is that naughty folks would know your box was there, and that the port was being filtered.
So..talking myself back in a circle, I think it depends on what you are doing. A ‘always use drop’ motto may be a bit too broad of a brush.
March 19th, 2008 at 11:25 am
@elliot,
“If you are filtering outbound traffic from an internal trusted network, you certainly want to use reject, so internal users get a better ‘user experience’, even when you are not allowing the traffic out.”
I agree. In my explanation as I talked about malicious hosts.
“Also, if you use drop, many hosts will continue trying to connect to you. You will receive far more packets than if you use the reject target”
Its possible that this could be a problem. If the number of packets they are sending is a problem and their logic is such that if they receive a REJECT, they move on.
“A ‘always use drop’ motto may be a bit too broad of a brush.”
I agree there are situations where you want to REJECT. However, I’d have to see a situation where using DROP causes a problem in regards to malicious hosts before I changed my opinion.
March 19th, 2008 at 4:19 pm
Quite honestly, this is a standard issue bottom up firewall security policy. That is, drop everything but allow what you need. For that matter, iptables is essentially a basic firewall in this scenario.
What exactly does this have to do with bash, other than the fact that you are using bash as your shell when you invoke iptables?
March 19th, 2008 at 4:27 pm
> Quite honestly, this is a standard issue bottom up firewall security policy.
Agreed, but its not always followed. I know of admin’s who use REJECT as the default. I wanted to describe WHY you should DROP instead of REJECT.
> What exactly does this have to do with bash, other than the fact that you are using bash as your shell when you invoke iptables?
I quite often stray off the command line. For example, see my ftp/kernel debugging articles.
However when I do so, I try and provide some insight into command line, commands. In this example, I am showing how to use netcat as both a client and server in addition to some basics of iptables.
March 20th, 2008 at 10:14 am
Many distros, such as Fedora, do REJECT out of the box not DROP
March 21st, 2008 at 8:25 am
This is known as tarpiting and is a common practice; http://en.wikipedia.org/wiki/Tarpit_(networking)
March 21st, 2008 at 9:47 am
@Merlin,
Thanks the for the link.
The Linux kernel can now be patched to allow tarpitting of incoming connections instead of the more usual dropping of packets. This is implemented in iptables by the addition of a TARPIT target. The same packet inspection and matching features can be applied to tarpit targets as are applied to other targets.
While its similar, the (very) basic idea that you should DROP packets instead of REJECTing them from malicious hosts is distinct from the tarpitting as described in the article. DROPing instead of REJECTing when you are specifically targeting a single host or subnet I would consider, a good practice. Whereas tarpitting seems to be a fully developed method of operation.
March 25th, 2008 at 6:59 am
[...] [...]
April 9th, 2008 at 2:42 am
I agree with your methodology and your rationale. Ironport successfully leverages this technology in it’s anti-spam devices for two reasons.
One is, as you described, that it leaves the attacker in an unknown status. Not only will it take some resources to sit and wait for the timeout, but also, it’s likely that some algorithm will later again attempt to contact your host because it’s possible that your server was offline the first time it tried to hit you.
The second is that at high volumes of traffic you’re making a performance gain. By not bothering to put together a reject packet, you’re eliminating some CPU cycles(which are quite precious on an anti-spam device) and also you’re using a bit less bandwidth, which while cheap, is not free.