iptables reject tcp-reset on loopback

6

0

I am trying to check how a software would behave if there is a network failure. That software is using tcp send() and recv() to communicate.

Previously I was making the software communicate by putting them in 2 different machine on a lan network. So, to simulate a network failure I was using the below rule.

sudo iptables -A INPUT -p tcp -s 10.100.52.234 -j REJECT --reject-with tcp-reset

Lets suppose 10.100.52.234 is the IP of one of the systems. This was leading to a failure in an instant. All well and good.


Now, I am trying to simulate this in one machine using loopback address 127.0.0.1. Everything is working same just like the previous setup, but the above command is not working. It is not failing the network connection and the software just hangs. There is no communication happening but it does not fail either.

I have used the command

sudo iptables -A INPUT -p tcp -s 127.0.0.1 -j REJECT --reject-with tcp-reset

and

sudo iptables -A INPUT -p tcp -i lo -j REJECT --reject-with tcp-reset

both are not working. The software takes a very long time to fail.

Is there a different way to fail the connection for loopback address immediately?

Haris

Posted 2016-06-28T22:55:49.780

Reputation: 127

how about --reject-with icmp-host-unreachable or --reject-with icmp-port-unreachable ? – guest-vm – 2016-07-02T16:52:49.710

@guest Tried every one of those options. Same behaviour persists. – Haris – 2016-07-02T16:53:58.640

just a wild guess, correct me if i am wrong: since both client and server have same loopback IP, whatever rejection message in response to client would equally be blocked by the iptables rule. can you differentiate the two with port number in the rule? – guest-vm – 2016-07-02T17:10:55.630

Odd, Are you attempting to simulate the loopback interface failing? Isnt the loopback interface's purpose to allow you to still access a service thats running on the local machine when the network does indeed fail? (likely you would be accessing this service via console within the datacenter if the network ever did go down, and you'd be the only one too.. ) – NotAdmin Dave – 2016-07-02T21:49:49.157

Answers

4

I reproduced your result (with SSH connection attempt to 127.0.0.1 while my sshd was listening). It is true that the software just hangs.

I think the software awaits a response or an error message, but the error message falls into the same rule and is rejected. I don't know whether there is some chain reaction of error messages or not -- I did not investigate that far. I may get it wrong in the first place, so if someone has better explanation I will be happy to read it.


Here's the solution that works in my Debian:

You should connect to 127.0.0.2 (explanation here) and make your rule as follows:

sudo iptables -I INPUT 1 -p tcp -d 127.0.0.2 -j REJECT --reject-with tcp-reset

Note the -I INPUT 1 fragment that ensures the rule to be inserted at the first position to take precedence over any ACCEPT rule you may already have on your loopback interface (as I have in my Debian).

I repeated the test (with SSH connection attempt, this time to 127.0.0.2). It failed immediately with

Connection refused

I think it works as you wish because now the error message is destined to 127.0.0.1, thus not being caught by the rejection rule and able to pass.

Kamil Maciorowski

Posted 2016-06-28T22:55:49.780

Reputation: 38 429