aboutsummaryrefslogtreecommitdiff
path: root/net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.initd
blob: eb5b79b7b08fb4ab0715b08b4754d63baa3b5980 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#!/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 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

	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;

	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/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_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
}