Add ncp-app for prometheus (system) metrics

* metrics.{sh,cfg}: Implement ncp-app for prometheus (system) metrics

letsencrypts.sh, nc-nextcloud.sh, nextcloud.conf.sh: Introduce templating/generator concept to allow multiple ncp apps to edit the same file without conflicts

library.sh: Add convenience function find_app_param

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* letsencrypt.sh: Remove commented code

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.cfg: Deactivate by default

- Add title, description and remove TODO entries

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.sh: Restart apache after enabling proxy_http

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* update.sh: Update ncp-templates directory during updates

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* update.sh: Copy ncp-templates directory, not just its content

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.sh,update.sh: Disable metrics in docker for now

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.sh: Disable prometheus-node-exporter via systemctl

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.sh: Move apache mod configuration to updates

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.cfg: Remove invalid parameter type

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.sh: Create /etc/default/prometheus-node-exporter via heredoc

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* nextcloud.conf.sh: Prevent template parsing error if metrics.sh is disabled (i.e. on docker)

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* metrics.cfg: Add info directing users to my preconfigured ncp dashboard

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* Various fixes

- metrics.sh: Fix is_active function always returning 1
- metrics.sh: Fix apache2 reload potentially interrupting web ui
- nc-nextcloud.sh: exit if nextcloud.conf templating fails
- various readability and code style improvements

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* letsencrypt.sh: Use consistent return codes in tmpl_letsencrypt_domain

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* nextcloud.conf.sh: Remove obsolete return code escape

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* nextcloud.conf.sh: Ensure that the snakeoil self-signed cert exists before enabling it

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>

* updates/1.36.4.sh: Reload apache in the background instead of restarting it blockingly

Signed-off-by: Tobias K <6317548+theCalcaholic@users.noreply.github.com>
This commit is contained in:
Tobias Knöppler 2021-08-02 23:12:56 +02:00 committed by GitHub
parent 4300e30d78
commit b8a990e264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 258 additions and 37 deletions

View File

@ -175,30 +175,13 @@ EOF
## SET APACHE VHOST
echo "Setting up Apache..."
cat > /etc/apache2/sites-available/nextcloud.conf <<'EOF'
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
DocumentRoot /var/www/nextcloud
CustomLog /var/log/apache2/nc-access.log combined
ErrorLog /var/log/apache2/nc-error.log
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
</VirtualHost>
<Directory /var/www/nextcloud/>
Options +FollowSymlinks
AllowOverride All
<IfModule mod_dav.c>
Dav off
</IfModule>
LimitRequestBody 0
SSLRenegBufferSize 10486000
</Directory>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
</IfModule>
</IfModule>
EOF
bash /usr/local/etc/nextcloud.conf.sh > /etc/apache2/sites-available/nextcloud.conf || {
echo "ERROR: An error occured while generating the nextcloud apache2 config. Attempting safe mode..."
bash /usr/local/etc/nextcloud.conf.sh --defaults > /etc/apache2/sites-available/nextcloud.conf || {
echo "ERROR: Safe mode templating failed as well. Nextcloud will not work."
exit 1
}
}
a2ensite nextcloud
cat > /etc/apache2/sites-available/000-default.conf <<'EOF'

View File

