All of lore.kernel.org
 help / color / mirror / Atom feed
* Best way to kill a live TCP connection?
@ 2011-01-11 12:35 Alessandro Vesely
  2011-01-11 14:41 ` Jan Engelhardt
  0 siblings, 1 reply; 12+ messages in thread
From: Alessandro Vesely @ 2011-01-11 12:35 UTC (permalink / raw)
  To: netfilter

Hi all,
this is clearly an overworked topic.  However, I haven't been able to
find definitive info about it.  Please help providing more insight.
In particular, if it is possible/convenient to design an RST injector
that uses libnetfilter_queue and how to attach it to iptables?  (I
would only send a RST to the local host/network.)

On iptables it is possible to say -j REJECT --reject-with tcp-reset.
From a netfilter, it is possible to mark packets whose connection has
to be forcibly closed, so that that REJECT target triggers for marked
packets.  However, this is overkill, as it implies filtering all
packets rather than just --syn.  In my case, I would kill the
connection right after detecting bad behavior, and at the same time
store the remote IP address in the database checked by a netfilter so
that further connection attempts will be dropped for a while.

Hm... but how to kill a live TCP connection?  I detect bad behavior
asynchronously (e.g. from log files) and thus would need a program or
function that kills any connection to the relevant IP address.  I've
found three different answers on google:


tcpkill
http://monkey.org/~dugsong/dsniff/
This takes a libpcap expression and generates raw TCP RST packets in
response to any matching packet.  The packet itself is not dropped,
but the connection is terminated.  The main loop is conceived like so:

	for (;;) {
		if ((pkt = (char *)pcap_next(pd, &pkthdr)) != NULL) {

	                // killer code is here
		}
	}

Part of the killer code looks like this:

	/*
	XXX - we ought to determine the rate of seqnum consumption and
	predict the correct seqnum to use, instead of brute force.
	*/
	for (i = 0; i < Opt_severity; i++) {
		ip->ip_id = libnet_get_prand(PRu16);
		seq = ack + (i * win);
		tcp->th_seq = htonl(seq);
		// ...
	}

Opt_severity is allowed values in [0, ..., 9] and by default is 3.


killcx
http://spamcleaner.net/en/misc/killcx.html
This is a parent/child Perl written procedure.  The parent sends a SYN

  # wait 0.5 second for our child to be ready :
  select( undef, undef, undef, 0.5 );
  print "[PARENT] sending spoofed SYN to [$local_ip:$local_port]".
     " with bogus SeqNum\n";

  # send spoofed SYN packet :
  my $packet = Net::RawIP->new({
      ip => {  frag_off => 0, tos => 0,
               saddr => $dest_ip, daddr => $local_ip
            },
      tcp =>{  dest => $local_port, source => $dest_port,
               seq => 10, syn => 1
            }
   });
   $packet->send;

The child sends a RST getting acknum from the packets it sniffs (using
Net::Pcap).  So one is left wondering whether sending that SYN packet
was necessary and reliable.  Apparently, without such kickoff packet
the program works only if some pristine packet happens to arrive on
the connection during the prescribed interval.

   # look for the magic acknum :
   if ( $tcp->{acknum} ) {
      print "[CHILD]  sending spoofed RST to [$local_ip:$local_port]".
         " with SeqNum [$tcp->{acknum}]\n";
      # we have it : spoof another packet (RST) with the correct seqnum
      # to close the connection :
      my $packet = Net::RawIP->new( {
         ip => {  frag_off => 0, tos => 0,
                  saddr => $dest_ip, daddr => $local_ip
               },
         tcp =>{  dest => $local_port, source => $dest_port,
                  seq => $tcp->{acknum}, rst => 1
               }
      } );
      $packet->send;

(For ESTABLISHED connections, a RST to the remote host is also sent.)


cutter
http://www.lowth.com/cutter/
This describes how to set up iptables rules, and suggests to inject a
forged packet, similar to killcx above, but without sniffing
packets.  Cutter uses FIN rather than SYN for the kickoff packet, and
describes its purpose like so:

  [I]f the firewall sends a packet that is "correct" in all respects
  except for the sequence number, then the host very helpfully tells
  us what should have been used.

Is that (still) true?

The site presents a self-contained, single-source, C program to
implement that technique.  The source is quite dated (April 2005) and
may need some adjustment, but even then did not work for me (either
my kernel or my firewall manage not to "helpfully tell" that number.)


For completeness, let me also mention a couple of related articles:

Programming with Libpcap
http://www.programming-pcap.aldabaknocking.com/

Detecting Forged TCP Reset Packets
http://www.isoc.org/isoc/conferences/ndss/09/pdf/08.pdf
(This mentions more RST injectors, snort and bro, and discusses
various details of injected RST packets.)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 12:35 Best way to kill a live TCP connection? Alessandro Vesely
@ 2011-01-11 14:41 ` Jan Engelhardt
  2011-01-11 16:21   ` Alessandro Vesely
  0 siblings, 1 reply; 12+ messages in thread
From: Jan Engelhardt @ 2011-01-11 14:41 UTC (permalink / raw)
  To: Alessandro Vesely; +Cc: netfilter

On Tuesday 2011-01-11 13:35, Alessandro Vesely wrote:

>Hi all,
>this is clearly an overworked topic.  However, I haven't been able to
>find definitive info about it.  Please help providing more insight.
>In particular, if it is possible/convenient to design an RST injector
>that uses libnetfilter_queue and how to attach it to iptables?  (I
>would only send a RST to the local host/network.)

If you use a ruleset that emits RST for NEW connections that are picked 
up rather than SYN-new,

-m conntrack --ctstate NEW -p tcp ! --syn --dport 22 -j REJECT 
--reject-with tcp-reset

.. makes it possible to RST-kill connections using `conntrack -D`.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 14:41 ` Jan Engelhardt
@ 2011-01-11 16:21   ` Alessandro Vesely
  2011-01-11 17:39     ` Pascal Hambourg
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Alessandro Vesely @ 2011-01-11 16:21 UTC (permalink / raw)
  To: netfilter; +Cc: support

