Skip to content

v1.8.4

Choose a tag to compare

@shayanb shayanb released this 08 Jun 22:57
d73c068

MoaV v1.8.4 — Release Notes

Released 2026-06-08 · Changelog


A performance + observability release. BBR + kernel network tuning ships behind an install-time prompt and consistently delivers 2–5× TCP throughput on the long-RTT, lossy paths proxy traffic actually traverses. Two operator-reported bugs are fixed end-to-end: VLESS Reality :443 no longer dies silently when REALITY_TARGET is set to a hostname that doesn't resolve, and the admin dashboard finally shows correct status for every container (xray, snowflake, and three previously-invisible DNS-tunnel services). Non-interactive installs (setsid / </dev/null) work cleanly on stock Ubuntu 24.04.

What's new

BBR + kernel network tuning, opt-in once

Real-world testing (~400 ms RTT, burst loss) showed BBR ~3× single-flow TCP vs CUBIC, and post-loss recovery jumped from "stuck at 2 Mbps for seconds" to "back to 43 Mbps in the next second". UDP buffer bumps also help Hysteria2, WireGuard, and quic-go (which needs ≥7.5 MiB per UDP socket to avoid drops).

Single dedicated file /etc/sysctl.d/99-moav-net.conf so revert is clean. Buffer max auto-capped at 16 MiB on hosts with <2 GB RAM, 32 MiB otherwise. Skips silently on kernels <4.9 or OpenVZ guests. Deliberately excludes tcp_fastopen — actively hostile in heavily-censored networks (China Mobile and ~5% of paths drop SYN+data, so TFO server-side adds latency).

moav net apply     # opt in to the bundle
moav net status    # show current vs recommended
moav net revert    # remove + reload sysctl
moav doctor net    # part of the regular doctor sweep

Full per-knob rationale in docs/OPSEC.md → "Network tuning".

Reality :443 no longer RSTs when REALITY_TARGET is unreachable

Issue #115 reported the inbound returning RST/0 bytes for every TLS hello. Diagnosis: the operator had set REALITY_TARGET to a hostname that returns NXDOMAIN. Reality's fallback dial failed → connection dropped → clients saw RST and the server's :443 looked visibly dead to passive scanners. The same trap exists for XHTTP_REALITY_TARGET on Xray's :2096.

Wiring is now:

  • Bootstrap-time validation — both targets must resolve via getent hosts before the bootstrap container starts; NXDOMAIN re-prompts (up to 3 attempts) with a vetted list of alternatives, rewrites .env in place.
  • moav doctor reality — exec's into sing-box and xray containers, validates DNS resolution + TCP reachability from inside each. Surfaces the problem at moav doctor time instead of after issuing broken bundles.
  • docs/OPSEC.md "Reality fallback target" — vetted global lists (www.cloudflare.com, www.apple.com, cdn.kernel.org) and Iran-friendly SNI cover (www.aparat.com, digikala.com, taghche.com).

Also removed tcp_fast_open: true from the sing-box Reality and Trojan inbounds for the same TFO-hostile-to-censored-networks reasoning as the BBR bundle.

Admin dashboard container status — real fix this time

Issue #117 reported xray showing as "unknown" even with clients connecting fine. The first attempt added a Docker healthcheck — that helps docker ps show real Health.Status, but the admin UI never read it. Actual root cause: check_service_status decided state by DNS-resolving the container hostname on moav_net, and xray was simply missing from the lookup dict.

The fix refactored the entire status path to use the docker-socket-proxy's /containers/json endpoint uniformly — one round-trip per refresh lists every running container, no per-service special cases. Same change surfaced three previously-invisible cards:

  • masterdns — 4th DNS tunnel, default-on since 1.8.0
  • dns-router — without it, all four DNS tunnels silently break (they all route through it on :53)
  • gooserelay — opt-in SOCKS5-over-Apps-Script exit

