All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Gubler <dg@doodle.com>
To: netfilter@vger.kernel.org
Subject: connlimit reached - cannot open connections even after I close some
Date: Thu, 24 Jan 2013 15:22:13 +0100	[thread overview]
Message-ID: <51014395.1000101@doodle.com> (raw)

Hi list,

I want to solve a seemingly simple problem: Limit the number of TCP 
connections coming from a single IP address to a web server on port 
8080. (background: we had some misbehaving clients eating up a lot of 
server resources by opening 400 parallel connections from a single IP - 
that number is unreasonnable even for proxy servers, so I want to 
enforce a limit)

This sounds like a case for connlimit, so this is what I did (max 4 
connections for easier testing):

iptables -A INPUT -p tcp --syn --dport 8080 -m connlimit 
--connlimit-above 4 -j REJECT

Fetching files with wget --limit-rate=1 shows that this works... sort of.

The fifth connection fails as expected, but after I kill some of the 
other connections (verified with netstat -anp | grep ESTABLISHED), I 
*still* cannot open new connections!

To be able to connect again, I have to cease *any* connect attempts for 
about two minutes. If I repeatedly try to connect, I'm not able to 
connect ever again (!), even when there are no more established connections.

As far as I can tell, the problem is the way connlimit works: It looks 
at the conntrack table and considers all entries there, even the 
SYN_WAIT ones (the ones that have been rejected by connlimit end up in 
that state). Or to put it differently: If connlimit denies a connection, 
that connection will *still* create a conntrack entry and thus will also 
count against the connection limit. This can be verified using the 
"conntrack -L" command.

This behaviour makes this simple setup completely unusable for us, 
because if some IP accidentally hits the limit I want that IP to be able 
to connect again as soon as it is back below the limit. Think well 
behaving NATs or proxy servers: They might have a very short burst which 
goes over the limit, so I want to block them for a few seconds, but 
after that things should immediately go back to normal.

After some research I came up with the following:

In addition to the connlimit rule above, I added

iptables -A PREROUTING -t raw -p tcp --dport 8080 -m connlimit 
--connlimit-above 4 -j NOTRACK
iptables -A OUTPUT -t raw -p tcp --sport 8080 -m connlimit 
--connlimit-above 4 -j NOTRACK

This prevents conntrack table entries from being created for connections 
that are over the limit.

But:

* Does this really do what I think it does (i.e. do you think this is 
safe for production)?
* It looks like there is a race condition: Some other connection could 
get closed between the NOTRACK and the REJECT rule. Result: A new 
connection would not get a conntrack entry because it is over the limit 
at first, but later would not be rejected because it is now under the 
limit. Could that be an issue?
* Is this a bug in connlimit?
* Am I missing something else (e.g. an undocumented parameter for 
connlimit)?

Thanks!

David

-- 
David Gubler
Senior Software & Operations Engineer
MeetMe: http://doodle.com/david
E-Mail: dg@doodle.com

             reply	other threads:[~2013-01-24 14:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-24 14:22 David Gubler [this message]
2013-02-03 11:51 ` connlimit reached - cannot open connections even after I close some Pascal Hambourg
2013-02-04 11:29   ` David Gubler
2013-02-05 19:54     ` Pascal Hambourg
2013-02-11 12:44       ` David Gubler
     [not found] <77346cbd-787d-4e7e-a918-d1b858d56b25@me.com>
2013-01-24 15:08 ` David Gubler
     [not found]   ` <CAHn-yPwtNh6sSo0PMScgavbgS=5mmLGaUHmQrj4wJQxMj4pWpA@mail.gmail.com>
2013-01-28 16:17     ` David Gubler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51014395.1000101@doodle.com \
    --to=dg@doodle.com \
    --cc=netfilter@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.