crowdsecurity / cs-firewall-bouncer

Crowdsec bouncer written in golang for firewalls
MIT License
117 stars 43 forks source link

Enhance rules created by the bouncer to respect conntrack #380

Closed ne20002 closed 3 weeks ago

ne20002 commented 1 month ago

/kind enhancement

What would you like to be added?

First of all: I like the ability to collect metrics of the bouncer.

For OpenWrt the rules as created by the bouncer in version 0.0.30 are not ideal. Most OpenWrt devices have limited power and based on the use case, that OpwnWrt (in this case) is a routing device, additional definitions for the created rules are neccessary. Until version 0.0.30 the OpenWrt bouncer package created the rules by itself running the bouncer in set-only mode. With the new approach this is still working (thank you) but lacks the features for the metrics.

I will only use ipv4 here but it's the same for ipv6. Now look at this:


root@BPI-R3-eth1:~# nft list table crowdsec
table ip crowdsec {
    set crowdsec-blacklists-CAPI {
        type ipv4_addr
        flags timeout
        elements = { 1.9.78.242 timeout 4d1h45m14s expires 4d1h36m44s280ms, 1.9.101.202 timeout 4d12h45m14s expires 4d12h36m44s340ms,
                 ...

                 223.247.218.77 timeout 2d6h45m13s expires 2d6h36m43s220ms, 223.247.218.112 timeout 5d20h45m13s expires 5d20h36m42s870ms }
    }

    set crowdsec-blacklists-lists-tor-exit-nodes {
        type ipv4_addr
        flags timeout
        elements = { 2.58.95.56 timeout 10h45m17s expires 10h36m46s560ms, 3.108.196.136 timeout 22h45m17s expires 22h36m46s560ms,
                 ...
                 217.170.201.71 timeout 10h45m17s expires 10h36m46s560ms }
    }

    set crowdsec-blacklists-fail2ban {
        type ipv4_addr
        flags timeout
        elements = { 4.246.246.232 timeout 3d6h41m31s expires 3d6h33m560ms, 13.91.180.110 timeout 10d10h16m28s expires 10d10h7m57s560ms,
                 ...
                 216.218.206.66 timeout 3d8h9m36s expires 3d8h1m5s560ms }
    }

    set crowdsec-blacklists-crowdsec {
        type ipv4_addr
        flags timeout
        elements = { 20.191.45.212 timeout 3h12m32s expires 3h4m1s560ms, 45.200.148.16 timeout 1h31m28s expires 1h22m57s560ms,
                 60.13.6.178 timeout 1h19m31s expires 1h11m560ms }
    }

    chain crowdsec-chain-input {
        type filter hook input priority filter + 4; policy accept;
        counter packets 61292 bytes 10732148
        ip saddr @crowdsec-blacklists-CAPI counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-lists-tor-exit-nodes counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-fail2ban counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-crowdsec counter packets 0 bytes 0 drop
    }

    chain crowdsec-chain-forward {
        type filter hook forward priority filter + 4; policy accept;
        counter packets 1521 bytes 96619
        ip saddr @crowdsec-blacklists-CAPI counter packets 2 bytes 84 drop
        ip saddr @crowdsec-blacklists-lists-tor-exit-nodes counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-fail2ban counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-crowdsec counter packets 0 bytes 0 drop
    }
}

This set of rules is suboptimal, because:

Even though the set lookup is fast, bypassing it if it is not neccessary is even faster.

As an example I suggest to change the rule creation for

    chain crowdsec-chain-input {
        type filter hook input priority filter + 4; policy accept;
        counter packets 61292 bytes 10732148
        ip saddr @crowdsec-blacklists-CAPI counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-lists-tor-exit-nodes counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-fail2ban counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-crowdsec counter packets 0 bytes 0 drop
    }

to this:

    chain crowdsec-chain-input {
        type filter hook input priority filter + 4; policy accept;
                ct state established,related accept comment "Allow inbound established and related flows"
                iifname not in { wan, wg1 } accept comment "Allow all internal flows"
        counter packets 61292 bytes 10732148
        ip saddr @crowdsec-blacklists-CAPI counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-lists-tor-exit-nodes counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-fail2ban counter packets 0 bytes 0 drop
        ip saddr @crowdsec-blacklists-crowdsec counter packets 0 bytes 0 drop
    }

whereas:

Why is this needed?

Needed for proper function of OpenWrt devices.

github-actions[bot] commented 1 month ago

@ne20002: Thanks for opening an issue, it is currently awaiting triage.

In the meantime, you can:

  1. Check Documentation to see if your issue can be self resolved.
  2. You can also join our Discord
Details I am a bot created to help the [crowdsecurity](https://github.com/crowdsecurity) developers manage community feedback and contributions. You can check out my [manifest file](https://github.com/crowdsecurity/cs-firewall-bouncer/blob/main/.github/governance.yml) to understand my behavior and what I can do. If you want to use this for your project, you can check out the [BirthdayResearch/oss-governance-bot](https://github.com/BirthdayResearch/oss-governance-bot) repository.
github-actions[bot] commented 1 month ago

@ne20002: There are no 'kind' label on this issue. You need a 'kind' label to start the triage process.

Details I am a bot created to help the [crowdsecurity](https://github.com/crowdsecurity) developers manage community feedback and contributions. You can check out my [manifest file](https://github.com/crowdsecurity/cs-firewall-bouncer/blob/main/.github/governance.yml) to understand my behavior and what I can do. If you want to use this for your project, you can check out the [BirthdayResearch/oss-governance-bot](https://github.com/BirthdayResearch/oss-governance-bot) repository.
ne20002 commented 1 month ago

I'm now using the new bouncer 0.0.30 in non set-only mode, the created chains and rules can be easily enhanced with the changes proposed above. It even gives more accurate numbers, now the overall count is just counting packets that are incomming on one of the wan interfaces and that really should be checked for filtering. Sadly, the additional rules needs to be applied manually after starting the bouncer process (e.g. after a reboot of the router).

This is how it looks: grafik

I believe the missing crowdsec-blacklists-crowdsec in Ipv6 is due to not have had at least a single match on any of the rules so the set is not created?

ne20002 commented 4 weeks ago

Hi @mmetc , @blotus

I have updated the OpenWrt crowdsec-firewall-bouncer package to make use of the new Crowdsec firewall bouncer. I'm happy to see that now the bouncer uses tables and chains if they have been created in advance and then adds its rules to those. With this the rules enhancement as described above can be achieved at least for the OpenWrt package.