Commit Graph

2916 Commits

Author SHA1 Message Date
6321307288 docs: track wg-toolbox reboot surf-blackhole nft fix 2026-07-10 08:14:41 +02:00
bf0460c189 fix(toolbox): wg-toolbox nft drop-in aborted every boot → tunnel surf blackholed
Root cause of 'surf stops when wg-toolbox VPN activated' after a reboot: the
persistent nft drop-in (loaded atomically by nftables.service via
/etc/nftables.conf include) failed to load, so the wg-toolbox DNAT never
existed after boot and all tunnel traffic was blackholed.

Two boot-time aborts, both fixed:
- referenced 'inet filter input' which does not exist on gk2 at load time →
  fold the UDP-51820 handshake accept into the wg-toolbox table's own input
  base chain (self-contained, no external table dependency)
- used iif/oif "wg-toolbox" (resolves an interface index at LOAD time, fails
  when wg-quick@wg-toolbox has not created the iface yet) → iifname/oifname
  (per-packet name match, load-order independent)

nft -c -f /etc/nftables.conf now passes; the DNAT survives reboot.
2026-07-10 08:13:55 +02:00
b644cd409f docs: WIP checkpoint — wireguard 1.0.3 done, users reskin + webui guidelines next 2026-07-10 07:48:39 +02:00
c61e4967d6 docs: track wireguard 1.0.3 connected-only peers + wg-toolbox peer prune 2026-07-10 07:46:05 +02:00
f25806c7d6 feat(wireguard): show connected-only peers on large tunnels (Show-all toggle) instead of suppressing 2026-07-10 07:45:09 +02:00
577a0037a8 docs: track wireguard 1.0.2 webui rewrite + perf avalanche fix 2026-07-10 07:31:42 +02:00
24972969a9 fix(wireguard): address review — close private-key disclosure in _parse_wg_show, delegate webui handlers (no JS-string interp), invalidate cache on mutations
- _parse_wg_show: parse all-dump by field count (5=iface/9=peer), drop private_key
  (sudo route had made it leak 48 bits via /stats,/summary,/peers/status);
  also restores peer parsing (old detection misclassified every peer line)
- webui: data-attr + delegated click handlers; guard peer-drawer loading flicker
- api: clear read cache after up/down/add/remove so mutations show immediately
2026-07-10 07:29:30 +02:00
f3acebdc4a feat(wireguard): rewrite webui as live interface dashboard + fix status/peers O(peers) subprocess avalanche
- webui: interface-card dashboard (roles, live status, lazy peer drawers,
  up/down + add-peer), certs skin + shared sidebar navbar