On 11/Jan/11 15:41, Jan Engelhardt wrote:
> On Tuesday 2011-01-11 13:35, Alessandro Vesely wrote:
> 
>>Hi all,
>>this is clearly an overworked topic.  However, I haven't been able to
>>find definitive info about it.  Please help providing more insight.
>>In particular, if it is possible/convenient to design an RST injector
>>and how to attach it to iptables?
> 
> If you use a ruleset that emits RST for NEW connections that are picked 
> up rather than SYN-new,
> 
> -m conntrack --ctstate NEW -p tcp ! --syn --dport 22 -j REJECT 
> --reject-with tcp-reset
> 
> .. makes it possible to RST-kill connections using `conntrack -D`.

That's the most elegant method I've seen thus far.  Thanks a lot!

A generic rule like that (i.e. without --dport) is mentioned in the
tutorial http://www.iptables.info/en/iptables-problems.html#NEWNOTSYN
but I never realized it can be used this way.  (I CC this there.)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 16:21   ` Alessandro Vesely
@ 2011-01-11 17:39     ` Pascal Hambourg
  2011-01-11 21:10       ` Grant Taylor
  2011-01-12  0:20     ` Pablo Neira Ayuso
  2011-01-12  0:20     ` Pablo Neira Ayuso
  2 siblings, 1 reply; 12+ messages in thread
From: Pascal Hambourg @ 2011-01-11 17:39 UTC (permalink / raw)
  To: netfilter

Hello,

Alessandro Vesely a écrit :
> On 11/Jan/11 15:41, Jan Engelhardt wrote:
>> On Tuesday 2011-01-11 13:35, Alessandro Vesely wrote:
>> 
>>> In particular, if it is possible/convenient to design an RST injector
>>> and how to attach it to iptables?
>> 
>> If you use a ruleset that emits RST for NEW connections that are picked 
>> up rather than SYN-new,
>>
>> -m conntrack --ctstate NEW -p tcp ! --syn --dport 22 -j REJECT 
>> --reject-with tcp-reset
>> 
>> .. makes it possible to RST-kill connections using `conntrack -D`.
> 
> That's the most elegant method I've seen thus far.  Thanks a lot!

However this sends only one RST to one side of the connection, leaving
the connection half-open - until the other side sends a packet and gets
a RST too. IMO it would be more elegant to send RSTs to boths sides of
the connection.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 17:39     ` Pascal Hambourg
@ 2011-01-11 21:10       ` Grant Taylor
  2011-01-11 22:31         ` Jan Engelhardt
  2011-01-18 17:50         ` Alessandro Vesely
  0 siblings, 2 replies; 12+ messages in thread
From: Grant Taylor @ 2011-01-11 21:10 UTC (permalink / raw)
  To: Mail List - Netfilter

On 01/11/11 11:39, Pascal Hambourg wrote:
> However this sends only one RST to one side of the connection,
> leaving the connection half-open - until the other side sends a
> packet and gets a RST too. IMO it would be more elegant to send RSTs
> to boths sides of the connection.

Wouldn't it be possible to send packet to user space and have something 
else send the reset packets to both ends?  I.e. use IPTables to match 
the packets and have a user space daemon act on what IPTables matched.

(I'm speaking out of my arse here, so ignore me if I'm way off base.)



Grant. . . .

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 21:10       ` Grant Taylor
@ 2011-01-11 22:31         ` Jan Engelhardt
  2011-01-12  8:52           ` Alessandro Vesely
  2011-01-18 17:50         ` Alessandro Vesely
  1 sibling, 1 reply; 12+ messages in thread
From: Jan Engelhardt @ 2011-01-11 22:31 UTC (permalink / raw)
  To: Grant Taylor; +Cc: Mail List - Netfilter

On Tuesday 2011-01-11 22:10, Grant Taylor wrote:

> On 01/11/11 11:39, Pascal Hambourg wrote:
>> However this sends only one RST to one side of the connection,
>> leaving the connection half-open - until the other side sends a
>> packet and gets a RST too. IMO it would be more elegant to send RSTs
>> to boths sides of the connection.
>
> Wouldn't it be possible to send packet to user space and have something else
> send the reset packets to both ends?  I.e. use IPTables to match the packets
> and have a user space daemon act on what IPTables matched.

Well, you could augment ipt_REJECT to send two packets. It does not have 
to just send one.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 16:21   ` Alessandro Vesely
  2011-01-11 17:39     ` Pascal Hambourg
@ 2011-01-12  0:20     ` Pablo Neira Ayuso
  2011-01-12  0:20     ` Pablo Neira Ayuso
  2 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2011-01-12  0:20 UTC (permalink / raw)
  To: Alessandro Vesely; +Cc: netfilter, support, Jan Engelhardt

On 11/01/11 17:21, Alessandro Vesely wrote:
> On 11/Jan/11 15:41, Jan Engelhardt wrote:
>> On Tuesday 2011-01-11 13:35, Alessandro Vesely wrote:
>>
>>> Hi all,
>>> this is clearly an overworked topic.  However, I haven't been able to
>>> find definitive info about it.  Please help providing more insight.
>>> In particular, if it is possible/convenient to design an RST injector
>>> and how to attach it to iptables?
>>
>> If you use a ruleset that emits RST for NEW connections that are picked 
>> up rather than SYN-new,
>>
>> -m conntrack --ctstate NEW -p tcp ! --syn --dport 22 -j REJECT 
>> --reject-with tcp-reset
>>
>> .. makes it possible to RST-kill connections using `conntrack -D`.
> 
> That's the most elegant method I've seen thus far.  Thanks a lot!
> 
> A generic rule like that (i.e. without --dport) is mentioned in the
> tutorial http://www.iptables.info/en/iptables-problems.html#NEWNOTSYN
> but I never realized it can be used this way.  (I CC this there.)

I'll try to add this to the conntrack-tools manual, it's indeed good.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 16:21   ` Alessandro Vesely
  2011-01-11 17:39     ` Pascal Hambourg
  2011-01-12  0:20     ` Pablo Neira Ayuso
