Rate limiting with UFW: setting limits

45,835

Solution 1

UFW is designed to be "uncomplicated," which in this case means you don't have control over the particulars of the rate to which connections are limited. If you want to dig into the Python source of UFW, you could find out how to tweak it. The appropriate information is (on my Ubuntu 10.04 system) in /usr/share/pyshared/ufw/backend_iptables.py

Setting the timing issue aside, therefore, here are some answers to your rapid-fire questions at the end.

  1. Assuming 10.10.10.0/24 is your local network, this applies the default limiting rule to port 80/tcp incoming:

    ufw limit from any to 10.10.10.0/24 port http comment 'limit web'
    
  2. and 3. Rate limiting is not turned on by default. To add it to every (destination) port except the range you want, use this rule. Note that rules (even with ranges) are atomic units and cannot be split up. You cannot, for example, add a rule for any port, then delete a (nonexistent) rule for a particular range to remove it. limit is not an acceptable argument to ufw default, either.

    ufw limit from any to any port 0:29999,30006:65535
    

Solution 2

As mentioned on the previous post you can customize the user.rules. I need my smtp connection rate limit of up to 12 connections in 6 seconds. I added a rule as shown below first. Note: this adds a limit rule allowing 6 in 30 sec by default

ufw limit smtp

and I edited the /lib/ufw/user.rules (I keep a custom copy of this file with lot of other tweaks) as shown below ...

### tuple ### limit tcp 25 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 25 -m state --state NEW -m recent --set
-A ufw-user-input -p tcp --dport 25 -m state --state NEW -m recent --update --seconds 6 --hitcount 12 -j ufw-user-limit
-A ufw-user-input -p tcp --dport 25 -j ufw-user-limit-accept

Solution 3

Rate limit can be changed on the UFW rules file which can be found /lib/ufw/user.rules.

By default there are no limits enabled for all ports. you should add every port manually or by editing user.rules file.

Solution 4

It is worthwhile to point out possible unintended consequences of using ufw's LIMIT feature.

Suppose one placed a blanket limit on port 22/tcp as the first ufw rule:

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     LIMIT IN    Anywhere                  
...

with the assumption that any connections operating under the limit could still be filtered by following ufw rules and finally the default policy of "deny(incoming)".

At least for ufw 0.35, that assumption would be wrong. In fact the LIMIT IN logic immediately accepts any input not rejected by the limit criterion.

In psuedocode, the LIMIT logic is

if CONDITION then DENY else ACCEPT

whereas other ufw rules seem to have logic:

if CONDITION then (DENY|ACCEPT) else continue to next rule.

I personally found that to be unexpected behavior for ufw LIMIT, which I only discovered by unexpectedly finding many port 22 login attempts in the system log file which should have never happened due to filtered by other ufw rules.

Details of behavior confirmation

The relevant lines of iptables code inserted by ufw are as follows:

-A ufw-user-input -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 30 --hitcount 6 --name DEFAULT --mask 255.255.255.255 --rsource -j ufw-user-limit
-A ufw-user-input -p tcp -m tcp --dport 22 -j ufw-user-limit-accept
-A ufw-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable
-A ufw-user-limit-accept -j ACCEPT

The above listing can be created with

iptables -S | grep ufw-user-limit

The first two lines are consecutive in ufw-user-input which can be confirmed with

iptables -S | grep ufw-user-input
Share:
45,835

Related videos on Youtube

Tom
Author by

Tom

Updated on September 18, 2022

Comments

  • Tom
    Tom over 1 year

    UFW's man page mentions that it can setup iptables rate limiting for me:

    ufw supports connection rate limiting, which is useful for protecting against brute-force login attacks. ufw will deny connections if an IP address has attempted to initiate 6 or more connections in the last 30 seconds. See http://www.debian-administration.org/articles/187 for details. Typical usage is:

         ufw limit ssh/tcp
    

    Unfortunately this is all the documentation that I could find. I would like to stick with UFW, and not use more complicated iptables commands (to keep things "uncomplicated").

    How would I use ufw to limit all incoming (so not outgoing) traffic on port 80 to 20 connections per 30 seconds? How would I disable rate limiting for ports 30000 to 30005? Is rate limiting enabled by default for all ports?

  • Tom
    Tom about 12 years
    Does this mean that the rate can never be set?
  • bonsaiviking
    bonsaiviking about 12 years
    Not without hacking the source, at least not for UFW 0.30pre1-0ubuntu2, which is current for Ubuntu 10.04. From the look of things in the current source, that hasn't changed. You can, however put iptables rules into /etc/ufw/after.rules (or /etc/ufw/before.rules), and those will be used as well. See man ufw-framework for more info.
  • Otto Kanellis
    Otto Kanellis about 5 years
    I found user.rules in /etc/ufw