summaryrefslogtreecommitdiffstats
path: root/net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.initd
blob: 33ebbb0eaef2596e0d562fd72c75c3c3c7ee30c4 (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
239
240
241
242
243
244
245
246
247
#!/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
}