How to make all outgoing RST drop

18,756

Solution 1

Hmm, it's quite possible that this is going through the forward chain rather than the input or output chain, since you are running this on the host machine.

A trick to debug this is to use iptables -L -v, this displays counts of how many packets go to each rule, if you set up a command that send lots of packets like this

watch --interval 0.1 "nc remote.machine CLOSED_PORT"

you can work out which rule is getting hit. You should also be aware that there are orthogonal tables - sets of rule chains used in different situations (e.g for nat). It might be worth looking in the NAT table - since your virtual host might be NAT'ing through your host rather than having it's own IP address

iptables -L -v -t nat

It would be informative to know what IP address the virtual host has - since if this is disjoint from your network's subnet this will probably be being NAT'ed.

Solution 2

If you are looking to drop inbound RST packets, you will want to do this:

iptables -I INPUT -p tcp --tcp-flags ALL RST,ACK -j DROP
iptables -I INPUT -p tcp --tcp-flags ALL RST -j DROP

If you are looking to drop outbound RST packets, you will want to do this:

iptables -I OUTPUT -p tcp --tcp-flags ALL RST,ACK -j DROP

Why RST ACK? According to the RFC, any response to a TCP packet including a SYN must ACK that sequence number. Therefore, even if you are indicating that your port is closed, you respond with a RST ACK.

Why care about outbound RST? If you're trying to use a tool like Scapy to experiment with IP behavior, you will frequently need to prevent the host's IP stack from sending back a RST ACK. Alternatively, you could implement a pseudo-stack in Scapy, claiming a MAC, responding to ARP or ICMP ND for IPv6, and bind your own IP address, which will also prevent the host's stack from responding. Clearly, this is more work than simply blocking outbound RST packets.

Share:
18,756
Justin Carrey
Author by

Justin Carrey

Updated on June 25, 2022

Comments

  • Justin Carrey
    Justin Carrey almost 2 years

    I am trying to drop all the outgoing RST and incoming RST on all ports. I am using Debian linux. I tried all possible combinations of commands listed on the internet but nothing seems to work.

    For example, i tried:

    iptables -A OUTPUT -o eth0 -p tcp --tcp-flags RST RST -j DROP  
    iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
    iptables -A INPUT -p tcp --tcp-flags RST RST -m state --state RELATED,ESTABLISHED -j DROP  
    iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP  
    

    Still i am seeing RST packets being sent by the kernel and also receiving RST packets. Please try to resolve this issue

  • user207421
    user207421 about 10 years
    Do they indeed? ACK of what? A segment that is intended for a connection that doesn't exist? Why would you ACK that?
  • adrianlzt
    adrianlzt about 10 years
    Ok, sorry. I was working in a particular problem where packets where ack+rst, but sure not all rst packets have ack flag. But maybe the problem of Justin is packets with rst+ack are not filtered by rst only filter
  • David Hoelzer
    David Hoelzer almost 8 years
    You were quite right, @adrianlzt. If someone sends you a SYN, the proper response must include an ACK of the sequence number + 1. Therefore, even a closed port will respond to a SYN with a RST/ACK. It's in the RFC.
  • Yingpei Zeng
    Yingpei Zeng almost 7 years
    Thank you very much, but I have to use a bit different command line to drop outbound RST packets (i.e., no ACK flag): "iptables -I OUTPUT -p tcp --tcp-flags ALL RST -j DROP"
  • David Hoelzer
    David Hoelzer almost 7 years
    Well, that seems appropriate since I clearly stated in this answer that it drops only RST-ACK packets.