crowdsecurity / cs-firewall-bouncer

Crowdsec bouncer written in golang for firewalls
MIT License
110 stars 41 forks source link

Firewalld #90

Open LtSich opened 2 years ago

LtSich commented 2 years ago

Hi,

After some test it seem that firewalld don't block IP from the IPSET if you add the IP with the ipset command.... This guy need that you add your entry with the firewall-cmd or he will just ignore everything...

Atm I have build my own bouncer to manage that, but it could be interesting to add firewalld support in the bouncer, and then just add firewalld in the mode option...

This are all the command that I use to manage my blocklist with firewalld, you will need those to adapt the bouncer : On start :

#remove ipset from firewalld
/bin/firewall-cmd --permanent --zone=drop --remove-source=ipset:crowdsec-blacklists
#remove ipset
/bin/firewall-cmd --permanent --delete-ipset=crowdsec-blacklists
#reload config
/bin/firewall-cmd --reload

#recreate ipset
/bin/firewall-cmd --permanent --new-ipset=crowdsec-blacklists --type=hash:net
#add the ipset to the drop zone on firewalld
/bin/firewall-cmd  --permanent --zone=drop --add-source=ipset:crowdsec-blacklists
#reload config
/bin/firewall-cmd --reload

After that get the full banlist with startup=true on LAPI Keep only the add, and remove all duplicate entry.

Then 2 solutions, I have made the choice to write the banlist to a tmp file, and then import that list with that command

/bin/firewall-cmd --ipset=crowdsec-blacklists --add-entries-from-file=/tmp/banlist
#save config
/bin/firewall-cmd --runtime-to-permanent

or you can just add each entry 1 by 1 :

firewall-cmd --ipset=crowdsec-blacklists --add-entry=<ip>
#save config
/bin/firewall-cmd --runtime-to-permanent

After that on each check, just get the partial banlist with startup=false on LAPI Remove duplicate entry, and here I have made the choice to write the add / del entry to 2 tmp files, and import them.

#add
/bin/firewall-cmd --ipset=crowdsec-blacklists --add-entries-from-file=/tmp/banlist_add
#del
/bin/firewall-cmd --ipset=crowdsec-blacklists --remove-entries-from-file=/tmp/banlist_del
#save
/bin/firewall-cmd --runtime-to-permanent

But you can do the same by adding / removing each ip one by one

#add 
firewall-cmd --ipset=crowdsec-blacklists --add-entry=<ip>
#del 
firewall-cmd --ipset=crowdsec-blacklists --remove-entry=<ip>
#save the configuration after that
/bin/firewall-cmd --runtime-to-permanent

On stop you can remove the ipset

#remove ipset from firewalld
/bin/firewall-cmd --permanent --zone=drop --remove-source=ipset:crowdsec-blacklists
#remove ipset
/bin/firewall-cmd --permanent --delete-ipset=crowdsec-blacklists
#reload config
/bin/firewall-cmd --reload

Note, it seem that firewalld don't like timeout. This is why on my side I clear everything on start/stop, and once / 24H I do a full reset with startup=true and remove / add the ipset...

LtSich commented 1 year ago

For information, after multiple month of using my custom bouncer to use this setup I have to point out some issue. First, when you add new decisions with /bin/firewall-cmd --ipset=crowdsec-blacklists --add-entries-from-file=/tmp/banlist_add then firewalld will clear the whole set during the time he is importing the new IP. This mean for 1 or 2s everything is open... Not nice... Acceptable when you run your bouncer once every 5min, but not if you run it every 20s...

Another point, the memory usage can grow very very fast, in this setup for firewalld. It seem that this is fixed in the most recent firewalld version, but on debian11 it's not the case atm.

Debian suggest to move to nftables / firewalld here but honestly it's not a good solution atm... And nftables have other issue (if you want to use the crowdsec-fw-bouncer-nftable), like if you want to ban a whole netrange, this fail if you have already some IP from this netrange in the set...

In the end, it seem that the good old iptables / ipset / shorewall work far better for me...