#!/bin/sh /etc/rc.common USE_PROCD=1 START=99 NAME=crowdsec-firewall-bouncer PROG=/usr/bin/cs-firewall-bouncer VARCONFIGDIR=/var/etc/crowdsec/bouncers VARCONFIG=/var/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml 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_yaml() { local section="$1" local set_only local hook_priority 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 chain_name local chain6_name local retry_initial_connect config_get hook_priority $section priority "4" 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 chain_name $section chain_name "crowdsec-chain" config_get chain6_name $section chain6_name "crowdsec6-chain" config_get_bool retry_initial_connect $section retry_initial_connect '1' # Create tmp dir & permissions if needed if [ ! -d "${VARCONFIGDIR}" ]; then mkdir -m 0755 -p "${VARCONFIGDIR}" fi; 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 retry_initial_connect: bool($retry_initial_connect) 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: false table: $TABLE chain: $chain_name priority: $hook_priority ipv6: enabled: bool($ipv6) set-only: false table: $TABLE6 chain: $chain6_name priority: $hook_priority nftables_hooks: - input - forward # packet filter pf: # an empty string disables the anchor anchor_name: "" prometheus: enabled: false listen_addr: 127.0.0.1 listen_port: 60601 EOM 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 hook_priority local deny_action local deny_log local log_prefix local ipv4 local ipv6 local filter_input local filter_forward local chain_name local chain6_name local interface local log_term="" config_get hook_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 chain_name $section chain_name "crowdsec-chain" config_get chain6_name $section chain6_name "crowdsec6-chain" 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" $chain_name-input "{ type filter hook input priority $hook_priority; policy accept; }" nft add rule ip "$TABLE" $chain_name-input ct state established,related accept nft add rule ip "$TABLE" $chain_name-input iifname != { $interface } accept fi if [ "$filter_forward" -eq "1" ] ; then nft add chain ip "$TABLE" $chain_name-forward "{ type filter hook forward priority $hook_priority; policy accept; }" nft add rule ip "$TABLE" $chain_name-forward ct state established,related accept nft add rule ip "$TABLE" $chain_name-forward iifname != { $interface } accept 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" $chain6_name-input "{ type filter hook input priority $hook_priority; policy accept; }" nft add rule ip6 "$TABLE6" $chain6_name-input ct state established,related accept nft add rule ip6 "$TABLE6" $chain6_name-input iifname != { $interface } accept fi if [ "$filter_forward" -eq "1" ] ; then nft add chain ip6 "$TABLE6" $chain6_name-forward "{ type filter hook forward priority $hook_priority; policy accept; }" nft add rule ip6 "$TABLE6" $chain6_name-forward ct state established,related accept nft add rule ip6 "$TABLE6" $chain6_name-forward iifname != { $interface } accept 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_set_param nice 10 if [ -x "/sbin/ujail" ]; then procd_add_jail cs-bouncer log procd_add_jail_mount $VARCONFIG procd_add_jail_mount_rw /var/log/ procd_set_param no_new_privs 1 fi procd_close_instance fi } start_service() { 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 }