- wgctl status/peers: single awk / wg show dump passes (was ~8 procs/peer)
- api: single-flight+TTL cache on read endpoints; kill wgctl child on timeout
- service: NoNewPrivileges=false so sudo -n wgctl elevates
2026-07-10 07:21:42 +02:00
f1f6b23600 release(wireguard): sudo-routed wg show 2026-07-10 06:53:38 +02:00
3433a666b2 fix(wireguard): sudo-route wgctl/wg (root needed for wg show dump) so webui lists interfaces+peers; fix(mochabin): clean netplan — WAN=eth2 DHCP metric100, drop stray lan3 IP (boot-wedge) 2026-07-10 06:53:38 +02:00
9884035e02 Merge: NAC online-clients → one-click Tor-VPN toggle + .onion webui discovery cache (tor 0700 workaround)
Some checks failed
License Headers / check (push) Has been cancelled
2026-07-09 15:32:09 +02:00
a319219efb release: NAC→Tor-VPN toggle (tor+toolbox) 2026-07-09 15:26:36 +02:00
d8397b1fdc feat(tor): NAC online-clients → one-click Tor-VPN routing toggle
Add a "LAN clients (from NAC)" subsection to the Tor-VPN selective-routing
panel in both /tor/ and /toolbox/#tor webuis. Lists NAC clients that are
online and not quarantined, cross-referenced against the current
/toolbox/vpn/clients selectors to derive each toggle's on/off state.
Toggling calls the existing POST/DELETE /toolbox/vpn/client {kind:"ip"}
endpoints and refreshes both lists. IPv6 client IPs are filtered out
client-side (VPN backend is v4-only, Phase 1). Existing free-text
add-selector control (MAC/CIDR/off-NAC clients) is unchanged.
2026-07-09 15:25:47 +02:00
a073b42b5d fix(tor/exposure): .onion webui discovery via root-written cache (tor 0700 blocks secubox-user reads) 2026-07-09 15:19:15 +02:00
204129f23f fix(exposure): reconcile makes HS .onion group-readable for webui discovery 2026-07-09 15:14:21 +02:00
0ccee5028b Merge secubox-reality: VLESS+Reality+Vision (Xray) egress module — API+WebUI, fleet skin, navbar (deployed on gk2)
Some checks are pending
License Headers / check (push) Waiting to run
2026-07-09 15:11:54 +02:00
4a808a4cad Merge Tor Phase-1 enhancement: exit-country, per-client Tor-VPN (leak-proof), emancipate .onion, .onion DNS, obfs4 bridges, /tor/+/toolbox/#tor webui (deployed+verified on gk2) 2026-07-09 15:11:53 +02:00
0d5edcab6f fix(exposure): create /var/lib/tor/hidden_services parent (2750 debian-tor) in postinst — tor config broke + egress died without it (live-found) 2026-07-09 15:11:53 +02:00
db64a056e4 release(reality): 0.1.1 fleet skin + navbar 2026-07-09 15:08:40 +02:00
f9ac5289e6 feat(reality): fleet crt-light skin + shared sidebar + navbar menu entry
Swap the standalone MESH-blue charter in reality.html for the fleet
crt-light/P31-phosphor skin (Courier Prime, --p31-* palette,
.main{margin-left:220px}) matching secubox-tor and other webuis, and
replace the bespoke breadcrumb sidebar with the shared sidebar.js/
sidebar-light.css injector so /reality/ appears in the common navbar.
All panels (server list+create, validate-target, apply, clients+link
QR, volume-guard config+stats) and their JS/fetch wiring are unchanged.

