#!/usr/bin/env bash set -euo pipefail # Run on the PVE service VM only. Does not enable TUN, DHCP, or change routes. task_root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) bind='127.0.0.1:8080' confirmed=false while (($#)); do case "$1" in --target-vm) confirmed=true; shift ;; --bind) bind=${2:?missing bind address}; shift 2 ;; *) echo "Usage: sudo scripts/install.sh --target-vm --bind VM_IP:8080" >&2; exit 2 ;; esac done [[ $EUID -eq 0 && $confirmed == true ]] || { echo 'Run as root on the PVE service VM with --target-vm.' >&2; exit 1; } python3 - "$bind" <<'PY' import ipaddress, sys address, port = sys.argv[1].rsplit(':', 1) ip = ipaddress.ip_address(address) assert ip.version == 4 and (ip.is_private or ip.is_loopback) and port == '8080', 'Use VM private IPv4:8080' PY for required in "$task_root/bin/clashweb" "$task_root/bin/mihomo" "$task_root/data/mihomo/rules/cn-domain.mrs" "$task_root/data/mihomo/rules/cn-ip.mrs"; do [[ -f "$required" ]] || { echo "Missing $required; see README build instructions." >&2; exit 1; } done for command in systemctl useradd groupadd sudo visudo; do command -v "$command" >/dev/null || { echo "Missing $command" >&2; exit 1; }; done getent group clashweb-core >/dev/null || groupadd --system clashweb-core id clashweb >/dev/null 2>&1 || useradd --system --user-group --no-create-home --home-dir /var/lib/clashweb --shell /usr/sbin/nologin clashweb id clashweb-mihomo >/dev/null 2>&1 || useradd --system --gid clashweb-core --no-create-home --home-dir /var/lib/clashweb-core --shell /usr/sbin/nologin clashweb-mihomo usermod -aG clashweb-core clashweb install -d -m 0700 -o clashweb -g clashweb /var/lib/clashweb install -d -m 2770 -o clashweb -g clashweb-core /var/lib/clashweb-core /var/lib/clashweb-core/rules install -d -m 0755 /usr/local/libexec /etc/clashweb install -m 0755 -o root -g root "$task_root/bin/clashweb" /usr/local/bin/clashweb install -m 0755 -o root -g root "$task_root/bin/mihomo" /usr/local/bin/mihomo install -m 0755 -o root -g root "$task_root/scripts/clashweb-control" /usr/local/libexec/clashweb-control install -m 0640 -o clashweb -g clashweb-core "$task_root/data/mihomo/rules/"*.mrs /var/lib/clashweb-core/rules/ if [[ -f /etc/clashweb/env ]]; then cp -a /etc/clashweb/env "/etc/clashweb/env.backup-$(date +%Y%m%d-%H%M%S)"; fi cat > /etc/clashweb/env < "$task_sudoers" <<'EOF' clashweb ALL=(root) NOPASSWD: /usr/local/libexec/clashweb-control start, /usr/local/libexec/clashweb-control stop, /usr/local/libexec/clashweb-control restart EOF visudo -cf "$task_sudoers" install -m 0440 -o root -g root "$task_sudoers" /etc/sudoers.d/clashweb sudo -u clashweb env CLASHWEB_DATA_DIR=/var/lib/clashweb CLASHWEB_CORE_DIR=/var/lib/clashweb-core CLASHWEB_MIHOMO_BIN=/usr/local/bin/mihomo /usr/local/bin/clashweb --init install -m 0644 "$task_root/deploy/clashweb.service" "$task_root/deploy/clashweb-mihomo.service" /etc/systemd/system/ systemctl daemon-reload systemctl enable --now clashweb-mihomo.service clashweb.service systemctl restart clashweb-mihomo.service clashweb.service systemctl is-active --quiet clashweb-mihomo.service clashweb.service echo "Installed on service VM. Open http://$bind" echo 'First-run token: journalctl -u clashweb -n 30' echo 'TUN remains disabled. Follow docs/deployment.md before enabling gateway mode.'