@ -9,7 +9,7 @@
ncdir=/var/www/nextcloud
vhostcfg=/etc/apache2/sites-available/nextcloud.conf
nc_vhostcfg=/etc/apache2/sites-available/nextcloud.conf
vhostcfg2=/etc/apache2/sites-available/ncp.conf
letsencrypt=/usr/bin/letsencrypt
@ -18,6 +18,16 @@ is_active()
[[ $( find /etc/letsencrypt/live/ -maxdepth 0 -empty | wc -l ) == 0 ]]
}
tmpl_letsencrypt_domain() {
(
. /usr/local/etc/library.sh
if is_active
then
find_app_param letsencrypt DOMAIN
fi
)
}
install()
{
cd /etc || return 1
@ -48,11 +58,6 @@ configure()
[[ "$DOMAIN" == "" ]] && { echo "empty domain"; return 1; }
# Configure Apache
grep -q ServerName $vhostcfg && \
sed -i "s|ServerName .*|ServerName $DOMAIN|" $vhostcfg || \
sed -i "/DocumentRoot/aServerName $DOMAIN" $vhostcfg
# Do it
local domain_string=""
for domain in $DOMAIN $OTHER_DOMAIN; do
@ -94,9 +99,7 @@ EOF
chmod +x /etc/letsencrypt/renewal-hooks/deploy/ncp
# Configure Apache
sed -i "s|SSLCertificateFile.*|SSLCertificateFile /etc/letsencrypt/live/$DOMAIN_LOWERCASE/fullchain.pem|" $vhostcfg
sed -i "s|SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/letsencrypt/live/$DOMAIN_LOWERCASE/privkey.pem|" $vhostcfg
bash /usr/local/etc/ncp-templates/nextcloud.conf.sh > ${nc_vhostcfg}
sed -i "s|SSLCertificateFile.*|SSLCertificateFile /etc/letsencrypt/live/$DOMAIN_LOWERCASE/fullchain.pem|" $vhostcfg2
sed -i "s|SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/letsencrypt/live/$DOMAIN_LOWERCASE/privkey.pem|" $vhostcfg2

78
bin/ncp/SYSTEM/metrics.sh Normal file
View File

@ -0,0 +1,78 @@
#!/bin/bash
is_active() {
systemctl is-active -q prometheus-node-exporter || return 0
return 1
}
tmpl_metrics_enabled() {
(
. /usr/local/etc/library.sh
local param_active="$(find_app_param metrics.sh ACTIVE)"
[[ "$param_active" == yes ]] || exit 1
)
}
install() {
# Subshell to return on failure instead of exiting (due to set -e)
(
set -e
cat > /etc/default/prometheus-node-exporter <<'EOF'
ARGS="--collector.filesystem.ignored-mount-points=\"^/(dev|proc|run|sys|mnt|var/log|var/lib/docker)($|/)\""
EOF
apt_install prometheus-node-exporter
# TODO: Docker support?
systemctl disable prometheus-node-exporter
service prometheus-node-exporter stop
)
}
configure() {
if [[ "$ACTIVE" != yes ]]
then
bash /usr/local/etc/ncp-templates/nextcloud.conf.sh --defaults > /etc/apache2/sites-available/nextcloud.conf
systemctl disable prometheus-node-exporter
service prometheus-node-exporter stop
else
[[ -n "$USER" ]] || {
echo "ERROR: User can not be empty!" >&2
return 1
}
[[ -n "$PASSWORD" ]] || {
echo "ERROR: Password can not be empty!" >&2
return 1
}
[[ ${#PASSWORD} -ge 10 ]] || {
echo "ERROR: Password must be at least 10 characters long!" >&2
return 1
}
local htpasswd_file="/usr/local/etc/metrics.htpasswd"
rm -f "${htpasswd_file}"
echo "$PASSWORD" | htpasswd -ciB "${htpasswd_file}" metrics
bash /usr/local/etc/ncp-templates/nextcloud.conf.sh > /etc/apache2/sites-available/nextcloud.conf || {
echo "An unexpected error occurred while configuring apache. Rolling back..." >&2
bash /usr/local/etc/ncp-templates/nextcloud.conf.sh --defaults > /etc/apache2/sites-available/nextcloud.conf
return 1
}
systemctl enable prometheus-node-exporter
service prometheus-node-exporter start
echo "Metric endpoint enabled. You can test it at https://nextcloudpi.local/metrics/system (or under your NC domain under the same path)"
fi
echo "Apache Test:"
apache2ctl -t
bash -c "sleep 2 && service apache2 reload" &>/dev/null &
}

View File

@ -8,10 +8,9 @@
# More at ownyourbits.com
#
NCPCFG=${NCPCFG:-/usr/local/etc/ncp.cfg}
CFGDIR=/usr/local/etc/ncp-config.d
BINDIR=/usr/local/bin/ncp
BINDIR=/usr/local/bin/ncp
export NCPCFG=${NCPCFG:-/usr/local/etc/ncp.cfg}
export CFGDIR=/usr/local/etc/ncp-config.d
export BINDIR=/usr/local/bin/ncp
command -v jq &>/dev/null || {
apt-get update
@ -112,6 +111,40 @@ function run_app()
run_app_unsafe "$script"
}
function find_app_param_num()
{
local script="${1?}"
local param_id="${2?}"
local ncp_app="$(basename "$script" .sh)"
local cfg_file="$CFGDIR/$ncp_app.cfg"
[[ -f "$cfg_file" ]] && {
local cfg="$( cat "$cfg_file" )"
local len="$(jq '.params | length' <<<"$cfg")"
for (( i = 0 ; i < len ; i++ )); do
local p_id="$(jq -r ".params[$i].id" <<<"$cfg")"
if [[ "${param_id}" == "${p_id}" ]]
then
echo "$i"
return 0
fi
done
}
return 1
}
find_app_param()
{
local script="${1?}"
local param_id="${2?}"
local ncp_app="$(basename "$script" .sh)"
local cfg_file="$CFGDIR/$ncp_app.cfg"
local p_num="$(find_app_param_num "$script" "$param_id")" || return 1
jq -r ".params[$p_num].value" < "$cfg_file"
}
# receives a script file, no security checks
function run_app_unsafe()
{

View File

@ -0,0 +1,28 @@
{
"id": "metrics",
"name": "System Metrics, that can be collected by an external server",
"title": "System Metrics",
"description": "Prometheus (https://prometheus.io) compatible metrics for things like, CPU/memory/disk usage etc.",
"info": "In order to use these metrics, you will need to setup at least an external Prometheus instance. You can find a quick and easy way to start at https://github.com/theCalcaholic/ncp-monitoring-dashboard",
"infotitle": "External service required",
"params": [
{
"id": "ACTIVE",
"name": "Active",
"value": "no",
"type": "bool"
},
{
"id": "USER",
"name": "Metrics User",
"value": "metrics",
"suggest": "metrics"
},
{
"id": "PASSWORD",
"name": "Metrics Password",
"value": "",
"type": "password"
}
]
}

View File

@ -0,0 +1,87 @@
#! /bin/bash
set -e
source /usr/local/etc/library.sh
source "${BINDIR}/NETWORKING/letsencrypt.sh"
if [[ "$DOCKERBUILD" == 1 ]]
then
source "${BINDIR}/SYSTEM/metrics.sh"
else
tmpl_metrics_enabled(){ return 1; }
fi
echo "### DO NOT EDIT! THIS FILE HAS BEEN AUTOMATICALLY GENERATED. CHANGES WILL BE OVERWRITTEN ###"
echo ""
cat <<EOF
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
DocumentRoot /var/www/nextcloud
EOF
LETSENCRYPT_DOMAIN="$(tmpl_letsencrypt_domain)"
if [[ "$1" != "--defaults" ]] && [[ -n "$LETSENCRYPT_DOMAIN" ]]
then
echo " ServerName ${LETSENCRYPT_DOMAIN}"
LETSENCRYPT_CERT_BASE_PATH="/etc/letsencrypt/live/${LETSENCRYPT_DOMAIN,,}"
LETSENCRYPT_CERT_PATH="${LETSENCRYPT_CERT_BASE_PATH}/fullchain.pem"
LETSENCRYPT_KEY_PATH="${LETSENCRYPT_CERT_BASE_PATH}/privkey.pem"
else
# Make sure the default snakeoil cert exists
[ -f /etc/ssl/certs/ssl-cert-snakeoil.pem ] || make-ssl-cert generate-default-snakeoil --force-overwrite
unset LETSENCRYPT_DOMAIN
fi
cat <<EOF
CustomLog /var/log/apache2/nc-access.log combined
ErrorLog /var/log/apache2/nc-error.log
SSLEngine on
SSLCertificateFile ${LETSENCRYPT_CERT_PATH:-/etc/ssl/certs/ssl-cert-snakeoil.pem}
SSLCertificateKeyFile ${LETSENCRYPT_KEY_PATH:-/etc/ssl/private/ssl-cert-snakeoil.key}
EOF
if [[ "$1" != "--defaults" ]] && tmpl_metrics_enabled
then
cat <<EOF
SSLProxyEngine on
<Location /metrics/system>
ProxyPass http://localhost:9100/metrics
Order deny,allow
Allow from all
AuthType Basic
AuthName "Metrics"
AuthUserFile /usr/local/etc/metrics.htpasswd
<RequireAll>
<RequireAny>
Require host localhost
Require user metrics
</RequireAny>
</RequireAll>
</Location>
EOF
fi
cat <<EOF
</VirtualHost>
<Directory /var/www/nextcloud/>
Options +FollowSymlinks
AllowOverride All
<IfModule mod_dav.c>
Dav off
</IfModule>
LimitRequestBody 0
SSLRenegBufferSize 10486000
</Directory>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
</IfModule>
</IfModule>
EOF
apache2ctl -t

View File

@ -36,6 +36,7 @@ nc-zram
SSH
fail2ban
NFS
metrics
"
# better use a designated container
@ -63,6 +64,7 @@ mkdir -p "$CONFDIR"
cp -r bin/* /usr/local/bin/
find etc -maxdepth 1 -type f ! -path etc/ncp.cfg -exec cp '{}' /usr/local/etc \;
cp -n etc/ncp.cfg /usr/local/etc
cp -r etc/ncp-templates /usr/local/etc/
# install new entries of ncp-config and update others
for file in etc/ncp-config.d/*; do

7
updates/1.36.4.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -e
# Required for the reverse proxy of the metrics app
a2enmod proxy_http
bash -c "sleep 2 && service apache2 reload" &>/dev/null &