Add menu.d/562-reality.json (mesh category) and install it via
debian/rules, mirroring secubox-tor. python3-segno was already
declared in debian/control.
2026-07-09 15:07:58 +02:00
9bf04ad795 release(tor): 1.0.4 arm toggle 2026-07-09 14:56:22 +02:00
ea5a703092 feat(tor): /tor/ Control Panel arms the transparent Tor egress (tor_mode) + shows armed state 2026-07-09 14:56:22 +02:00
5526144e90 feat(reality): debian packaging — secubox-reality 0.1.0-1~bookworm1
control/rules/postinst/prerm/changelog/compat + 4 systemd units:
secubox-reality.service (API, User=secubox, RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes per #494/RuntimeDirectory-wipe lessons),
secubox-xray@.service (templated per-egress instance: DynamicUser=yes,
ProtectSystem=strict, LoadCredential for the private-key-bearing config,
AmbientCapabilities=CAP_NET_BIND_SERVICE, NoNewPrivileges=yes),
secubox-reality-monitor.service+.timer (5-min volume-guard sweep).
postinst only chowns /etc/secubox/reality and /var/lib/secubox/reality
(never the shared parents). Verified via a full local dpkg-buildpackage
-us -uc -b (builds clean, correct paths, dh_installsystemd wiring
confirmed).
2026-07-09 13:57:17 +02:00
e923ba0174 feat(reality): webui — standalone Reality dashboard
Zero CDN/frontend deps (inline CSS/JS), Space Grotesk + JetBrains Mono
with system-font fallback, MESH accent #104A88, sidebar ROOT->MESH->MIND.
Panels: server list+create, validate-target, apply, clients+/link QR,
volume-guard config+stats. esc() everywhere, sbx_token bearer auth,
fail-safe fetch wrapper with 401 redirect to login.
2026-07-09 13:57:12 +02:00
0cc9629805 feat(reality): router + ASGI entrypoint — /api/mesh/reality REST surface
APIRouter(prefix="/api/mesh/reality", dependencies=[require_jwt]) —
router-level JWT gate on every route. Servers/clients CRUD,
validate-target, apply (force-overridable sanity gate), link (vless://
+ QR), guard get/put, stats. All subprocess-touching handlers are
plain def so FastAPI threadpools them off the event loop. main.py adds
the uvicorn ASGI app target (secubox_reality.main:app) — not in the
original file list but required to serve the router.
2026-07-09 13:57:08 +02:00
613541d6a0 feat(reality): monitor — sliding-window volume-guard (MIND)
xray api statsquery via loopback StatsService, samples stored in
SQLite; per-window delta = max-min across samples (cumulative
counters). Soft warn / hard disable (stop-not-destroy). CLI entry
point for the 5-min systemd timer.
2026-07-09 13:57:02 +02:00
a24b3b2085 feat(reality): service — secubox-xray@<id> instance lifecycle (BOOT)
Plain-def systemctl wrappers (start/stop/enable/disable/restart/status)
for the hardened templated unit; stop_instance() never disables/destroys
so the volume-guard DISABLE action preserves IP/keys.
2026-07-09 13:56:59 +02:00
e0663d66d6 feat(reality): store — SQLite WAL persistence (ROOT)
servers/clients/stats_samples tables, PRAGMA journal_mode=WAL, all
queries parameterized (no string-built SQL).
2026-07-09 13:56:56 +02:00
7c3303b390 feat(reality): validator — TLS1.3+X25519 target sanity gate (MIND)
openssl s_client probe (-tls1_3 -groups X25519 -alpn h2,http/1.1),
defensive parsing across OpenSSL 3.x's terser handshake-summary output
and the classic SSL-Session dump, connect-failure vs TLS-mismatch
distinction, ALPN capture. refuse_apply_if_insane() gates /apply unless
forced.
2026-07-09 13:56:53 +02:00
537b74f7c5 feat(reality): xray — identity/config generation (AUTH+WALL+MESH hooks)
Defensive x25519 keypair parsing across xray-core output variants
(Private key:/Public key: and PrivateKey:/Password:), even-length hex
shortIds, atomic config write (tempfile + os.replace), vless:// URI +
segno SVG QR (lazy import). Compat constants NETWORK_KEY/TARGET_KEY/
LINK_TYPE kept stable across xray-core versions. Server config wires a
loopback dokodemo-door api inbound + StatsService for monitor.py.
2026-07-09 13:56:49 +02:00
61f1a223bf feat(reality): models — Pydantic v2 data contracts for Reality egress points
ServerCreate/Server, ClientCreate/Client, GuardConfig, StatsPoint,
ValidateTargetRequest, ApplyRequest. Uses model_config/field_validator
(v2 API only, no legacy Config/@validator).
2026-07-09 13:56:45 +02:00
3619b6c07b release(tor): 1.0.3 /tor/ page panels + discovery perms 2026-07-09 13:39:46 +02:00
22d607dd56 feat(tor): Tor control panels on the /tor/ page + fix hidden-service discovery perms
Mirror the toolbox #tor tab's five control panels (exit-country, Tor-VPN
clients w/ IPv6 warning, obfs4 bridges, emancipate-to-.onion, hidden
services + .onion-DNS status) onto secubox-tor's own /tor/ dashboard,
wired to the same cross-module endpoints via /api/v1/{toolbox,exposure,tor}.
All onclick="fn(...)" handlers replaced with data-attrs + delegated
listeners; every backend-derived string is esc()'d before landing in
innerHTML.

Fix _discover_hidden_services(): secubox-exposure's emancipate flow
creates hidden services under /var/lib/tor/hidden_services/<name>/hostname
(its own TOR_DATA constant), not directly under /var/lib/tor/<name>/hostname
like this module's legacy add_hidden_service(). Discovery now scans both
layouts (still fail-safe, still de-duplicated by name), so GET
/hidden_services surfaces .onions regardless of which flow created them.

Also grants secubox-tor.service SupplementaryGroups=debian-tor so the
process can traverse the debian-tor-owned hidden-service directories once
the board operator grants group-read/traverse bits (documented in the
unit's comment + PR description — this alone isn't sufficient, the parent
dirs still need their permission bits relaxed operator-side).
2026-07-09 13:29:32 +02:00
5a8139a22c release: bump toolbox/exposure/tor for Tor Phase-1 deploy 2026-07-09 13:03:25 +02:00
b9371aeba6 fix(tor): pre-create toolbox state files (500 on fresh install) + persist self-heal on torrc reset + package exposure persist unit + audit webui emancipation
FINAL-REVIEW fix wave for tor-enhancement-phase1:

- Critical 1: postinst pre-creates + chowns tor-exit-country.txt,
  tor-vpn-clients.txt, tor-bridges.txt under the 0750 root:secubox-toolbox
  /etc/secubox/toolbox dir, mirroring the filters.json pattern, so the
  first CRUD write on a fresh install no longer 500s with PermissionError.
