使用 nftables 和 IPv6 的 Fail2ban

使用 nftables 和 IPv6 的 Fail2ban

编辑:根据 Marco 的建议,添加了额外的 .conf 文件并稍微更改了措辞


我在跑Fail2ban v0.10它应该支持IPv6。

我已经设置了根据这些说明使用 nftables 进行 Fail2ban,但我使用了 nftables 的“inet”系列而不是 ip 系列,因为我想允许 IPv6 流量进入我的服务器。

该服务器可通过 IPv6 访问,并且据我所知,我的防火墙(nftables)似乎配置正确(表 inet 过滤器)。

然而,我写这篇文章的原因是“table inet fail2ban”,在我看来,Fail2ban 只读取 IPv4 日志,并阻止有问题的 IPv4 主机。

我读得对吗?如果对,有人知道如何让 Fail2ban 也能处理 IPv6 流量吗?我知道 Fail2ban v0.10 更新日志指出并非所有禁令都支持 IPv6,但我似乎找不到列表。

我也欢迎提供可以找到该信息的链接,因为我自己似乎找不到。

我只包含了重复的 jail 配置,因为我认为如果我可以让 jail 与 IPv6 一起工作,我就可以对其他的 jail 做同样的事情,如果我的这个假设有误,请告诉我 :)


我的 nftables 规则集:

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
        ct state { related, established} accept
        ct state invalid drop
        iifname "lo" accept
        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept
        tcp dport ssh accept
        tcp dport http accept
        tcp dport https accept
        limit rate 5/minute burst 5 packets counter packets 972 bytes 56710 log prefix " denied: " level debug
        drop
    }

    chain forward {
        type filter hook forward priority 0; policy accept;
        drop
    }

    chain output {
        type filter hook output priority 0; policy accept;
        accept
    }
}

table inet fail2ban {
    set f2b-sshd {
        type ipv4_addr
    }

    set f2b-nginx-botsearch {
        type ipv4_addr
    }

    set f2b-recidive {
        type ipv4_addr
    }

    chain INPUT {
        type filter hook input priority 100; policy accept;
        ip protocol hopopt-reserved ip saddr @f2b-recidive drop
        tcp dport { http, https} ip saddr @f2b-nginx-botsearch drop
        tcp dport { ssh} ip saddr @f2b-sshd drop
    }
}

/etc/nftables/fail2ban.conf

#!/usr/sbin/nft -f

table inet fail2ban {
        chain INPUT {
                type filter hook input priority 100;
        }
}

/etc/nftables.conf

#!/usr/bin/nft -f

table inet filter {
  chain input {
    type filter hook input priority 0;

    ct state {established, related} accept

    ct state invalid drop

    iifname lo accept

    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept

    tcp dport ssh accept

    tcp dport http accept
    tcp dport https accept

    limit rate 5/minute burst 5 packets counter packets 0 bytes 0 log prefix " denied: " level debug

    drop
  }
  chain forward {
    type filter hook forward priority 0;
    drop
  }
  chain output {
    type filter hook output priority 0;
    accept
  }

}

include "/etc/nftables/fail2ban.conf"

/etc/fail2ban/action.d/nftables-common.local

[Init]
nftables_family = inet
nftables_table  = fail2ban

blocktype       = drop

nftables_set_prefix =

/etc/fail2ban/jail.local

[INCLUDES]

before = paths-arch.conf

[DEFAULT]

ignorecommand =

bantime  = 1h

findtime  = 10m

maxretry = 5

usedns = warn

logencoding = auto

enabled = false

filter = %(__name__)s

protocol = tcp

chain = INPUT

port = 0:65535

fail2ban_agent = Fail2Ban/%(fail2ban_version)s

banaction = nftables-multiport
banaction_allports = nftables-allports

action_mw = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
            %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
action_mwl = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
             %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
action_xarf = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath=%(logpath)s, port="%(port)s"]
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

action_blocklist_de  = blocklist_de[email="%(sender)s", service=%(filter)s, apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]

action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]

action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]

action_abuseipdb = abuseipdb

action = %(action_)s


[sshd]
enabled = true
mode    = normal
filter  = sshd[mode=%(mode)s]
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s


[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = %(nginx_error_log)s
maxretry = 2

[recidive]
enabled = true
logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime  = 1w
findtime = 1d
maxretry  = 3
protocol  = 0-255

/etc/fail2ban/filter.d/recidive.conf

[INCLUDES]

before = common.conf

[Definition]

_daemon = fail2ban\.actions\s*

_jailname = recidive

failregex = ^(%(__prefix_line)s| %(_daemon)s%(__pid_re)s?:\s+)NOTICE\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$

ignoreregex =

[Init]

journalmatch = _SYSTEMD_UNIT=fail2ban.service PRIORITY=5

/etc/fail2ban/filter.d/common.conf

[DEFAULT]

_daemon = \S*

__pid_re = (?:\[\d+\])

__daemon_re = [\[\(]?%(_daemon)s(?:\(\S+\))?[\]\)]?:?

__daemon_extra_re = \[ID \d+ \S+\]

__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:?)

__kernel_prefix = kernel: \[ *\d+\.\d+\]

__hostname = \S+

__md5hex = (?:[\da-f]{2}:){15}[\da-f]{2}

__bsd_syslog_verbose = <[^.]+\.[^.]+>

__vserver = @vserver_\S+

__date_ambit = (?:\[\])

__prefix_line = %(__date_ambit)s?\s*(?:%(__bsd_syslog_verbose)s\s+)?(?:%(__hostname)s\s+)?(?:%(__kernel_prefix)s\s+)?(?:%(__vserver)s\s+)$

__pam_auth = pam_unix

datepattern = {^LN-BEG}

答案1

这可能是这个错误固定的在 v0.10.1 中

答案2

对于我来说,在默认存储库中的 Debian bullseye 1.0.2 版本上,这似乎运行良好。

“inet”类型表对于任一地址系列都有正确的规则。“ip”特定于 IPv4,或“ip6”特定于 IPv6。在这种情况下,“inet”允许两种类型的规则。

在我的系统上,如果某个 IPv6 地址被禁止,则会将一组新地址添加到 fail2ban 表中,称为“addr6-set-sshd”(用于 ssh)。并且会将一条规则添加到 f2b-chain 中,以阻止 IPv6 地址被禁止。例如,当我执行“nft list ruleset”时,会出现以下表

table inet f2b-table {
    set addr-set-sshd {
        type ipv4_addr
        elements = { <blocked_v4_ips> }
    }

    set addr6-set-sshd {
        type ipv6_addr
        elements = { <blocked_v6_ips> }
    }

    chain f2b-chain {
        type filter hook input priority filter - 1; policy accept;
        tcp dport 22 ip saddr @addr-set-sshd drop
        tcp dport 22 ip6 saddr @addr6-set-sshd drop
    }
}

令人困惑的是,如果 fail2ban 没有条目可放入其中,则不会创建丢弃规则和集合。这是有道理的,也是最理想的。但这意味着如果没有被阻止的 IPv6 地址,您将看不到那里的条目。

由于 IPv6 地址空间非常庞大,因此扫描其中的开放端口比 IPv4 要少得多。因此,您完全没有尝试通过 v6 触发创建,这并非不可能。

如果您运行“fail2ban-client status”并在禁止列表中看到 IPv6 地址,则在执行“nft list ruleset”时应该会看到该条目。否则,它预计会丢失,并且可能有效,但您可能需要测试失败以确保万无一失。

相关内容