on master help sign in
utils/filtron.sh: add script to install filtron middleware

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>

commit4139c63d23a1f4cc427eb428bcff0594c395c1c5 authorMarkus Heiser <markus.heiser@darmarit.de> dateWed 8 Jan 2020, 19:21 (7 years ago) parent28dacee
5 files changed+307−5
Makefile+1 utils/filtron.sh+214 utils/lib.sh+7−5 utils/templates/etc/filtron/rules.json+56 utils/templates/lib/systemd/system/filtron.service+29
Makefile+1
@@ -78,6 +78,7 @@ test: test.pep8 test.unit test.sh test.robot
7878
7979test.sh:
8080 shellcheck -x utils/lib.sh
81+ shellcheck -x utils/filtron.sh
8182
8283test.pep8: pyenvinstall
8384 $(PY_ENV_ACT); ./manage.sh pep8_check
utils/filtron.shnew file+214
@@ -0,0 +1,214 @@
1+#!/usr/bin/env bash
2+# -*- coding: utf-8; mode: sh -*-
3+# shellcheck disable=SC2119
4+
5+# shellcheck source=utils/lib.sh
6+source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
7+
8+# ----------------------------------------------------------------------------
9+# config
10+# ----------------------------------------------------------------------------
11+
12+FILTRON_ETC="/etc/filtron"
13+
14+SERVICE_NAME="filtron"
15+SERVICE_USER="${SERVICE_NAME}"
16+SERVICE_HOME="/home/${SERVICE_USER}"
17+SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
18+
19+# shellcheck disable=SC2034
20+SERVICE_GROUP="${SERVICE_USER}"
21+
22+GO_ENV="${SERVICE_HOME}/.go_env"
23+GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
24+GO_TAR=$(basename "$GO_PKG_URL")
25+
26+# ----------------------------------------------------------------------------
27+usage(){
28+# ----------------------------------------------------------------------------
29+
30+ # shellcheck disable=SC1117
31+ cat <<EOF
32+
33+usage:
34+
35+ $(basename "$0") shell
36+ $(basename "$0") install [all|user]
37+ $(basename "$0") remove [all]
38+ $(basename "$0") activate [server]
39+ $(basename "$0") deactivate [server]
40+
41+shell - start interactive shell with user ${SERVICE_USER}
42+install user - add service user '$SERVICE_USER' at $SERVICE_HOME
43+
44+EOF
45+ [ ! -z ${1+x} ] && echo -e "$1"
46+}
47+
48+main(){
49+ rst_title "$SERVICE_NAME" part
50+
51+ local _usage="ERROR: unknown or missing $1 command $2"
52+
53+ case $1 in
54+ --source-only) ;;
55+ -h|--help) usage ;;
56+
57+ shell)
58+ sudo_or_exit
59+ interactive_shell
60+ ;;
61+ install)
62+ sudo_or_exit
63+ case $2 in
64+ all) install_all ;;
65+ user) assert_user ;;
66+ *) usage "$_usage"; exit 42;;
67+ esac ;;
68+ remove)
69+ sudo_or_exit
70+ case $2 in
71+ all) remove_all;;
72+ user) remove_user ;;
73+ *) usage "$_usage"; exit 42;;
74+ esac ;;
75+ activate)
76+ sudo_or_exit
77+ case $2 in
78+ server) activate_server ;;
79+ *) usage "$_usage"; exit 42;;
80+ esac ;;
81+ deactivate)
82+ sudo_or_exit
83+ case $2 in
84+ server) deactivate_server ;;
85+ *) usage "$_usage"; exit 42;;
86+ esac ;;
87+ *) usage "ERROR: unknown or missing command $1"; exit 42;;
88+ esac
89+}
90+
91+install_all() {
92+ rst_title "Install $SERVICE_NAME (service)"
93+ assert_user
94+ install_go
95+ install_filtron
96+ install_server
97+}
98+
99+remove_all() {
100+ rst_title "De-Install $SERVICE_NAME (service)"
101+ remove_server
102+ remove_user
103+ rm -rf "$FILTRON_ETC"
104+ wait_key
105+}
106+
107+install_server() {
108+ rst_title "Install System-D Unit ${SERVICE_NAME}.service ..." section
109+ install_template ${SERVICE_SYSTEMD_UNIT} root root 644
110+ wait_key
111+ activate_server
112+}
113+
114+remove_server() {
115+ if ! ask_yn "Do you really want to deinstall $SERVICE_NAME?"; then
116+ return
117+ fi
118+ deactivate_server
119+ rm "${SERVICE_SYSTEMD_UNIT}"
120+}
121+
122+
123+activate_server () {
124+ rst_title "Activate $SERVICE_NAME (service)" section
125+ tee_stderr <<EOF | bash 2>&1 | prefix_stdout
126+systemctl enable $SERVICE_NAME.service
127+systemctl restart $SERVICE_NAME.service
128+EOF
129+ tee_stderr <<EOF | bash 2>&1 | prefix_stdout
130+systemctl status $SERVICE_NAME.service
131+EOF
132+ wait_key
133+}
134+
135+deactivate_server () {
136+ rst_title "De-Activate $SERVICE_NAME (service)" section
137+ echo
138+ tee_stderr <<EOF | bash 2>&1 | prefix_stdout
139+systemctl stop $SERVICE_NAME.service
140+systemctl disable $SERVICE_NAME.service
141+EOF
142+ wait_key
143+}
144+
145+assert_user() {
146+ rst_title "user $SERVICE_USER" section
147+ echo
148+ tee_stderr 1 <<EOF | bash | prefix_stdout
149+sudo -H adduser --shell /bin/bash --system --home $SERVICE_HOME --group --gecos 'Filtron' $SERVICE_USER
150+sudo -H usermod -a -G shadow $SERVICE_USER
151+groups $SERVICE_USER
152+EOF
153+ SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
154+ export SERVICE_HOME
155+ echo "export SERVICE_HOME=$SERVICE_HOME"
156+
157+ cat > "$GO_ENV" <<EOF
158+export GOPATH=\$HOME/go-apps
159+export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
160+EOF
161+ echo "Environment $GO_ENV has been setup."
162+
163+ tee_stderr <<EOF | sudo -i -u $SERVICE_USER
164+grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
165+EOF
166+}
167+
168+remove_user() {
169+ rst_title "Drop $SERVICE_USER HOME" section
170+ if ask_yn "Do you really want to drop $SERVICE_USER home folder?"; then
171+ userdel -r -f "$SERVICE_USER"
172+ else
173+ rst_para "Leave HOME folder $(du -sh "$SERVICE_HOME") unchanged."
174+ fi
175+}
176+
177+interactive_shell(){
178+ echo "// exit with STRG-D"
179+ sudo -H -u ${SERVICE_USER} -i
180+}
181+
182+_service_prefix="$SERVICE_USER@$(hostname) -->| "
183+
184+install_go(){
185+ rst_title "Install Go in user's HOME" section
186+
187+ rst_para "download and install go binary .."
188+ cache_download "${GO_PKG_URL}" "${GO_TAR}"
189+
190+ tee_stderr 0.1 <<EOF | sudo -i -u "$SERVICE_USER" | prefix_stdout "$_service_prefix"
191+echo \$PATH
192+echo \$GOPATH
193+mkdir -p \$HOME/local
194+rm -rf \$HOME/local/go
195+tar -C \$HOME/local -xzf ${CACHE}/${GO_TAR}
196+EOF
197+ echo
198+ sudo -i -u "$SERVICE_USER" <<EOF | prefix_stdout
199+! which go >/dev/null && echo "Go Installation not found in PATH!?!"
200+which go >/dev/null && go version && echo "congratulations -- Go installation OK :)"
201+EOF
202+ wait_key
203+}
204+
205+install_filtron() {
206+ tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" | prefix_stdout "$_service_prefix"
207+go get -v -u github.com/asciimoo/filtron 2>&1
208+EOF
209+ install_template "$FILTRON_ETC/rules.json" root root 644
210+}
211+
212+# ----------------------------------------------------------------------------
213+main "$@"
214+# ----------------------------------------------------------------------------
utils/lib.sh+7−5
@@ -19,7 +19,7 @@ if [[ -z "$CACHE" ]]; then
1919fi
2020
2121if [[ -z "$SYSTEMD_UNITS" ]]; then
22− SYSTEMD_UNITS="/lib/systemd/system/"
22+ SYSTEMD_UNITS="/lib/systemd/system"
2323fi
2424
2525sudo_or_exit() {
@@ -253,9 +253,9 @@ install_template() {
253253 #
254254 # install_template --no-eval /etc/updatedb.conf root root 644
255255
256− local do_eval=0
256+ local do_eval=1
257257 if [[ "$1" == "--no-eval" ]]; then
258− do_eval=1; shift
258+ do_eval=0; shift
259259 fi
260260 local dst="${1}"
261261 local owner=${2-$(id -un)}
@@ -286,6 +286,8 @@ install_template() {
286286 fi
287287 fi
288288
289+ mkdir -p "$(dirname "${dst}")"
290+
289291 if [[ -f "${dst}" ]] ; then
290292 info_msg "file ${dst} allready exists on this host"
291293 choose_one _reply "choose next step with file $dst" \
@@ -296,7 +298,7 @@ install_template() {
296298 "replace file")
297299 info_msg "install: ${template_file}"
298300 sudo -H install -v -o "${owner}" -g "${group}" -m "${chmod}" \
299− "${template_file}" "${dst}"
301+ "${template_file}" "${dst}" | prefix_stdout
300302 ;;
301303 "leave file unchanged")
302304 ;;
@@ -309,7 +311,7 @@ install_template() {
309311 else
310312 info_msg "install: ${template_file}"
311313 sudo -H install -v -o "${owner}" -g "${group}" -m "${chmod}" \
312− "${template_file}" "${dst}"
314+ "${template_file}" "${dst}" | prefix_stdout
313315 fi
314316
315317}
utils/templates/etc/filtron/rules.jsonnew file+56
@@ -0,0 +1,56 @@
1+[
2+ {
3+ "name": "api limit",
4+ "interval": 60,
5+ "limit": 1000,
6+ "filters": ["Path=^/api"],
7+ "aggregations": ["Path"],
8+ "actions": [
9+ {"name": "block"}
10+ ],
11+ "subrules": [
12+ {
13+ "name": "drop put",
14+ "interval": 60,
15+ "limit": 100,
16+ "filters": ["Method=PUT"],
17+ "aggregations": ["Header:X-Forwarded-For"],
18+ "actions": [
19+ {"name": "shell",
20+ "params": {"cmd": "iptables -A INPUT -s %v -j DROP", "args": ["Header:X-Forwarded-For"]}}
21+ ]
22+ }
23+ ]
24+ },
25+ {
26+ "name": "log'n'block rss",
27+ "interval": 300,
28+ "limit": 2500,
29+ "filters": ["Path=^/$", "GET:format=rss"],
30+ "actions": [
31+ {"name": "log"},
32+ {"name": "block"}
33+ ]
34+ },
35+ {
36+ "name": "log rule",
37+ "filters": ["Path=/"],
38+ "actions": [ {"name": "log"} ],
39+ "subrules": [
40+ {
41+ "name": "block missing accept-language",
42+ "filters": ["!Header:Accept-Language"],
43+ "actions": [
44+ {"name": "block"}
45+ ]
46+ },
47+ {
48+ "name": "block curl",
49+ "filters": ["Header:User-Agent=[Cc]url"],
50+ "actions": [
51+ {"name": "block"}
52+ ]
53+ }
54+ ]
55+ }
56+]
utils/templates/lib/systemd/system/filtron.servicenew file+29
@@ -0,0 +1,29 @@
1+[Unit]
2+
3+Description=${SERVICE_NAME}
4+After=syslog.target
5+After=network.target
6+
7+[Service]
8+
9+Type=simple
10+User=${SERVICE_USER}
11+Group=${SERVICE_GROUP}
12+WorkingDirectory=${SERVICE_HOME}
13+ExecStart=${SERVICE_HOME}/go-apps/bin/filtron -rules ${FILTRON_RULES}
14+
15+Restart=always
16+Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME}
17+
18+# Some distributions may not support these hardening directives. If you cannot
19+# start the service due to an unknown option, comment out the ones not supported
20+# by your version of systemd.
21+
22+ProtectSystem=full
23+PrivateDevices=yes
24+PrivateTmp=yes
25+NoNewPrivileges=true
26+
27+[Install]
28+
29+WantedBy=multi-user.target