Removed a reference to a non-existent `data_manager`.
Key validation now uses the existing `DATA_LOCK`, and the SSH check is performed in a separate thread.
Server editing and deletion operations have been synchronized using the same lock.
Added a test for the actual handler: validation returns HTTP 200, and the key is correctly saved to the trust file. The mock object that masked an error in previous tests has been removed.
Upstream v1.7.7 test_stopped_container_is_not_reported_as_applied fails on
clean v1.7.7: fake_ssh only stored /clientsTable uploads, so the docker cp
of /tmp/_amnz_bwlimits raised KeyError before the deferred RuntimeError.
Upstream v1.7.7 test_stopped_container_is_not_reported_as_applied fails on
clean v1.7.7: fake_ssh only stored /clientsTable uploads, so the docker cp
of /tmp/_amnz_bwlimits raised KeyError before the deferred RuntimeError.
- contour scripts + systemd units live in scripts/rknblock/ now
- install-rkn-extra.sh fetches them straight from PRVTPRO raw URLs
(no external repo, no git-clone dependency on hosts)
- app.py: RKN_RAW_BASE points at this repo's raw main
- new card button 'Options' + modal with 4 flags: block/log inbound/outbound
- new endpoint POST /api/servers/{id}/rknblock/options driving the blocker
'set' subcommand; record merge in install/enable keeps flags across toggles
- status probe head 6 -> 10; parser reads 'flags:' line and 'last_update:'
- card summary shows base update time and disabled directions
- _rkn_run_cmd now refreshes the host-side script copy before running
- icon shield -> rainbow in card and marketplace app list
- translations: 14 new keys x 5 languages
Clicking Install no longer drops back to the page with a bare toast:
the shared installModal opens in progress-only mode (form hidden) with
the progress bar and a running step log (download scripts -> ipset sets
-> firewall rules -> scan agent), finishing with the green Done state
exactly like protocol installs.
The alert badge in the card now stands out with a red fill and a
'details' label; clicking it opens a large modal with the per-org and
per-port breakdown, direction totals and the recent-event table (all
previously dumped inline into the card). The card itself keeps only the
short agent/lists summary; the clear-statistics button moved into the
modal footer.
loadRknBlock runs during page init; a throw from the card renderer
cascaded into the rest of the server page (instances vanished from
view together with the 'esc is not defined' toast on FINN).
esc() only exists as a local helper inside two unrelated functions;
renderRknBlockCard calling it threw ReferenceError as soon as the card
rendered an installed app with scan data. Thrown mid-init it broke the
page chain (instances vanished from view) and every rknblock action
toast showed 'esc is not defined'. Use the global escapeHtml.
The card called installFromMarketplace('rknblock'), which opened the AWG
instance installer (port/MTU/DNS/I1-I5) - none of that applies to a
host-level ipset agent with no container and no listening port. Install
now calls installRknBlock() directly (POST /rknblock/install), like the
server-page card does.
Replace the raw rkn_block_enabled toggle with a full marketplace app:
- install/uninstall/enable/update endpoints; uninstall fully removes the
contour (rules, ipset sets, units, scripts, configs) via a fresh
rkn-extra-block copy so old servers can always be cleaned
- server page card with Start/Stop/Delete/Update buttons, scan count in
the badge row, stats detail in the card info
- servers-overview scan alert now anchors to the marketplace card
- legacy rkn_block_enabled flag dropped in load_data; rkn_scans response
gains installed/enabled
- amnezia-blocker repo gains 'rkn-extra-block uninstall' (e7514a9)
Providers route through a /126 (sometimes /127 or /128) onlink transit
network between the box and their router; those addresses are
infrastructure, not a public address. Keep only prefixes up to /64.
test_awg3_default_would_not_fit_a_standard_link drew random obfuscation
sizes and asserted the old default MTU is unsafe for them; an unlucky
draw (overhead 120 bytes on a 1376 default) failed the assertion about
one run in ten, so CI on unrelated PRs flaked. Seeding the generator in
setUp keeps the scenario representative and makes the suite
deterministic.
The header listed host:port and user only. Servers on dual-stack networks
also have public IPv6 addresses the admin had to look up over SSH. The
/stats endpoint now collects them (scope global, so ULA and link-local
stay excluded) and the page renders a second mono line under the address
when the list is non-empty.
Every fresh AWG/AWG2/AWG3 instance used to fall back to the same default
10.8.1.0/24 (fd42:8:1::/64) and handed out client IPs without looking at
the other containers on the host. With several instances on one server
the same client IP ended up assigned to different peers in different
containers, so host-level rules keyed by the tunnel subnet/IP (firewall,
exit links, smart route, traffic accounting) cannot tell the colliding
peers apart.
On a fresh install (no server config yet) the manager now scans the
Address lines of all amnezia-awg*/amnezia-wireguard containers on the
host and picks the smallest free subnet index N, installing the instance
into 10.8.N.0/24 and fd42:8:N::/64 instead. Existing configs are never
rewritten, and on any scan failure the install falls back to the
previous default behaviour.
The amneziawg-go README documents "Jc: int, recommended range is 4-12"
and the native AmneziaVPN installer picks 4-6. The panel generated
1-10, so fresh instances could land below the documented floor.
Clamp the range to 4-12 and pin it with a test.
The OpenAPI document is a ready-made map of every endpoint and parameter
of the panel; anonymous visitors could use it to enumerate features.
Guard the three schema routes with _check_admin (session cookie or admin
Bearer token both count) in a dedicated middleware.
SessionMiddleware has to wrap the new middleware for request.session to
be populated, so its installation moves below all @app.middleware
definitions (Starlette runs later-added middleware further out).
Every mutating op reads the table, modifies its snapshot and saves it
back. Uvicorn runs these blocking calls in a thread pool, so two
overlapping ops (a rename racing an add, two toggles, ...) saved in
arbitrary order: the last write wins with a stale snapshot and silently
drops the other op's row. The lost row resurfaced as a synthesized
'External (native app)' entry — the WireGuard config stores no names —
which is how peer names got lost in production.
Hold a per-(host, container) threading.Lock across the whole
read-modify-write in both AWG and WireGuard managers. Saves already
invalidate the prefetched batch snapshot, so reads inside the lock
always see the freshest table.
Conntrack entries outlive the VPN session by hours or even days (TCP
ESTABLISHED timeout), so a peer that disconnected long ago still 'owns'
~900 stale flows in /proc/net/nf_conntrack. The per-peer flood warning
counter attributed those stale flows to offline peers and kept posting
phantom '900 connections' warnings every hour.
Count connections only for peers whose latest handshake is fresh
(<= 5 minutes). When liveness cannot be determined the counter returns
empty instead of trusting stale data.
A from-scratch Xray build keeps the install request busy for ~6 min;
a browser-to-panel connection loss (proxy/VPN timeout) surfaces as a
bare 'Failed to fetch' and looks like a failed install even though
the server side completed fine. On a network abort, poll /check for
the new protocol and report success when it shows up.