Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Feb 2007 20:37:50 +0400
From:      admin <admin@azuni.net>
To:        Ian Smith <smithi@nimnet.asn.au>
Cc:        freebsd-net@freebsd.org, freebsd-questions@freebsd.org
Subject:   Re: ipfw limit src-addr woes
Message-ID:  <45D9D25E.1050007@azuni.net>
In-Reply-To: <Pine.BSF.3.96.1070219235025.26249C-100000@gaia.nimnet.asn.au>
References:  <Pine.BSF.3.96.1070219235025.26249C-100000@gaia.nimnet.asn.au>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
Ian Smith wrote:
> On Mon, 19 Feb 2007, admin wrote:
>  > Ian Smith wrote:
>  > > On Mon, 19 Feb 2007, admin wrote:
>  > >  > Andre Santos wrote:
>  > >  > > On 2/18/07, admin <admin@azuni.net> wrote:
>  > >  > > 
>  > >  > >> Hi, I'm trying to use ipfw's limit clause to limit the number of
>  > >  > >> connections a single IP can have at the same time in a transparent
>  > >  > >> web-proxy environment:
>  > >  > >>
>  > >  > >> 00350 skipto 401 tcp from x.x.x.x/x,y.y.y.y/y,z.z.z.z/z to any dst-port
>  > >  > >> 80 in via if0 setup limit src-addr 10
>  > >  > >> 00401 fwd local.ip.ad.dr,8080 tcp from x.x.x.x/x to any dst-port 80
>  > >  > >> ... the rest fwd...
>  > >  > >>
>  > >  > >> as I understand the manpage, when the current number of connectiions is
>  > >  > >> below 10, the action "skipto" is performed, else, the packet is dropped
>  > >  > >> and the search terminates. But...
>  > > 
>  > > No, a packet is not dropped on a condition that fails a skipto test. 
>  > > 
>  > The manpage doesn't make this point clear.
> 
> You pretty much have to read it all .. several times .. a year.  One of
> the things you note is that each rule is tested until a packet is either
> allowed or denied by a rule, even until '65535 deny ip from any to any'.
> 
>  > limit {src-addr | src-port | dst-addr | dst-port} N
>  >               The firewall will only allow N connections with the same 
>  >               set of parameters as specified in the rule.
> 
> Yes, for this rule.  It still needs to be applied to an allow or deny
> (or forward, divert etc, anything that terminates the search). 
> 
>  >       To limit the number of connections a user can open you can use the 
>  > following type of rules:
>  >             ipfw add allow tcp from my-net/24 to any setup limit src-addr 10
>  >             ipfw add allow tcp from any to me setup limit src-addr 4
> 
> Yes.  Notice that these are allow rules, so the search terminates when
> successfully matched.  It is assumed you'll later have rule/s denying
> what you've not allowed.  True, this is not stated with every example. 
> 

>  > I'm assuming the packet gets silently dropped when the limit is 
>  > overloaded but gets acted upon otherwise due to the stateful "limit" 
>  > behaviour (keep-state in disguise). Just do a "skipto" when there's a 
>  > state entry and that's it. And that's why the counter grows for 
>  > established connections too, even though there's a "setup" modifier.
> 
> Can't tell without seeing your whole ruleset, but now that you know that
> the skipto rule has NOT dropped the setup packets that don't match that
> rule (including those exceeding the src-addr limit), I suspect you'll
> find another rule has allowed them, on some other condition, later on.
> 

Wrong: the implied "check-state" done by the "limit" lets the connection 
through (i.e. performs the action) iff there's state recorded for it 
(src-addr+src-port+dst-addr+dst-port). If however it's a SYN packet 
incoming and the number of current states is trying to cross the limit, 
the SYN packet is implicitly dropped and the search terminates.

This is not to say that I completely understand the things going on when 
the connections start building up (different timeouts?) but the above 
conclusion is based on what simulation has shown. The whole ruleset fits 
on one screen, there's an "allow ip from any to any" in the end, so I'm 
pretty sure I'm not crazy :-)

>  > As for the problem, it seems to me that all this noise is because of 
>  > different timeouts in ipfw and TCP layer/whatever. The dynamic state 
>  > entry for a connection expires while netstat -na still show the 
>  > connection as ESTABLISHED, or, worse, the state entry is still there but 
>  > the corresponding connection is in some half-closed state (FIN_WAIT_2, 
>  > CLOSE_WAIT, LAST_ACK). The first case allows many more connections than 
>  > "limit", while the second case won't let many good clients connect due 
>  > to their buggy browsers not closing connections and letting the count 
>  > build up. Could this be it?
> 
> I don't believe so.  They can only have been established in the first
> place if the setup packet has been, somewhere in your ruleset, allowed.
> 

Yup. Then, after setting up the connections, the state times out earlier 
than the actual connection shown by netstat! Gotta play a bit more with 
the *_lifetime sysctls... And yes (answering to someone else on the 
list), net.inet.ip.fw.dyn_keepalive is on: I don't tend to mess with the 
default values of things I don't understand or care about... only what's 
absolutely necessary.

> Here it seems they're allowed (at least the ones from x.x.x.x/x) by the
> fwd at 401 which has no 'setup' constraint, and will fwd both setup AND
> established packets from x.x.x.x/x .. other rules, y and z, presumably.
> 
> Replaying .. trying not to do quite so much in one rule, but given you
> can't just 'allow' here, since you want to run your fwd rules later: 
> 
>  > 00350 skipto 401 tcp from x.x.x.x/x,y.y.y.y/y,z.z.z.z/z to any dst-port \
>  >       80 in via if0 setup limit src-addr 10
> 
>    00350 skipto 370 tcp from ${thatmob} to any dst-port 80 in via if0
>    00360 skipto 401 ip from any to any   # bit clunky, but !(all that)
> 
>    00370 skipto 401 tcp from any to any setup limit src-addr 10  # goodies
>    00380 deny tcp from any to any                           # else baddies
> 
>  > 00401 fwd local.ip.ad.dr,8080 tcp from x.x.x.x/x to any dst-port 80
>  > ... the rest fwd...

Rule 380 is good for capturing bogus or late-coming connection packets 
(when state entry has already expired). Once again, its use for denying 
over-limit connection attempts is debatable as "limit" will already have 
done that.

> 
> FWIW: not only have I never used limit src-addr, but neither forward
> with keep-state rules, so I could be talking ${hit} .. caveat bloggor.
> 
> Cheers, Ian
> 
> 

I should've read the mail backwards :-) Then please don't pay any 
attention to what I wrote.



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?45D9D25E.1050007>