Dashboard goes from 13 cards to 16, and snowflake (host networking) now reports real running state instead of always "unknown".

telemt log spam silenced

Same issue #117. telemt v3.4.x writes a runtime observability snapshot (beobachten.txt) relative to its working directory. The container is read_only: true with tmpfs at /app/tlsfront, /app/cache, /tmp — but the entrypoint was cd /app, the read-only image root. Every flush hit ENOSYS, logging once per ~15 s. Non-fatal but loud.

Fix: entrypoint now cd /app/cache (existing tmpfs), tls_front_dir flipped to absolute /app/tlsfront so the cwd change doesn't break TLS fronting.

Non-interactive install robustness (thanks @ibeezhan, #120)

Six fixes caught while deploying via setsid bash -c "... install.sh ... </dev/null" on fresh Ubuntu 24.04:

  • BBR detection now modprobe tcp_bbr first and persists via /etc/modules-load.d/moav-bbr.conf — most distro kernels ship BBR as a loadable module, absent from /proc/sys/net/ipv4/tcp_available_congestion_control until something loads it. Without this, the network-tuning offer was silently skipping on every fresh Ubuntu 24.04 install.
  • install.sh under setsid no longer leaks bash: /dev/tty: No such device or address — the previous [[ -e /dev/tty ]] guard was true under setsid even though opening the device returns ENXIO. Detection now actually opens the device.
  • moav no longer aborts at clear when TERM is unsetclear now only runs when stdout is a TTY.
  • moav no longer aborts in ensure_admin_password on closed stdinread -r now tolerates EOF and the auto-generate fallback fires.
  • moav install no longer exits 1 sourcing completions/moav.bash under nounset${ZSH_VERSION:-} instead of $ZSH_VERSION.
  • xray healthcheck uses xray run -test (the correct subcommand) instead of xray test (which doesn't exist). Caught before any operator hit the broken check.

Upgrade

moav update
moav net apply                                          # opt in to BBR/sysctl bundle
moav restart xray                                       # picks up new healthcheck
moav build telemt --no-cache && moav restart telemt    # picks up entrypoint fix
moav restart admin                                      # picks up the new status detection + 3 new cards

No bootstrap, no user regeneration, no DB migration required. Existing installs with a NXDOMAIN REALITY_TARGET will see the issue surfaced on next moav doctor; fix .env and run moav regenerate-users to re-issue bundles with the new SNI.

Verification

  • 15 files changed vs v1.8.3 (+689 / −17)
  • bash -n clean on every touched shell script
  • docker compose config parses YAML clean
  • Reality validator + moav doctor reality tested against the actual NXDOMAIN hostnames from issue #115
  • BBR helpers tested standalone on a non-BBR host (correctly skip)
  • check_service_status regression-tested across all 16 dashboard cards plus host-networked snowflake + a non-mapped name
  • Live-tested by @ibeezhan on fresh Ubuntu 24.04 via setsid bash -c "... install.sh ... </dev/null" — install completes, bootstrap runs, all 4 domainless protocols (Reality, XHTTP, SS-2022, WireGuard) proxy end-to-end with the server's IP as egress

Thanks

@ibeezhan — issue #115 (Reality :443 RST root-cause), all six fixes in PR #120 including catching two issues with the initial v1.8.4 work (the broken xray test subcommand and the BBR module-load gap), and live-verifying the release on Ubuntu 24.04 before merge.

@sacredx72 — issue #117 (xray status "unknown" + telemt log spam). Both were caught running real users on real servers; the diagnosis went two layers deeper than the first attempt — the admin UI doesn't read Docker healthchecks at all, so the real fix had to be in admin/main.py.


🤖 Generated with Claude Code

New Contributors

Full Changelog: v1.8.3...v1.8.4


Quick Install

curl -fsSL moav.sh/install.sh | bash

This will install MoaV to /opt/moav and guide you through setup.

Documentation

moav.sh/docs — Full documentation