@ 2011-01-12  0:20     ` Pablo Neira Ayuso
  2 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2011-01-12  0:20 UTC (permalink / raw)
  To: Alessandro Vesely; +Cc: netfilter, support, Jan Engelhardt

On 11/01/11 17:21, Alessandro Vesely wrote:
> On 11/Jan/11 15:41, Jan Engelhardt wrote:
>> On Tuesday 2011-01-11 13:35, Alessandro Vesely wrote:
>>
>>> Hi all,
>>> this is clearly an overworked topic.  However, I haven't been able to
>>> find definitive info about it.  Please help providing more insight.
>>> In particular, if it is possible/convenient to design an RST injector
>>> and how to attach it to iptables?
>>
>> If you use a ruleset that emits RST for NEW connections that are picked 
>> up rather than SYN-new,
>>
>> -m conntrack --ctstate NEW -p tcp ! --syn --dport 22 -j REJECT 
>> --reject-with tcp-reset
>>
>> .. makes it possible to RST-kill connections using `conntrack -D`.
> 
> That's the most elegant method I've seen thus far.  Thanks a lot!
> 
> A generic rule like that (i.e. without --dport) is mentioned in the
> tutorial http://www.iptables.info/en/iptables-problems.html#NEWNOTSYN
> but I never realized it can be used this way.  (I CC this there.)

I'll try to add this to the conntrack-tools manual, it's indeed good.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 22:31         ` Jan Engelhardt
@ 2011-01-12  8:52           ` Alessandro Vesely
  0 siblings, 0 replies; 12+ messages in thread
From: Alessandro Vesely @ 2011-01-12  8:52 UTC (permalink / raw)
  To: Mail List - Netfilter

On 11/Jan/11 23:31, Jan Engelhardt wrote:
> On Tuesday 2011-01-11 22:10, Grant Taylor wrote:
>> On 01/11/11 11:39, Pascal Hambourg wrote:
>>> However this sends only one RST to one side of the connection,
>>> leaving the connection half-open - until the other side sends a
>>> packet and gets a RST too. IMO it would be more elegant to send RSTs
>>> to boths sides of the connection.
>>
>> Wouldn't it be possible to send packet to user space and have something else
>> send the reset packets to both ends?  I.e. use IPTables to match the packets
>> and have a user space daemon act on what IPTables matched.
> 
> Well, you could augment ipt_REJECT to send two packets. It does not have 
> to just send one.

Besides practical issues about augmenting modules, RST will never be
as clean as FIN.  I mean, aborting will still be different from
cleanly shutting down.  This particular difference, the minimal-cost
tarpit that results from sending RST to the local end only, may even
have its merits.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-11 21:10       ` Grant Taylor
  2011-01-11 22:31         ` Jan Engelhardt
@ 2011-01-18 17:50         ` Alessandro Vesely
  2011-01-18 18:45           ` Gáspár Lajos
  1 sibling, 1 reply; 12+ messages in thread
From: Alessandro Vesely @ 2011-01-18 17:50 UTC (permalink / raw)
  To: Mail List - Netfilter

Having tried it, it's rather tricky.  The behavior depends on when the
connection is deleted.  For example, with

   # input rule meant to drop incoming packets
   iptables -A INPUT -m conntrack --ctstate NEW -p tcp ! --syn\
      -j DROP
and
   # output rule to reset connections to the local server
   iptables -A OUTPUT -m conntrack --ctstate NEW -p tcp ! --syn\
      -j REJECT --reject-with tcp-reset

the connection is most likely deleted after the local server has sent
a reply but before the remote client sends a further commands.  In
this case the server will timeout waiting for those dropped input packets.

I tried removing that input rule.  That way the relevant packets are
accepted, but server's reply packets in the OUTPUT table are marked
ESTABLISHED again.

I tried using connmark, as in

   iptables -A INPUT -m conntrack --ctstate NEW -p tcp ! --syn\
      -j CONNMARK --or-mark 8
and
   iptables -A OUTPUT -m connmark --mark 8/8 -p tcp ! --syn\
      -j REJECT --reject-with tcp-reset

However, the latter rule never matched.  Is it the wrong table?

-- 
BTW, I'v added a request for tcp-reset-both to the wish list
http://bugzilla.netfilter.org/show_bug.cgi?id=696 (I hope I'll still
be alive by the time it lands on debian ;-)  For debian users, lenny's
conntrack doesn't work, but v0.9.14 of squeeze does --see
http://marc.info/?l=netfilter&m=127653938407010&w=2 for pinning--
conntrack -D -s 1.2.3.4 works for me despite the bug in
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=496769 mentions 0.9.15.)

N.B. Despite announce of 15/09/10, I couldn't find conntrack 0.9.15 in
http://conntrack-tools.netfilter.org/downloads.html



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-18 17:50         ` Alessandro Vesely
@ 2011-01-18 18:45           ` Gáspár Lajos
  2011-01-19 13:32             ` Alessandro Vesely
  0 siblings, 1 reply; 12+ messages in thread