- Critical 2: tor_reconcile_persist() now re-applies the torrc
  HiddenService* stanza whenever the key dir survives but the stanza is
  missing (torrc reset), not just when the key dir is absent, so a torrc
  reset no longer leaves a .onion permanently dark. Added
  _torrc_has_stanza() + repair-path tests.
- Packaging: debian/rules now installs
  sbin/secubox-exposure-tor-reconcile and the matching systemd unit;
  postinst enables the unit, so boot-time persist actually runs.
- Audit: emancipate_webui() now writes a CSPN audit-log entry (operator,
  action, resulting onion) via a new _audit_exposure_action() helper
  shared with the existing _audit_exposure() vhost-reach audit path.
- Confirmed emancipate_webui() already records local_port=9080 (not 80).
2026-07-09 11:17:32 +02:00
9a54897155 fix(toolbox): atomic nft set swap in reapply (no clearnet window) + write torrc drop-ins before tor restart 2026-07-09 09:17:08 +02:00
7672b39da2 feat(toolbox): obfs4 bridges drop-in + reapply-when-armed (edits apply live) 2026-07-09 09:02:21 +02:00
b8d4e1b630 feat(toolbox): #tor tab — exit-country, Tor-VPN clients, obfs4 bridges, emancipate, .onion list + DNS status 2026-07-09 08:50:18 +02:00
5f654e2c2f docs(tor-plan): Task 7 webui must warn about IPv6 leak on routed VPN clients (Task 3 limitation) 2026-07-09 08:44:01 +02:00
12ce912164 feat(tor): auto-discover all on-disk .onion services + .onion-DNS status
- _discover_hidden_services() globs TOR_DATA for every */hostname (not just
  config-listed ones), cross-referencing secubox config for local_port/
  virtual_port/enabled where a matching entry exists. Fail-safe: missing
  TOR_DATA, broken config, or unreadable hostname files degrade to empty
  entries, never raise.
- GET /hidden_services now surfaces every on-disk hidden service via
  _discover_hidden_services(), including orphaned/hand-created ones.
- GET /onion_dns reports {dnsport_up, forward_zone_installed, resolves}:
  dnsport_up via a local-only /proc/net/{tcp,udp}[6] scan (no network I/O,
  never hangs), forward_zone_installed via checking the unbound drop-in,
  resolves via a tightly bounded (1.5s) UDP canary query only attempted when
  both prerequisites hold.
2026-07-09 08:39:49 +02:00
691a5cbad1 docs(tor-plan): Task 9 must-fix — package secubox-exposure-tor-reconcile sbin+unit (Task 5 persist-on-boot) 2026-07-09 08:35:43 +02:00
217628ce71 feat(exposure): emancipate webui .onion (standalone federate-optional) + persist-on-boot reconcile 2026-07-09 08:32:26 +02:00
6b1c76253f fix(toolbox): reject IPv6 VPN selectors (backend is v4-only) — no false-success 2026-07-09 08:26:11 +02:00
cf548517b7 docs(tor-plan): Task 8 also adds reapply-when-armed (edits apply without disarm/arm cycle) 2026-07-09 08:24:58 +02:00
c848b7c65a feat(toolbox): exit-country + Tor-VPN-client + obfs4-bridge API (validated, audited, reconcile-triggered) 2026-07-09 08:17:45 +02:00
6e163614e5 fix(toolbox): Tor-VPN DNS-leak ordering + fail-closed kill-switch + mac-branch guard 2026-07-09 08:07:43 +02:00
805e3e94c5 feat(toolbox): per-client Tor-VPN prerouting chain + tor_vpn_src set population 2026-07-09 07:57:22 +02:00
4ccfe4a331 docs(tor-plan): add Task 8 obfs4 bridges; fold bridge API/webui into Tasks 4/7; bump live-e2e to Task 9 2026-07-09 07:54:51 +02:00
e983520604 docs(tor-spec): add feature 6 — obfs4 bridges (Niveau-1 anti-censorship, entry-side) 2026-07-09 07:53:53 +02:00
5bdf2cd5ef feat(toolbox): global Tor exit-country drop-in (ExitNodes/StrictNodes from state file) 2026-07-09 07:44:17 +02:00