crowdsec-firewall-bouncer: update to 0.0.25
Update crowdsec-firewall-bouncer to latest upstream release version 0.0.25 Signed-off-by: S. Brusch <ne20002@gmx.ch> Maintainer: Kerma Gérald <gandalf@gk2.net> 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
This commit is contained in:
parent
7bce2138ef
commit
b748d59e07
6 changed files with 228 additions and 102 deletions
|
@ -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))
|
||||
|
|
|
@ -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 </dev/urandom | head -c 8`
|
||||
API_KEY=`/usr/bin/cscli bouncers add crowdsec-firewall-bouncer-${SUFFIX} -o raw`
|
||||
sed -i "s,^\(\s*api_key\s*:\s*\).*\$,\1$API_KEY," $CONFIG
|
||||
else
|
||||
echo API key already registered...
|
||||
fi
|
||||
|
||||
# unfortunately, UCI doesn't provide a nice way to add an anonymous section only if it doesn't already exist
|
||||
if ! uci show firewall | grep -q firewall.cs; then
|
||||
name="$(uci add firewall include)"
|
||||
uci set "firewall.${name}.path=/etc/firewall.cs"
|
||||
uci set "firewall.${name}.enabled=1"
|
||||
uci set "firewall.${name}.reload=1"
|
||||
echo -e "Adding the following UCI config:\n $(uci changes)"
|
||||
uci commit
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
/etc/init.d/crowdsec enabled && /etc/init.d/crowdsec restart
|
||||
/etc/init.d/crowdsec-firewall-bouncer enabled && /etc/init.d/crowdsec-firewall-bouncer restart
|
||||
exit 0
|
|
@ -1,69 +1,231 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2021-2022 Gerald Kerma <gandalf@gk2.net>
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
|
15
net/crowdsec-firewall-bouncer/files/crowdsec.config
Normal file
15
net/crowdsec-firewall-bouncer/files/crowdsec.config
Normal file
|
@ -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'
|
||||
|
|
@ -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
|
Loading…
Reference in a new issue