Will using iptables DROP target result in socket CLOSE_WAIT that never completes?

I have some simple rules to block certain IP blocks used frequently by hackers/spammers, e.g.:

iptables -A INPUT -s 173.208.250.0/24 -j DROP

But, I noticed that apache hangs after a couple of days with many CLOSE_WAITs showing in netstat's output that never go away:

# netstat -atlpn 
Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address Foreign   Address State PID/Program name 
tcp 1 0 ::ffff:10.0.0.107:80 ::ffff:173.208.250.123.50813 CLOSE_WAIT 29125/httpd

Could this be caused by specifying the DROP target in the rule? Should I use REJECT instead?


Solution 1:

Could this be caused by specifying the DROP target in the rule?

No.

Should I use REJECT instead?

No.


A DROP target on that rule on the INPUT chain will mean that Apache never gets to see the very first SYN packet or any packet at all with that source address. Without establishing a connection, it will never end up in the CLOSE_WAIT state. See the state diagram from Wikipedia below:

TCP state diagram

As you can see, CLOSE_WAIT only happens after an established session and only on the server if the client initiates closing the session. With KeepAlive, the session stays open until one of the client or the server reaches their timeout and actively closes the session.

It is common for the server to reach this timeout and close the session, leading the server to end up with a lot of connections in the TIME_WAIT state. They will stay in this state for two minutes by default but this will very rarely cause a problem. TIME_WAIT connections (on Linux) tie up a IP/port combination but you won't run out of those until you have about 30,000 connections in the TIME_WAIT state.


The source address range in your rule does not match the IP address in the CLOSE_WAIT state in your example.

REJECT is polite to use for polite people if for some reason you are not able to accept their connections because it allows them to close the connection immediately, but for hackers/spammers there is no need to be polite. Make them wait for whatever timeout they have configured.


So, what can cause connections in the CLOSE_WAIT state? The client sends a FIN, the server responds with a FIN/ACK and then waits for the final ACK. If it never received that final ACK, it's stuck there until something else happens such as restarting Apache.

Bad connection state tracking in other code (such as a hardware firewall) could cause this, as could problems at the client end. I couldn't be sure what's causing your specific problem.