From: Gáspár Lajos @ 2011-01-18 18:45 UTC (permalink / raw)
  To: Alessandro Vesely; +Cc: Mail List - Netfilter

Do you know the conntrack tool?

conntrack -D...


2011-01-18 18:50 keltezéssel, Alessandro Vesely írta:
> Having tried it, it's rather tricky.  The behavior depends on when the
> connection is deleted.  For example, with
>
>     # input rule meant to drop incoming packets
>     iptables -A INPUT -m conntrack --ctstate NEW -p tcp ! --syn\
>        -j DROP
> and
>     # output rule to reset connections to the local server
>     iptables -A OUTPUT -m conntrack --ctstate NEW -p tcp ! --syn\
>        -j REJECT --reject-with tcp-reset
I do not think that the outgoing packets will be sent without a SYN... 
But you may check it.
> the connection is most likely deleted after the local server has sent
> a reply but before the remote client sends a further commands.  In
> this case the server will timeout waiting for those dropped input packets.
>
> I tried removing that input rule.  That way the relevant packets are
> accepted, but server's reply packets in the OUTPUT table are marked
> ESTABLISHED again.
>
> I tried using connmark, as in
>
>     iptables -A INPUT -m conntrack --ctstate NEW -p tcp ! --syn\
>        -j CONNMARK --or-mark 8
> and
>     iptables -A OUTPUT -m connmark --mark 8/8 -p tcp ! --syn\
>        -j REJECT --reject-with tcp-reset
>
> However, the latter rule never matched.  Is it the wrong table?
>
Do you have more connmark rules? Maybe something interferencing whit 
these rules...

