utils/filtron.sh: add script to install filtron middleware

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
Markus Heiser 2020-01-08 19:21:07 +01:00
parent 28dacee288
commit 4139c63d23
5 changed files with 307 additions and 5 deletions

View file

@ -78,6 +78,7 @@ test: test.pep8 test.unit test.sh test.robot
test.sh:
shellcheck -x utils/lib.sh
shellcheck -x utils/filtron.sh
test.pep8: pyenvinstall
$(PY_ENV_ACT); ./manage.sh pep8_check

214
utils/filtron.sh Executable file
View file

@ -0,0 +1,214 @@
#!/usr/bin/env bash
# -*- coding: utf-8; mode: sh -*-
# shellcheck disable=SC2119
# shellcheck source=utils/lib.sh
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
# ----------------------------------------------------------------------------
# config
# ----------------------------------------------------------------------------
FILTRON_ETC="/etc/filtron"
SERVICE_NAME="filtron"
SERVICE_USER="${SERVICE_NAME}"
SERVICE_HOME="/home/${SERVICE_USER}"
SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
# shellcheck disable=SC2034
SERVICE_GROUP="${SERVICE_USER}"
GO_ENV="${SERVICE_HOME}/.go_env"
GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
GO_TAR=$(basename "$GO_PKG_URL")
# ----------------------------------------------------------------------------
usage(){
# ----------------------------------------------------------------------------
# shellcheck disable=SC1117
cat <<EOF
usage:
$(basename "$0") shell
$(basename "$0") install [all|user]
$(basename "$0") remove [all]
$(basename "$0") activate [server]
$(basename "$0") deactivate [server]
shell - start interactive shell with user ${SERVICE_USER}
install user - add service user '$SERVICE_USER' at $SERVICE_HOME
EOF
[ ! -z ${1+x} ] && echo -e "$1"
}
main(){
rst_title "$SERVICE_NAME" part
local _usage="ERROR: unknown or missing $1 command $2"
case $1 in
--source-only) ;;
-h|--help) usage ;;
shell)
sudo_or_exit
interactive_shell
;;
install)
sudo_or_exit
case $2 in
all) install_all ;;
user) assert_user ;;
*) usage "$_usage"; exit 42;;
esac ;;
remove)
sudo_or_exit
case $2 in
all) remove_all;;
user) remove_user ;;
*) usage "$_usage"; exit 42;;
esac ;;
activate)
sudo_or_exit
case $2 in
server) activate_server ;;
*) usage "$_usage"; exit 42;;
esac ;;
deactivate)
sudo_or_exit
case $2 in
server) deactivate_server ;;
*) usage "$_usage"; exit 42;;
esac ;;
*) usage "ERROR: unknown or missing command $1"; exit 42;;
esac
}
install_all() {
rst_title "Install $SERVICE_NAME (service)"
assert_user
install_go
install_filtron
install_server
}
remove_all() {
rst_title "De-Install $SERVICE_NAME (service)"
remove_server
remove_user
rm -rf "$FILTRON_ETC"
wait_key
}
install_server() {
rst_title "Install System-D Unit ${SERVICE_NAME}.service ..." section
install_template ${SERVICE_SYSTEMD_UNIT} root root 644
wait_key
activate_server
}
remove_server() {
if ! ask_yn "Do you really want to deinstall $SERVICE_NAME?"; then
return
fi
deactivate_server
rm "${SERVICE_SYSTEMD_UNIT}"
}
activate_server () {
rst_title "Activate $SERVICE_NAME (service)" section
tee_stderr <<EOF | bash 2>&1 | prefix_stdout
systemctl enable $SERVICE_NAME.service
systemctl restart $SERVICE_NAME.service
EOF
tee_stderr <<EOF | bash 2>&1 | prefix_stdout
systemctl status $SERVICE_NAME.service
EOF
wait_key
}
deactivate_server () {
rst_title "De-Activate $SERVICE_NAME (service)" section
echo
tee_stderr <<EOF | bash 2>&1 | prefix_stdout
systemctl stop $SERVICE_NAME.service
systemctl disable $SERVICE_NAME.service
EOF
wait_key
}
assert_user() {
rst_title "user $SERVICE_USER" section
echo
tee_stderr 1 <<EOF | bash | prefix_stdout
sudo -H adduser --shell /bin/bash --system --home $SERVICE_HOME --group --gecos 'Filtron' $SERVICE_USER
sudo -H usermod -a -G shadow $SERVICE_USER
groups $SERVICE_USER
EOF
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
export SERVICE_HOME
echo "export SERVICE_HOME=$SERVICE_HOME"
cat > "$GO_ENV" <<EOF
export GOPATH=\$HOME/go-apps
export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
EOF
echo "Environment $GO_ENV has been setup."
tee_stderr <<EOF | sudo -i -u $SERVICE_USER
grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
EOF
}
remove_user() {
rst_title "Drop $SERVICE_USER HOME" section
if ask_yn "Do you really want to drop $SERVICE_USER home folder?"; then
userdel -r -f "$SERVICE_USER"
else
rst_para "Leave HOME folder $(du -sh "$SERVICE_HOME") unchanged."
fi
}
interactive_shell(){
echo "// exit with STRG-D"
sudo -H -u ${SERVICE_USER} -i
}
_service_prefix="$SERVICE_USER@$(hostname) -->| "
install_go(){
rst_title "Install Go in user's HOME" section
rst_para "download and install go binary .."
cache_download "${GO_PKG_URL}" "${GO_TAR}"
tee_stderr 0.1 <<EOF | sudo -i -u "$SERVICE_USER" | prefix_stdout "$_service_prefix"
echo \$PATH
echo \$GOPATH
mkdir -p \$HOME/local
rm -rf \$HOME/local/go
tar -C \$HOME/local -xzf ${CACHE}/${GO_TAR}
EOF
echo
sudo -i -u "$SERVICE_USER" <<EOF | prefix_stdout
! which go >/dev/null && echo "Go Installation not found in PATH!?!"
which go >/dev/null && go version && echo "congratulations -- Go installation OK :)"
EOF
wait_key
}
install_filtron() {
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" | prefix_stdout "$_service_prefix"
go get -v -u github.com/asciimoo/filtron 2>&1
EOF
install_template "$FILTRON_ETC/rules.json" root root 644
}
# ----------------------------------------------------------------------------
main "$@"
# ----------------------------------------------------------------------------

