Can ipfw be used to limit concurrent requests from an IP?
smithi at nimnet.asn.au
Sat May 28 14:28:12 UTC 2016
In freebsd-questions Digest, Vol 625, Issue 7, Message: 3
On Fri, 27 May 2016 20:34:56 +0100 Will Squire <will_squire at hotmail.co.uk> wrote:
(please wrap lines < 80 columns if possible)
> Can ipfw limit the number requests in a given amount of time from a
> specific IP?
> To contextualise, if an IP sends requests in high concurrency (let's
> say 50 a second) can ipfw either block requests the exceed a
> threshold for that second (lets say the threshold is 20, 30 would be
> blocked), or ban/deny the given IP for exceeding a threshold?
Not as such. If you know the specific IP address (or range, or subnet)
you can use stateful rules with 'limit' instead of 'keep-state' to limit
the maximum number of concurrent connections to the port/s configured in
a given rule; see ipfw(8). You cauld use a table of addresses to block
or limit rather than hard-coding them into rule/s.
While this is very useful for avoiding DoS of any particular service, it
does not allow you to specify a rate, nor time limit, nor (directly) to
block an IP address that's exceeding the given number of connections.
> The aim is to lessen strain under DoS attacks, specifically for HTTP.
> The system is using Apache and mod_evasive has been added and tested,
> but it is not functioning correctly.
I haven't used (nor heard of) mod_evasive so can't comment on that, but
limiting the total number of connections open to a given service can
certainly mitigate the effect of such DoS attacks.
You could of course use /etc/inetd.conf (aka TCPwrappers) to limit
connections in just the ways you want, though I'm not sure starting HTTP
connections in that way is recommended these days. I use if for FTP and
POP3 connections, which works very well, thus:
sola# grep -v '#' /etc/inetd.conf
ftp stream tcp nowait/7/3 root /usr/libexec/ftpd ftpd -dll -S
pop3 stream tcp nowait/7/4 root /usr/local/libexec/qpopper qpopper -s -T 120
See inetd(1), particularly re the inetd.conf setting:
The above example limits pop3 connections to 7 children and 4
connections per IP per minute. Excess connections are logged to
/var/log/messages (and console.log if enabled) thus:
May 21 12:31:59 sola inetd: pop3 from 18.104.22.168 exceeded counts/min (limit 4/min)
May 21 14:21:51 sola inetd: pop3 from 22.214.171.124 exceeded counts/min (limit 4/min)
May 21 14:21:52 sola inetd: pop3 from 126.96.36.199 exceeded counts/min (limit 4/min)
May 21 14:26:40 sola inetd: pop3 from 188.8.131.52 exceeded counts/min (limit 4/min)
May 21 15:34:53 sola inetd: pop3 from 184.108.40.206 exceeded counts/min (limit 4/min)
May 21 16:26:56 sola inetd: pop3 from 220.127.116.11 exceeded counts/min (limit 4/min)
You could run a script to tail messages hunting for such lines, then add
the IP to a table if you want; for example I run a script that instantly
bans GET requests for certain strings to any of a number of webservers.
I also tend to check logs and hand-add naughty nets such as the above to
a block table, never to be seen again ..
I also use not dissimilar connection limits to sendmail's MTA, but
that's done in sendmail's own configuration.
Others may know better ways to deal specifically with HTTP connections?
> (P.S. The freebsd-ipfw list seems to be for development of the
> technology only, so asking this here. Please let me know if this
> isn?t the case)
It's usually fairly low volume and noone seems to mind usage questions,
though the developers usually tend to let these go by.
More information about the freebsd-questions