Swifty

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Best way to kill a live TCP connection?
  2011-01-18 18:45           ` Gáspár Lajos
@ 2011-01-19 13:32             ` Alessandro Vesely
  0 siblings, 0 replies; 12+ messages in thread
From: Alessandro Vesely @ 2011-01-19 13:32 UTC (permalink / raw)
  To: Mail List - Netfilter

On 18/Jan/11 19:45, Gáspár Lajos wrote:
> Do you know the conntrack tool?
> 
> conntrack -D...

Yes, I'm sorry I didn't leave more context in place.  The thread was
about deleting connections as above and have iptables kill them as a
side effect.

>> I tried using connmark, as in
>>
>>     iptables -A INPUT -m conntrack --ctstate NEW -p tcp ! --syn\
>>        -j CONNMARK --or-mark 8
>> and
>>     iptables -A OUTPUT -m connmark --mark 8/8 -p tcp ! --syn\
>>        -j REJECT --reject-with tcp-reset
>>
>> However, the latter rule never matched.  Is it the wrong table?
>
> Do you have more connmark rules? Maybe something interferencing whit
> these rules...

Not connmark --which I'm unfamiliar with-- but there was a sanity
check that I overlooked.  Your question has put me on the right track.
 Thanks!

Now, having fixed that, terminating connections this way apparently
works perfectly: issuing "conntrack -D -s x.x.x.x", the local end of
each connection to x.x.x.x is reset, thereby saving server's
resources, while malicious clients are left idling alone.

This seems about the best I can get.  However, this method still has
two minor defects:

First, after I have determined that the client is malicious I have to
let in one more packet.  This could be avoided using the
tcp-reset-destination iptables enhancement that I proposed.

Second, if such further packet never arrives, the server has to wait
until timeout.  I think I'd need the seq/ack numbers of the last
packet in order to avoid this.  They must be somewhere in the system,
don't they?  (Or would it help to send spoofed packets to remote
clients at the time their maliciousess is determined, as other
methods* do?)

Further thoughts?

-- 
[*] see killcx or cutter, mentioned upthread.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-01-19 13:32 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-11 12:35 Best way to kill a live TCP connection? Alessandro Vesely
2011-01-11 14:41 ` Jan Engelhardt
2011-01-11 16:21   ` Alessandro Vesely
2011-01-11 17:39     ` Pascal Hambourg
2011-01-11 21:10       ` Grant Taylor
2011-01-11 22:31         ` Jan Engelhardt
2011-01-12  8:52           ` Alessandro Vesely
2011-01-18 17:50         ` Alessandro Vesely
2011-01-18 18:45           ` Gáspár Lajos
2011-01-19 13:32             ` Alessandro Vesely
2011-01-12  0:20     ` Pablo Neira Ayuso
2011-01-12  0:20     ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.