v1.8.2
v1.8.2 — bugfix rollup
Rollup of stability and UX fixes surfaced by fresh-VPS testing since v1.8.0 .
- fixed some issues reported by @vibecodegits #106.
Behavior change
- Shadowsocks-2022 is now on by default (ENABLE_SS=true in .env.example). Matches the other on-by-default proxies. Existing .env files with an explicit value win; only fresh installs / .env files that removed the line see the change.
Fixed
moav start and profile handling
-
Disabled services started anyway via
DEFAULT_PROFILES / --profile all(issue #106). Six code paths hard-coded … conduit snowflake into the literal profile list, soENABLE_SNOWFLAKE=false/ENABLE_CONDUIT=falsewere silently overridden — the Snowflake relay actively relayed Tor traffic on installs where the operator had explicitly disabled it. New profile_enabled / derive_enabled_profiles / filter_disabled_profiles helpers are now the single source of truth. moav start filters stale DEFAULT_PROFILES entries (self-heal with a one-line note); moav start all expands to the derived enabled set; moav start withENABLE_*=falseprompts: (1) enable in .env and start, (2) skip, (3) start once without persisting. snowflake-exporter profile moved from [monitoring, all] to [snowflake, all] so Grafana panels don't show stale data when the relay is off. -
moav start prompt option 1 was unclear, especially for monitoring (single-flag but labeled "n/a — multiple flags"). Added
monitoring → ENABLE_MONITORING to the case map. Multi-flag profiles (proxy, dnstunnel) now name their underlying flags. All three option labels reworded action-first.
Domainless mode
- Bootstrap errored with DOMAIN is required immediately after the operator chose domainless. scripts/bootstrap.sh checks 6 vars; the moav.sh disable loops only flipped 5 — ENABLE_MASTERDNS (added in 1.8.0 default-on) was missing. Fixed both loops. The bootstrap error message also listed only 4 of the 6 vars to disable; corrected. The "Running in domainless mode" notice is now derived from ENABLE_* flags so the listed protocols stay accurate.
- Domainless mode triggered a port-53 / systemd-resolved conflict prompt for nothing. XDNS doesn't need TLS, but the dnstunnel profile pulls in dns-router which is useless without a domain to delegate. Disable loop now also flips ENABLE_XDNS=false; direct-mode XDNS (port 5356)re-enabled manually.
- Bundle for fresh users was missing MasterDNS instructions. The fast host-side moav user add only generated dnstt/Slipstream/XDNS instructions; MasterDNS (default-on since 1.8.0) was missed. Fixed.
Interactive bootstrap
- https://AAA.DDD/ accepted as DOMAIN verbatim — broke Let's Encrypt / DNS / Reality / CDN. New sanitize_domain strips scheme / user@ / path/ port / whitespace and lowercases; is_valid_domain validates the result. Prints Cleaned input: 'X' → 'Y' so the operator sees what landed in .env. Same auto-clean runs against existing malformed DOMAIN= on later bootstraps.
- Arrow keys printed raw ^[[D in the domain / email prompts — read -r doesn't enable readline. Switched to read -r -e.
- Aborted bootstrap left .env half-configured; next run skipped everything. Ctrl-C after typing the domain (before email) left DOMAIN set, ACME_EMAIL empty, ADMIN_PASSWORD at the insecure default. The existing-.env branch now re-prompts for missing ACME_EMAIL and always runs ensure_admin_password.
- moav bootstrap exited silently after ✓ .env file exists on the second run. ensure_admin_password returned 1 for "already set", which set -euo pipefail turned into a silent abort. Changed to return 0; no caller inspected the return code.
- moav bootstrap itself failed with /usr/local/bin/sing-box: cannot execute: required file not found. Dockerfile.bootstrap was on
alpine:3.21 (musl) but the prebuilt sing-box 1.13.x binary is glibc-linked (its PT_INTERP is /lib64/ld-linux-x86-64.so.2, missing on
Alpine). Switched to debian:bookworm-slim. - DNS records prompt was missing the MasterDNS NS row (m) — fresh installs with all 4 DNS tunnels default-on wouldn't know to delegate MasterDNS. Added the missing row.
User lifecycle
- moav user add silently produced incomplete bundles when ENABLE_SS=true was set post-bootstrap. Without the server PSK + shadowsocks-in inbound (only created during bootstrap), the user-add path silently skipped SS generation via two code paths. Added a loud precondition check with exact remediation.
- moav user revoke reported failure after a successful files-only cleanup. The REVOKED flag only flipped when the user was found in a service entry; pure file cleanup didn't update it, so revoke would print file successes then error "not found." Added a CLEANED_FILES tracker; summary distinguishes service-revoke / files-only / not-found.
Helpers
- update_env_var appended duplicate lines instead of uncommenting #X=. The helper recognized # X= (space after #) but not #X= — and .env.example:73 ships #ENABLE_MONITORING= with no space. Regex relaxed to ^#[[:space:]]*X=. Routed 4 other ad-hoc grep+sed-or-append patterns through the helper.
Upgrade
moav update
moav build bootstrap --no-cache # only needed if pulling in the alpine→debian Dockerfile.bootstrap change
moav start # recreates containers
No bootstrap, user-regeneration, or DB migration required. Behavior changes self-heal on next start:
- Stale DEFAULT_PROFILES entries naming disabled services drop on next moav start
- Malformed DOMAIN= values auto-clean on next moav bootstrap
- Missing ACME_EMAIL with DOMAIN set re-prompts on next bootstrap
Full Changelog: v1.8.0...v1.8.2
Quick Install
curl -fsSL moav.sh/install.sh | bashThis will install MoaV to /opt/moav and guide you through setup.
Documentation
moav.sh/docs — Full documentation
- Setup Guide — Complete installation instructions
- Client Setup — How to connect from devices
- DNS Configuration — DNS records setup
- CLI Reference — All commands and options
- Monitoring — Grafana dashboards and metrics
- Troubleshooting — Common issues and solutions