From acddc2050a7a1f3a5a7627c568c4e26ad92354df Mon Sep 17 00:00:00 2001 From: "S. Brusch" Date: Mon, 30 Jan 2023 19:26:59 +0100 Subject: [PATCH] crowdsec-firewall-bouncer: update to 0.0.25 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Update crowdsec-firewall-bouncer to latest upstream release version 0.0.25 Signed-off-by: S. Brusch Maintainer: Kerma Gérald Run tested: ipq40xx/generic, Fritzbox 4040, Openwrt 22.03.3 Rework: - now based on uci config file - create nftables tables and chains in initd script --- net/crowdsec-firewall-bouncer/Makefile | 33 +-- .../files/crowdsec-firewall-bouncer.defaults | 23 -- .../files/crowdsec-firewall-bouncer.firewall | 4 - .../files/crowdsec-firewall-bouncer.initd | 246 +++++++++++++++--- .../files/crowdsec.config | 15 ++ .../001-fix_config_iptables_chains.patch | 9 - 6 files changed, 228 insertions(+), 102 deletions(-) delete mode 100644 net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.defaults delete mode 100644 net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.firewall create mode 100644 net/crowdsec-firewall-bouncer/files/crowdsec.config delete mode 100644 net/crowdsec-firewall-bouncer/patches/001-fix_config_iptables_chains.patch diff --git a/net/crowdsec-firewall-bouncer/Makefile b/net/crowdsec-firewall-bouncer/Makefile index 52318f5630..b8ea0b18e9 100644 --- a/net/crowdsec-firewall-bouncer/Makefile +++ b/net/crowdsec-firewall-bouncer/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=crowdsec-firewall-bouncer -PKG_VERSION:=0.0.21 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=0.0.25 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/crowdsecurity/cs-firewall-bouncer/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=c92e02085c4c8481009a46ba80374329d102a45933fd0fd2164901954331923e +PKG_HASH:=15ffaa38644215a4cf5e5d5d3a6fc6f0800057bc55d4bd25778d8e952679506e PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE @@ -47,8 +47,7 @@ endef define Package/crowdsec-firewall-bouncer $(call Package/crowdsec-firewall-bouncer/Default) - DEPENDS:=@(PACKAGE_iptables||PACKAGE_nftables) \ - $(GO_ARCH_DEPENDS) + DEPENDS:=$(GO_ARCH_DEPENDS) endef define Package/golang-crowdsec-firewall-bouncer-dev @@ -65,7 +64,7 @@ define Package/crowdsec-firewall-bouncer/Default/description crowdsec-firewall-bouncer will fetch new and old decisions from a CrowdSec API to add them in a blocklist used by supported firewalls. - You must install iptables+ipset or nftables. + You must install nftables. endef define Package/crowdsec-firewall-bouncer/description @@ -83,29 +82,15 @@ endef define Package/crowdsec-firewall-bouncer/install $(call GoPackage/Package/Install/Bin,$(1)) - $(INSTALL_DIR) $(1)/etc/crowdsec/bouncers - $(INSTALL_DATA) \ - $(GO_PKG_BUILD_DIR)/src/$(GO_PKG)/config/crowdsec-firewall-bouncer.yaml \ - $(1)/etc/crowdsec/bouncers + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/crowdsec.config $(1)/etc/config/crowdsec $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) \ - ./files/crowdsec-firewall-bouncer.initd \ - $(1)/etc/init.d/crowdsec-firewall-bouncer - - $(INSTALL_DIR) $(1)/etc - $(INSTALL_BIN) \ - ./files/crowdsec-firewall-bouncer.firewall \ - $(1)/etc/firewall.cs - - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) \ - ./files/crowdsec-firewall-bouncer.defaults \ - $(1)/etc/uci-defaults/99_crowdsec-firewall-bouncer + $(INSTALL_BIN) ./files/crowdsec-firewall-bouncer.initd $(1)/etc/init.d/crowdsec-firewall-bouncer endef define Package/crowdsec-firewall-bouncer/conffiles -/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml +/etc/config/crowdsec endef $(eval $(call GoBinPackage,crowdsec-firewall-bouncer)) diff --git a/net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.defaults b/net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.defaults deleted file mode 100644 index 64d69a2f11..0000000000 --- a/net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.defaults +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -CONFIG=/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml -## Gen&ConfigApiKey -if grep -q "{API_KEY}" "$CONFIG"; then - SUFFIX=`tr -dc A-Za-z0-9 -START=99 USE_PROCD=1 + +START=99 + NAME=crowdsec-firewall-bouncer PROG=/usr/bin/cs-firewall-bouncer -CONFIG=/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml -BACKEND=iptables VARCONFIGDIR=/var/etc/crowdsec/bouncers VARCONFIG=/var/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml -FW_BACKEND="iptables" + +CONFIGURATION=crowdsec + +TABLE="crowdsec" +TABLE6="crowdsec6" service_triggers() { procd_add_reload_trigger crowdsec-firewall-bouncer + procd_add_config_trigger "config.change" "crowdsec" /etc/init.d/crowdsec-firewall-bouncer reload } -init_config() { - ## CheckFirewall - iptables="true" - which iptables > /dev/null - FW_BACKEND="" - if [[ $? != 0 ]]; then - echo "iptables is not present" - iptables="false" - else - FW_BACKEND="iptables" - echo "iptables found" - fi +init_yaml() { - nftables="true" - which nft > /dev/null - if [[ $? != 0 ]]; then - echo "nftables is not present" - nftables="false" - else - FW_BACKEND="nftables" - echo "nftables found" - fi + local section="$1" - if [ "$nftables" = "true" -a "$iptables" = "true" ]; then - echo "Found nftables(default) and iptables..." - fi + local update_frequency + local log_level + local api_url + local api_key + local ipv6 + local deny_action + local deny_log + local log_prefix + local log_max_size + local log_max_backups + local log_max_age + local ipv4 + local input_chain_name + local input6_chain_name - if [ "$FW_BACKEND" = "iptables" ]; then - which ipset > /dev/null - if [[ $? != 0 ]]; then - echo "ipset not found, install it !" - fi - fi - BACKEND=$FW_BACKEND + config_get update_frequency $section update_frequency '10s' + config_get log_level $section log_level 'info' + config_get api_url $section api_url "http://127.0.0.1:8080" + config_get api_key $section api_key "API_KEY" + config_get_bool ipv6 $section ipv6 '1' + config_get deny_action $section deny_action "drop" + config_get_bool deny_log $section deny_log '0' + config_get log_prefix $section log_prefix "crowdsec: " + config_get log_max_size $section log_max_size '100' + config_get log_max_backups $section log_max_backups '3' + config_get log_max_age $section log_max_age '30' + config_get_bool ipv4 $section ipv4 '1' + config_get input_chain_name $section input_chain_name "input" + config_get input6_chain_name $section input6_chain_name "input" # Create tmp dir & permissions if needed if [ ! -d "${VARCONFIGDIR}" ]; then mkdir -m 0755 -p "${VARCONFIGDIR}" fi; - cp $CONFIG $VARCONFIG + cat > $VARCONFIG <<-EOM + mode: nftables + pid_dir: /var/run/ + update_frequency: $update_frequency + daemonize: true + log_mode: file + log_dir: /var/log/ + log_level: $log_level + log_compression: true + log_max_size: $log_max_size + log_max_backups: $log_max_backups + log_max_age: $log_max_age + api_url: $api_url + api_key: $api_key + insecure_skip_verify: true + disable_ipv6: boolnot($ipv6) + deny_action: $deny_action + deny_log: bool($deny_log) + supported_decisions_type: + - ban + #to change log prefix + deny_log_prefix: "$log_prefix" + #to change the blacklists name + blacklists_ipv4: crowdsec-blacklists + blacklists_ipv6: crowdsec6-blacklists + #type of ipset to use + ipset_type: nethash + #if present, insert rule in those chains + iptables_chains: + - INPUT + # - FORWARD + # - DOCKER-USER + ## nftables + nftables: + ipv4: + enabled: bool($ipv4) + set-only: true + table: $TABLE + chain: $input_chain_name + ipv6: + enabled: bool($ipv6) + set-only: true + table: $TABLE6 + chain: $input6_chain_name + # packet filter + pf: + # an empty disables the anchor + anchor_name: "" + prometheus: + enabled: false + listen_addr: 127.0.0.1 + listen_port: 60601 + EOM - sed -i "s,^\(\s*mode\s*:\s*\).*\$,\1$BACKEND," $VARCONFIG + sed -i "s/bool(1)/true/g" $VARCONFIG + sed -i "s/bool(0)/false/g" $VARCONFIG + sed -i "s/boolnot(1)/false/g" $VARCONFIG + sed -i "s/boolnot(0)/true/g" $VARCONFIG + sed -i "s,^\(\s*api_url\s*:\s*\).*\$,\1$api_url," $VARCONFIG + sed -i "s,^\(\s*api_key\s*:\s*\).*\$,\1$api_key," $VARCONFIG +} + +init_nftables() { + + local section="$1" + + local priority + local deny_action + local deny_log + local log_prefix + local ipv4 + local ipv6 + local filter_input + local filter_forward + local input_chain_name + local forward_chain_name + local input6_chain_name + local forward6_chain_name + local interface + local log_term="" + + config_get priority $section priority "4" + config_get deny_action $section deny_action "drop" + config_get_bool deny_log $section deny_log '0' + config_get log_prefix $section log_prefix "crowdsec: " + config_get_bool ipv4 $section ipv4 '1' + config_get_bool ipv6 $section ipv6 '1' + config_get_bool filter_input $section filter_input '1' + config_get_bool filter_forward $section filter_forward '1' + config_get input_chain_name $section input_chain_name "input" + config_get forward_chain_name $section forward_chain_name "forward" + config_get input6_chain_name $section input6_chain_name "input" + config_get forward6_chain_name $section forward6_chain_name "forward" + config_get interface $section interface 'eth1' + + if [ "$deny_log" -eq "1" ] ; then + local log_term="log prefix \"${log_prefix}\"" + fi + + local interface="${interface// /, }" + + #as of kernel 3.18 we can delete a table without need to flush it + nft delete table ip crowdsec 2>/dev/null + nft delete table ip6 crowdsec6 2>/dev/null + + if [ "$ipv4" -eq "1" ] ; then + + nft add table ip crowdsec + nft add set ip crowdsec crowdsec-blacklists '{ type ipv4_addr; flags timeout; }' + + if [ "$filter_input" -eq "1" ] ; then + nft add chain ip "$TABLE" $input_chain_name "{ type filter hook input priority $priority; policy accept; }" + nft add rule ip "$TABLE" $input_chain_name iifname { $interface } ct state new ip saddr @crowdsec-blacklists ${log_term} counter $deny_action + fi + if [ "$filter_forward" -eq "1" ] ; then + nft add chain ip "$TABLE" $forward_chain_name "{ type filter hook forward priority $priority; policy accept; }" + nft add rule ip "$TABLE" $forward_chain_name iifname { $interface } ct state new ip saddr @crowdsec-blacklists ${log_term} counter $deny_action + fi + fi + + if [ "$ipv6" -eq "1" ] ; then + + nft add table ip6 crowdsec6 + nft add set ip6 crowdsec6 crowdsec6-blacklists '{ type ipv6_addr; flags timeout; }' + + if [ "$filter_input" -eq "1" ] ; then + nft add chain ip6 "$TABLE6" $input6_chain_name "{ type filter hook input priority $priority; policy accept; }" + nft add rule ip6 "$TABLE6" $input6_chain_name iifname { $interface } ct state new ip6 saddr @crowdsec6-blacklists ${log_term} counter $deny_action + fi + if [ "$filter_forward" -eq "1" ] ; then + nft add chain ip6 "$TABLE6" $forward6_chain_name "{ type filter hook forward priority $priority; policy accept; }" + nft add rule ip6 "$TABLE6" $forward6_chain_name iifname { $interface } ct state new ip6 saddr @crowdsec6-blacklists ${log_term} counter $deny_action + fi + fi +} + +run_bouncer() { + + local section="$1" + + local enabled + config_get_bool enabled $section enabled 0 + + if [ "$enabled" -eq "1" ] ; then + + init_yaml "$section" + init_nftables "$section" + + procd_open_instance + procd_set_param command "$PROG" -c "$VARCONFIG" + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance + fi } start_service() { - init_config - procd_open_instance - procd_set_param command "$PROG" -c "$VARCONFIG" - procd_close_instance + config_load "${CONFIGURATION}" + config_foreach run_bouncer bouncer +} + +service_stopped() { + + rm $VARCONFIG + + nft delete table ip crowdsec 2>/dev/null + nft delete table ip6 crowdsec6 2>/dev/null } + + diff --git a/net/crowdsec-firewall-bouncer/files/crowdsec.config b/net/crowdsec-firewall-bouncer/files/crowdsec.config new file mode 100644 index 0000000000..ad43bd1193 --- /dev/null +++ b/net/crowdsec-firewall-bouncer/files/crowdsec.config @@ -0,0 +1,15 @@ +config bouncer + option enabled '0' + option ipv4 '1' + option ipv6 '1' + option api_url 'http://localhost:8080/' + option api_key '' + option update_frequency '10s' + option deny_action 'drop' + option deny_log '0' + option log_prefix 'crowdsec: ' + option log_level 'info' + option filter_input '1' + option filter_forward '1' + list interface 'eth1' + diff --git a/net/crowdsec-firewall-bouncer/patches/001-fix_config_iptables_chains.patch b/net/crowdsec-firewall-bouncer/patches/001-fix_config_iptables_chains.patch deleted file mode 100644 index f129ad89f1..0000000000 --- a/net/crowdsec-firewall-bouncer/patches/001-fix_config_iptables_chains.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/config/crowdsec-firewall-bouncer.yaml -+++ b/config/crowdsec-firewall-bouncer.yaml -@@ -20,5 +20,5 @@ supported_decisions_types: - #if present, insert rule in those chains - iptables_chains: - - INPUT --# - FORWARD -+ - FORWARD - # - DOCKER-USER -- 2.30.2