topology: 2 linux computer connected directly . no iptables rules (except - iptables -A OUTPUT -p tcp -j NFQUEUE ) no firewall.

route is defined as - "route add default dev eth0"

on the second one ( run apache server .

I have a small program based on libnetfilter_queue that listen to the nfqueue and change the dst ip to in case that the dst ip is (i know that i can do it with iptables , but my program will do more things in the future), fix check sum and return to the queue.

if i call to telnet , means that my program dosnt need to do any manipulation, handshake is OK. If i call to telnet , my program change the dest. server get the syn and return syn-ack, but right after getting the syn-ack the client send rst.

Can anyone advice?

wireshark of the telnet

tcpdump of the telenet above

  • Your architecture description is insufficient and vague. Please specify more details about your network. Do you have 2 network segments? – dkaragasidis Jul 3 '12 at 15:31

If i call to telnet , my program change the dest. server get the syn and return syn-ack, but right after getting the syn-ack the client send rst.

The problem you have is you're opening a TCP socket to one endpoint (, rewriting the destination to and somehow ensuring that packets are sent back to your NIC.

When those packets arrive on your NIC, you don't have an open TCP socket in the linux kernel corresponding to, so the kernel sends a RST.

The only thing you can do to stop the damage done by the RST is to insert an iptables rule to drop TCP RST packets destined to from your source TCP port. You will need to remove this rule after you are finished.

  • Sorry, that it was not clear from my question. My program is based on libnetfilter_queue , so i dont open any socket . i get callback when packet add to the nfqueue than i check the ip dest , change it and return it to the queue . no socket was opened (i think so). – Avihai Marchiano Jul 3 '12 at 16:07
  • Has the packet got your linux machine's IP address in it? – Mike Pennington Jul 3 '12 at 16:17
  • Yep. You can see the iptables rule in the question. I am on the output event. – Avihai Marchiano Jul 3 '12 at 18:09
  • If the SYN-ACK is addressed to the same linux machine that sends the TCP RST, then that exactly describes the situation in my answer. You can either use iptables to mangle packets, or use iptables to prevent the TCP RST from going back to the webserver – Mike Pennington Jul 3 '12 at 18:13
  • In the question there are links to wireshark and tcpdump. Dosnt the socket is opened only after the packet passed the complete stack cycle ? I can decide to drop the packets , so it's seems strange to me that socket already opened. I will try your advice. – Avihai Marchiano Jul 3 '12 at 18:18

If you mangle packets in one direction, you should check the packets in the other direction whether they belong to such mangled connection and undo it.

In your case incoming packets with source might belong to a connection you mangled, and you should set the source back to

The kernel sends a RST because the source address doesn't match the one it sent the SYN to (the kernel doesn't know anything about your address translations).

  • I tried to mangle it back by adding: iptables -A INPUT -p tcp -J NFQUEU and in my program change the source ip from to the fake one -, but this dosnt solve the problem. if i have the following rule iptables -t nat -A OUTPUT -p tcp -d -j DNAT --to-destination it work without the need to mangle it back (in netstat you see that the fake one open). thank you!!!!!! – Avihai Marchiano Jul 4 '12 at 9:45
  • i'd say it "should" have worked with another NFQUEUE; also this is just what DNAT does anyway, from the man page: "and all future packets in this connection will also be mangled" - this applies to packets in both directions. – Stefan Jul 7 '12 at 11:32
  • its correct. i want to set it as a answer too, but you can set 2 answers. and i dont have enough budget to vote up. – Avihai Marchiano Jul 8 '12 at 1:15

The reason that the client ignore the syn-ack and send rst was beacause the port tables this port was register under ip (the original ip), so when ip sent syn-ack back with the same port the client sent RST.

More details explain:

I have a rule on IPTABLES OUTPUT that put output packets in the nfqueue . apparently on this stage the client already allocate a port and register it with the original ip, when you change the ip this registration dosnt change.

i change the ip and return it back to the NFQUEUE with the new dest ip.

a syn is sent to the fixed ip , but when it return syn-ack back his ip is not register on this port.

So solution is to have also INPUT rule and when you get packets back from the changed ip to change the ip back to the original one.

Thank you all for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.