View file

@ -19,7 +19,7 @@ if [[ -z "$CACHE" ]]; then
fi
if [[ -z "$SYSTEMD_UNITS" ]]; then
SYSTEMD_UNITS="/lib/systemd/system/"
SYSTEMD_UNITS="/lib/systemd/system"
fi
sudo_or_exit() {
@ -253,9 +253,9 @@ install_template() {
#
# install_template --no-eval /etc/updatedb.conf root root 644
local do_eval=0
local do_eval=1
if [[ "$1" == "--no-eval" ]]; then
do_eval=1; shift
do_eval=0; shift
fi
local dst="${1}"
local owner=${2-$(id -un)}
@ -286,6 +286,8 @@ install_template() {
fi
fi
mkdir -p "$(dirname "${dst}")"
if [[ -f "${dst}" ]] ; then
info_msg "file ${dst} allready exists on this host"
choose_one _reply "choose next step with file $dst" \
@ -296,7 +298,7 @@ install_template() {
"replace file")
info_msg "install: ${template_file}"
sudo -H install -v -o "${owner}" -g "${group}" -m "${chmod}" \
"${template_file}" "${dst}"
"${template_file}" "${dst}" | prefix_stdout
;;
"leave file unchanged")
;;
@ -309,7 +311,7 @@ install_template() {
else
info_msg "install: ${template_file}"
sudo -H install -v -o "${owner}" -g "${group}" -m "${chmod}" \
"${template_file}" "${dst}"
"${template_file}" "${dst}" | prefix_stdout
fi
}

View file

@ -0,0 +1,56 @@
[
{
"name": "api limit",
"interval": 60,
"limit": 1000,
"filters": ["Path=^/api"],
"aggregations": ["Path"],
"actions": [
{"name": "block"}
],
"subrules": [
{
"name": "drop put",
"interval": 60,
"limit": 100,
"filters": ["Method=PUT"],
"aggregations": ["Header:X-Forwarded-For"],
"actions": [
{"name": "shell",
"params": {"cmd": "iptables -A INPUT -s %v -j DROP", "args": ["Header:X-Forwarded-For"]}}
]
}
]
},
{
"name": "log'n'block rss",
"interval": 300,
"limit": 2500,
"filters": ["Path=^/$", "GET:format=rss"],
"actions": [
{"name": "log"},
{"name": "block"}
]
},
{
"name": "log rule",
"filters": ["Path=/"],
"actions": [ {"name": "log"} ],
"subrules": [
{
"name": "block missing accept-language",
"filters": ["!Header:Accept-Language"],
"actions": [
{"name": "block"}
]
},
{
"name": "block curl",
"filters": ["Header:User-Agent=[Cc]url"],
"actions": [
{"name": "block"}
]
}
]
}
]

View file

@ -0,0 +1,29 @@
[Unit]
Description=${SERVICE_NAME}
After=syslog.target
After=network.target
[Service]
Type=simple
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${SERVICE_HOME}
ExecStart=${SERVICE_HOME}/go-apps/bin/filtron -rules ${FILTRON_RULES}
Restart=always
Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME}
# Some distributions may not support these hardening directives. If you cannot
# start the service due to an unknown option, comment out the ones not supported
# by your version of systemd.
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target