fix: hex password generation, safe DATABASE_URL, consistent /opt/argus default
Root cause of a real production failure on the first live install
(wap-proxy, 2026-07-25): DB_PASSWORD was generated with
`openssl rand -base64 24`, which can produce '/', '+', or '=' --
docker-compose.yml then naively interpolated the raw password into
postgres://postgres:${DB_PASSWORD}@db:5432/..., and a generated
password containing '/' broke the connection string outright. The API
never became healthy; log ingestion failed completely.
- install.sh now generates with `openssl rand -hex 32` (always
[0-9a-f], can't produce this class of character). Same fix applied
everywhere else openssl-rand-base64-24 was referenced.
- docker-compose.yml no longer builds DATABASE_URL by string
interpolation -- DB_PASSWORD is passed as its own var and the API
assembles the connection string safely internally using
net/url.UserPassword (proper percent-encoding), a second,
independent layer so the installer doesn't rely on the password
generator alone. See the matching argus-appliance commit for the
Go-side change and its regression test.
- backup.sh/healthcheck.sh/restore.sh/uninstall.sh still defaulted
ARGUS_INSTALL_DIR to $HOME/argus, inconsistent with install.sh/
update.sh's own /opt/argus default (changed in an earlier commit
this session) -- confirmed live on the same install: healthcheck.sh
and uninstall.sh reported "no installation found" when run from the
real, correct directory. All five scripts now agree on /opt/argus.
Corresponding argus-appliance fix (config.go's buildDatabaseURL, v3.73.1)
already built and pushed to git-cloud.weboria.eu/weboria/argus-api.
This commit is contained in:
@@ -151,7 +151,7 @@ curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/
|
|||||||
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/docker-socket-proxy/haproxy.cfg.template -o docker-socket-proxy/haproxy.cfg.template
|
curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/docker-socket-proxy/haproxy.cfg.template -o docker-socket-proxy/haproxy.cfg.template
|
||||||
|
|
||||||
# Generate a secure database password
|
# Generate a secure database password
|
||||||
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$(openssl rand -base64 24)/" .env
|
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$(openssl rand -hex 32)/" .env
|
||||||
|
|
||||||
# ARGUS expects this network to already exist
|
# ARGUS expects this network to already exist
|
||||||
docker network create argus-network
|
docker network create argus-network
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
# ARGUS backup — dumps the database and application data (certificates,
|
# ARGUS backup — dumps the database and application data (certificates,
|
||||||
# uploaded config) into a single, timestamped archive.
|
# uploaded config) into a single, timestamped archive.
|
||||||
#
|
#
|
||||||
# cd ~/argus && ./backup.sh [output-directory]
|
# cd /opt/argus && ./backup.sh [output-directory]
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
|
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
|
||||||
OUT_DIR="${1:-$PWD}"
|
OUT_DIR="${1:-$PWD}"
|
||||||
STAMP="$(date +%Y%m%d-%H%M%S)"
|
STAMP="$(date +%Y%m%d-%H%M%S)"
|
||||||
ARCHIVE="${OUT_DIR}/argus-backup-${STAMP}.tar.gz"
|
ARCHIVE="${OUT_DIR}/argus-backup-${STAMP}.tar.gz"
|
||||||
|
|||||||
+8
-1
@@ -108,7 +108,14 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
TZ: ${TZ:-UTC}
|
TZ: ${TZ:-UTC}
|
||||||
PORT: "8080"
|
PORT: "8080"
|
||||||
DATABASE_URL: postgres://postgres:${DB_PASSWORD:-postgres}@db:5432/argus?sslmode=disable
|
# DATABASE_URL is not set here — the API builds it internally from
|
||||||
|
# DB_PASSWORD using net/url (proper percent-encoding), instead of this
|
||||||
|
# file naively interpolating the password into a raw connection
|
||||||
|
# string. A raw '${DB_PASSWORD}@...' interpolation breaks outright if
|
||||||
|
# the password ever contains '@', ':', '/', or similar (confirmed
|
||||||
|
# live: an openssl-rand-base64-generated password containing '/'
|
||||||
|
# produced an unparseable URL and the API never became healthy).
|
||||||
|
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
||||||
REDIS_URL: redis://valkey:6379/0
|
REDIS_URL: redis://valkey:6379/0
|
||||||
ENVIRONMENT: ${ENVIRONMENT:-production}
|
ENVIRONMENT: ${ENVIRONMENT:-production}
|
||||||
NGINX_CONTAINER: argus-proxy
|
NGINX_CONTAINER: argus-proxy
|
||||||
|
|||||||
+2
-2
@@ -2,11 +2,11 @@
|
|||||||
#
|
#
|
||||||
# ARGUS health check — reports the status of every component.
|
# ARGUS health check — reports the status of every component.
|
||||||
#
|
#
|
||||||
# cd ~/argus && ./healthcheck.sh
|
# cd /opt/argus && ./healthcheck.sh
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
|
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
|
||||||
|
|
||||||
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
|
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
|
||||||
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
|
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
|
||||||
|
|||||||
+9
-1
@@ -67,8 +67,16 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ── 4. Generate secrets (first install only — never overwrite an existing .env) ──
|
# ── 4. Generate secrets (first install only — never overwrite an existing .env) ──
|
||||||
|
# hex, not base64: base64 can produce '/', '+', '=', any of which breaks the
|
||||||
|
# raw postgres://user:PASSWORD@host connection string if it ever ends up
|
||||||
|
# interpolated unescaped (confirmed live on the first real production
|
||||||
|
# install — see config.go's buildDatabaseURL for the second, independent
|
||||||
|
# defensive layer this pairs with). Hex output is always [0-9a-f], which
|
||||||
|
# can never produce that class of bug, at 4 bits/char vs base64's ~6 —
|
||||||
|
# 32 hex chars (128 bits) is used in place of 24 base64 chars (~144 bits)
|
||||||
|
# to keep entropy comparable rather than matching digit-count cosmetically.
|
||||||
if grep -q '^DB_PASSWORD=change-me-in-production' .env 2>/dev/null; then
|
if grep -q '^DB_PASSWORD=change-me-in-production' .env 2>/dev/null; then
|
||||||
DB_PASSWORD="$(openssl rand -base64 24 | tr -d '\n')"
|
DB_PASSWORD="$(openssl rand -hex 32)"
|
||||||
sed -i.bak "s#^DB_PASSWORD=.*#DB_PASSWORD=${DB_PASSWORD}#" .env && rm -f .env.bak
|
sed -i.bak "s#^DB_PASSWORD=.*#DB_PASSWORD=${DB_PASSWORD}#" .env && rm -f .env.bak
|
||||||
ok "Generated a secure database password"
|
ok "Generated a secure database password"
|
||||||
fi
|
fi
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@
|
|||||||
# that already has data on it, uninstall.sh --remove-data && install.sh
|
# that already has data on it, uninstall.sh --remove-data && install.sh
|
||||||
# first, then run this.
|
# first, then run this.
|
||||||
#
|
#
|
||||||
# cd ~/argus && ./restore.sh argus-backup-20260719-120000.tar.gz
|
# cd /opt/argus && ./restore.sh argus-backup-20260719-120000.tar.gz
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
|
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
|
||||||
ARCHIVE="${1:-}"
|
ARCHIVE="${1:-}"
|
||||||
|
|
||||||
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
|
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
|
||||||
|
|||||||
+2
-2
@@ -6,13 +6,13 @@
|
|||||||
# it only stops and removes containers, so a plain re-install (install.sh)
|
# it only stops and removes containers, so a plain re-install (install.sh)
|
||||||
# picks up right where you left off.
|
# picks up right where you left off.
|
||||||
#
|
#
|
||||||
# cd ~/argus && ./uninstall.sh # containers only, data kept
|
# cd /opt/argus && ./uninstall.sh # containers only, data kept
|
||||||
# ./uninstall.sh --remove-data # also destroys all data (asks to confirm)
|
# ./uninstall.sh --remove-data # also destroys all data (asks to confirm)
|
||||||
# ./uninstall.sh --remove-data --yes # non-interactive, for scripted use
|
# ./uninstall.sh --remove-data --yes # non-interactive, for scripted use
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
INSTALL_DIR="${ARGUS_INSTALL_DIR:-$HOME/argus}"
|
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
|
||||||
REMOVE_DATA=false
|
REMOVE_DATA=false
|
||||||
ASSUME_YES=false
|
ASSUME_YES=false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user