UFW 默认 limit 修改

ufw 官方介绍

  1. design
  2. README

UFW 代码托管在launchpad,相比 github 并不那么便利. checkout 代码: git clone git clone https://git.launchpad.net/ufw

ufw 使用指南

  1. How to Setup UFW Firewall on Ubuntu and Debian
  2. A Guide to the Uncomplicated Firewall (UFW) for Linux
  3. Comparing and contrasting Uncomplicated Firewall and FirewallD

其中最后一篇提到,On the other hand, ufws hard-coded six-connections-per-30-seconds is non-configurable.,而这个只是说 ufw limit(ufw-user-limit) 生成的 iptables 命令。 并不是说默认的 limit(ufw-not-local 链中的 limit)。

先看一下 ufw 的控制流:

INPUT ->
  ufw-before-logging-input ->
  ufw-before-input ->
    ufw-user-input ->
      ufw-user-logging-input (rule specific) ->
  ufw-after-input ->
  ufw-after-logging-input ->
  ufw-reject-input -> return to INPUT

OUTPUT ->
  ufw-before-logging-output ->
  ufw-before-output ->
    ufw-user-output ->
      ufw-user-logging-output (rule specific) ->
  ufw-after-output ->
  ufw-after-logging-output ->
  ufw-reject-output -> return to OUTPUT

FORWARD ->
  ufw-before-logging-forward ->
  ufw-before-forward ->
    ufw-user-forward ->
      ufw-user-logging-forward (not used) ->
  ufw-after-forward ->
  ufw-after-logging-forward ->
  ufw-reject-forward -> return to FORWARD

ufw control flow

内置 limit 限制

默认执行 limit 限制策略

  1. 非本地的链接(ufw-not-local)
  2. INVALID 的链接(通过 conntrack 检查)
  3. 其他未匹配规则的链接(先记录日志,然后走默认策略 deny)
$ sudo iptables -S|grep limit|grep -v ufw-user-limit|grep -v -F '[UFW ALLOW]'
-A ufw-logging-deny -m conntrack --ctstate INVALID -m limit --limit 10/sec --limit-burst 100 -j RETURN
-A ufw-logging-deny -m limit --limit 10/sec --limit-burst 100 -j LOG --log-prefix "[UFW BLOCK] "

-A ufw-not-local -m limit --limit 10/sec --limit-burst 100 -j ufw-logging-deny

-A ufw-after-logging-input -m limit --limit 10/sec --limit-burst 100 -j LOG --log-prefix "[UFW BLOCK] "

默认的 limit,对我来说太低,修改如下: sudo diff {/usr/lib/python3/dist-packages/ufw/backend_iptables.py{,.bak}

620c620
<         limit_args = '-m limit --limit 600/min --limit-burst 100'
---
>         limit_args = '-m limit --limit 3/min --limit-burst 10'
1299c1299
<         limit_args = ['-m', 'limit', '--limit', '600/min', '--limit-burst', '100']
---
>         limit_args = ['-m', 'limit', '--limit', '3/min', '--limit-burst', '10']

sudo diff /etc/ufw/before.rules{,.bak}

79,80c77
< #-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
< -A ufw-not-local -m limit --limit 600/min --limit-burst 100 -j ufw-logging-deny
---
> -A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny

用户 limit 限制

$ sudo iptables -S|grep -- -j|grep ufw-user-limit
# 可以看出没有任何规则跳到ufw-user-limit
-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
$ sudo ufw limit smtp
Rule added
$ sudo iptables -S|grep -- -j|grep ufw-user-limit
# 下面这一条规则直接跳到了ufw-user-limit
-A ufw-user-input -p tcp -m tcp --dport 25 -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 25 -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

常用命令

  • 查看当前被 BLOCK 的地址:sudo grep -i 'UFW BLOCK' /var/log/syslog|grep -o -E 'SRC=[0-9.]+'| uniq -c|sort -n | tail
  • 查看 ufw-not-local:sudo iptables -S ufw-not-local
  • 查看用户自定义规则 sudo ufw show added
  • 检查依赖是否满足:sudo /usr/share/ufw/check-requirements -h

当然,最纯粹的办法,就是卸载 ufw,直接用 iptables,iptables fundamentals, Per-IP rate limiting with iptables, Uncomplicated Firewall

Comments