Improve wg-ui host setup: IP availability checks and current-user install script
- setup-main-host-button: live availability status, grab-next-subnet helper, error/success feedback - setup-wireguard-host: harden generated shell scripts with set -e - check-private-ip-address-availability: add user access check, drop manual body validation - setup-main-host: pass host object with wg_ip_address - install-wg-ui.sh: run service as the invoking user (root or sudo) instead of a dedicated wgui user, and skip systemd/OpenRC daemon setup when NODE_ENV=development
This commit is contained in:
@@ -10,20 +10,46 @@ set -euo pipefail
|
||||
|
||||
WGUI_LIB_DIR="/var/lib/wgui"
|
||||
INSTALL_DIR="${INSTALL_DIR:-$WGUI_LIB_DIR/webapp}"
|
||||
SERVICE_USER="${SERVICE_USER:-wgui}"
|
||||
SERVICE_USER="${SERVICE_USER:-}"
|
||||
SERVICE_GROUP="${SERVICE_GROUP:-}"
|
||||
SERVICE_NAME="${SERVICE_NAME:-wgui}"
|
||||
REPO_URL="${REPO_URL:-}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
BUN_INSTALL_DIR="${BUN_INSTALL_DIR:-/opt/bun}"
|
||||
BUN_BIN="/usr/local/bin/bun"
|
||||
UPDATE=false
|
||||
DEV_MODE=false
|
||||
if [ "${NODE_ENV:-}" = "development" ]; then
|
||||
DEV_MODE=true
|
||||
log "NODE_ENV=development — skipping system service installation (daemon is assumed to already be running)"
|
||||
fi
|
||||
|
||||
log() { echo "==> $*"; }
|
||||
fail() { echo "error: $*" >&2; exit 1; }
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
fail "this script must be run as root"
|
||||
fi
|
||||
require_root() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
if ! command -v sudo >/dev/null 2>&1; then
|
||||
fail "this script must be run as root, and sudo is not installed"
|
||||
fi
|
||||
log "not running as root — re-executing with sudo ..."
|
||||
sudo -v || fail "current user does not have sudo privileges — run this script as root or grant the current user sudo access"
|
||||
exec sudo -E "$0" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_service_user() {
|
||||
if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ] && id -u "$SUDO_USER" >/dev/null 2>&1; then
|
||||
echo "$SUDO_USER"
|
||||
else
|
||||
echo "root"
|
||||
fi
|
||||
}
|
||||
|
||||
require_root
|
||||
SERVICE_USER="${SERVICE_USER:-$(resolve_service_user)}"
|
||||
SERVICE_GROUP="${SERVICE_GROUP:-$(id -gn "$SERVICE_USER")}"
|
||||
log "running the wg-ui service as $SERVICE_USER (group: $SERVICE_GROUP)"
|
||||
|
||||
if [ -z "$REPO_URL" ]; then
|
||||
fail "REPO_URL is not set — pass the git URL of the wg-ui repo, e.g.
|
||||
@@ -90,11 +116,8 @@ install_bun() {
|
||||
}
|
||||
|
||||
setup_service_user() {
|
||||
if ! id -u "$SERVICE_USER" >/dev/null 2>&1; then
|
||||
useradd --system --home-dir "$WGUI_LIB_DIR" --shell /usr/sbin/nologin "$SERVICE_USER"
|
||||
fi
|
||||
mkdir -p "$WGUI_LIB_DIR/iptables" "$WGUI_LIB_DIR/keys" "$WGUI_LIB_DIR/clients"
|
||||
chown -R "$SERVICE_USER:$SERVICE_USER" "$WGUI_LIB_DIR"
|
||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" "$WGUI_LIB_DIR"
|
||||
}
|
||||
|
||||
clone_or_update() {
|
||||
@@ -115,7 +138,7 @@ clone_or_update() {
|
||||
log "cloning wg-ui ($REPO_URL, branch $BRANCH) ..."
|
||||
git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
|
||||
fi
|
||||
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
|
||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR"
|
||||
}
|
||||
|
||||
run_as_service_user() {
|
||||
@@ -137,12 +160,12 @@ ensure_env_file() {
|
||||
if [ ! -f "$INSTALL_DIR/.env" ]; then
|
||||
log "generating $INSTALL_DIR/.env with fresh encryption secrets ..."
|
||||
{
|
||||
echo "NODE_ENV=production"
|
||||
echo "NODE_ENV=${NODE_ENV:-production}"
|
||||
echo "ENCRYPTION_KEY=$(openssl rand -base64 32 | tr -d '\n')"
|
||||
echo "ENCRYPTION_SALT=$(openssl rand -base64 32 | tr -d '\n')"
|
||||
echo "DATA_DIR=$INSTALL_DIR/.data"
|
||||
} > "$INSTALL_DIR/.env"
|
||||
chown "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR/.env"
|
||||
chown "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR/.env"
|
||||
chmod 600 "$INSTALL_DIR/.env"
|
||||
fi
|
||||
}
|
||||
@@ -158,7 +181,7 @@ setup_wireguard() {
|
||||
grant_runtime_access() {
|
||||
log "granting $SERVICE_USER access to /etc/wireguard ..."
|
||||
mkdir -p /etc/wireguard
|
||||
chown "root:$SERVICE_USER" /etc/wireguard
|
||||
chown "root:$SERVICE_GROUP" /etc/wireguard
|
||||
chmod 770 /etc/wireguard
|
||||
}
|
||||
|
||||
@@ -174,7 +197,7 @@ Wants=network-online.target
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$SERVICE_USER
|
||||
Group=$SERVICE_USER
|
||||
Group=$SERVICE_GROUP
|
||||
WorkingDirectory=$INSTALL_DIR
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=$BUN_BIN src/server.ts
|
||||
@@ -242,23 +265,29 @@ ensure_env_file
|
||||
setup_wireguard
|
||||
grant_runtime_access
|
||||
|
||||
case "$INIT_SYSTEM" in
|
||||
systemd)
|
||||
install_systemd_unit
|
||||
;;
|
||||
openrc)
|
||||
install_openrc_unit
|
||||
;;
|
||||
*)
|
||||
log "no supported init system found — start manually with:
|
||||
if [ "$DEV_MODE" = false ]; then
|
||||
case "$INIT_SYSTEM" in
|
||||
systemd)
|
||||
install_systemd_unit
|
||||
;;
|
||||
openrc)
|
||||
install_openrc_unit
|
||||
;;
|
||||
*)
|
||||
log "no supported init system found — start manually with:
|
||||
su -s /bin/bash $SERVICE_USER -c 'cd $INSTALL_DIR && NODE_ENV=production $BUN_BIN src/server.ts'
|
||||
(add the line above to your boot scripts)"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
PORT="$(grab_port)"
|
||||
log "wg-ui install complete."
|
||||
log "webapp: $INSTALL_DIR"
|
||||
log "runtime: $WGUI_LIB_DIR (keys, iptables, client configs)"
|
||||
log "process: managed by $INIT_SYSTEM as $SERVICE_NAME"
|
||||
if [ "$DEV_MODE" = true ]; then
|
||||
log "process: development mode — no system service installed"
|
||||
else
|
||||
log "process: managed by $INIT_SYSTEM as $SERVICE_NAME"
|
||||
fi
|
||||
log "open http://$(hostname -I 2>/dev/null | awk '{print $1}' || echo localhost):$PORT in your browser"
|
||||
Reference in New Issue
Block a user