16 Commits
Author SHA1 Message Date
maeneko 2f2f0e268a Bump to Beta 0.3.1
release / release (push) Successful in 3m18s
Covers all seven places the version is written down: .env, the copy
install.sh keeps because it prints its banner and builds the release URL
before the archive with .env exists, the four package.json files (awg-agent
is new), and the /ui/brand example in the README.

Multiple servers under one panel (core + nodes), the installer's role
question and its full log.
2026-09-26 20:19:50 +03:00
maeneko 6e010a0141 Bump to Beta 0.3.0
Covers all six places the version is written down: .env, the copy install.sh
keeps because it prints its banner and builds the release URL before the
archive with .env exists, the three package.json files, and the /ui/brand
example in the README.

First release with the sen:// subscription and master keys.
2026-09-25 17:24:52 +03:00
maeneko d5e00ddaf8 Bump to Beta 0.2.2
Covers all six places the version is written down: .env, the copy install.sh
keeps because it prints its banner and builds the release URL before the
archive with .env exists, the three package.json files, and the /ui/brand
example in the README.
2026-09-10 17:51:19 +03:00
maeneko 2b46d04af9 Support Debian in the installer
install.sh only knew Ubuntu. On Debian 13 the dependency step died on
software-properties-common, which trixie no longer ships, and on
linux-headers-generic, which Debian never had — so add-apt-repository and the
Ubuntu headers meta package are both off the table there.

The distro family now comes from /etc/os-release (derivatives via ID_LIKE) and
shows up as its own line in the compatibility checklist. On Debian the amnezia
PPA is wired by hand: the key is fetched from keyserver.ubuntu.com by its full
fingerprint and checked after download, then a signed-by source is written on
the Ubuntu series whose glibc is not newer than the Debian release's
(bullseye→focal, bookworm→jammy, trixie→noble; AMNEZIA_PPA_SUITE overrides).

Headers are installed as a separate step so a missing package gets precise
advice instead of a generic failure. Debian's archive keeps only the latest
kernel build, so a server that hasn't rebooted in a while has no headers for
its running kernel; the hint names linux-image/linux-headers for the kernel's
own flavour (cloud-amd64 and so on) plus a reboot.

iptables joins the dependencies — PostUp calls it, and a minimal Debian 13 on
nftables doesn't have it. IP forwarding moves to its own file in
/etc/sysctl.d: Debian 13 no longer reads /etc/sysctl.conf at boot, so the old
line would have held only until the first reboot.
2026-09-10 17:51:19 +03:00
maeneko a358504e2a Bump to Beta 0.2.1
release / release (push) Successful in 3m31s
ci / check (push) Successful in 6m8s
Covers all six places the version is written down: .env, the copy install.sh
keeps because it prints its banner and builds the release URL before the
archive with .env exists, the three package.json files, and the /ui/brand
example in the README.
2026-09-10 00:24:18 +03:00
maeneko a11cfc88de Bring back the external API keys
Commit 0dbb13f removed the whole feature: the apikeys tab, the /ui/apikeys
routes, requireApiKey, the /api/v1 router, the ApiKey type, the better-sqlite3
dependency and UI_DB_FILE in the CLI and the installer. Only the untracked
awg-ui/API.md survived, so the README went on to claim there was no key-based
API at all.

Restores all of it: ui.db with the api_keys table, awgk_ key generation storing
only the SHA-256 and a display prefix, the JWT-guarded CRUD, and the /api/v1
router mounted before the JWT proxy on /api so the key auth is not swallowed.
The tab comes back as its own folder and the registry picks it up on its own.
UI_DB_FILE points at /etc/amnezia/amneziawg/ui.db, outside the install tree, so
reinstalling keeps the keys; a fresh install moves the old one aside with its
WAL sidecars.

better-sqlite3 takes the slot of jsonwebtoken, which arrived with the MA7
integration and has been unused since 068cab4 removed it.

One defect is not reproduced: the /api/v1 handlers called ctrl() without a
try/catch, and Express 4 does not catch async rejections, so a single request
with awg-ctrl down killed the panel process. They now answer 502 like proxy()
already did.

The API contract is documented in the README rather than linked: .gitignore
excludes every markdown but README.md, so awg-ui/API.md is not in the repo and
the link would break on a clone.

Checked against a running server: login, key create/list/delete, 400 on a bad
label, 401 without a JWT, "API key required" rather than "Unauthorized" on
/api/v1, "Invalid API key" for a deleted key, last_used updating, and all three
/api/v1 routes returning 502 with the process still alive.
2026-09-10 00:24:18 +03:00
maeneko 44c032b376 Document the panel API in the README
The public /api/v1 surface and its docs went away with the API keys, leaving
nothing written down about what the panel exposes — even though every route it
uses is reachable over HTTP with a login token.

Replaces the install-source section with an API chapter: the JWT flow and its
401/429 cases, the unauthenticated /ui/brand, health and interface status, the
user routes including why fetching a key is a POST, reissue, and the 2.0 to 3.1
upgrade with its 409 and 500 cases. What is left of the install-source notes is
one line pointing at the comments in install.sh and .env.

Shapes and status codes are taken from the handlers rather than from memory,
and the auth behaviour was checked against a running server.
2026-08-29 03:45:27 +03:00
maeneko 068cab4d24 Remove the MA7 integration
release / release (push) Successful in 2m47s
The integration was half-committed: server.ts imported ./ma7 and the profile
tab was documented, but neither file ever reached the repository, so awg-ui
could not start at all — `Error: Cannot find module './ma7'`.

Everything that referenced it is gone: the import and the /ui/ma7/profile
route, the three MA7_* variables the CLI passed to awg-ui, the installer
prompts and their cli.env block, and the README section. The panel login
prompt goes back to defaulting to admin instead of the MA7 subscriber login.

awg-ui type-checks, builds and starts again.
2026-08-29 03:23:40 +03:00
maeneko ca1c8e8c68 Add a Gitea release workflow
Releases only existed on GitHub, while install.sh now defaults to pulling the
archive from the Gitea mirror. This builds the same archive on a v* tag and
publishes it through the Gitea API, since the runner has no gh CLI: create the
release, fall back to looking it up by tag when it already exists, then upload
the tarball as an asset.

Two details are easy to get wrong and are commented in place. The release id is
the first "id" in Gitea's JSON, so the match must be non-greedy — a greedy one
picks up the author or asset id instead. And the id helper needs `|| true`,
because an empty grep under pipefail would abort the step on the path where the
release already exists.

The workflow cannot run yet: the Gitea repo is a pull mirror, which neither
runs Actions nor accepts release creation. It starts working once the repo is
un-mirrored, Actions are enabled and a runner with the ubuntu-latest label is
registered; the header of the file lists those prerequisites.
2026-08-29 03:08:51 +03:00
maeneko 602c0416ba Move panel name and version into .env, bump to Beta 0.2.0
The product name, the channel word "Alpha" and the version were scattered
across install.sh, the CLI banner, two spots in App.tsx and three
package.json files, so a rename or a bump meant editing strings in code.

They now live in one committed .env at the project root (BRAND, CHANNEL,
VERSION), shipped inside the release archive and read at runtime: the CLI
loads it after cli.env — so real env and machine settings still win — and
injects the three values into awg-ui, which serves them from GET /ui/brand
for the wordmark. awg-ui also parses the same file directly, so
`npm run server` in dev shows what production shows.

install.sh keeps its own VERSION and CHANNEL and says why: it prints the
banner and builds the release URL before the archive holding .env has been
downloaded. It writes BRAND into cli.env only when the operator passed one
explicitly, so the file stays the single source otherwise.

Version bumped to Beta 0.2.0 across .env, install.sh and the three
package.json files.
2026-08-29 03:08:51 +03:00
maeneko 18972ed58f Make the distribution source and brand configurable
Nothing about the install was overridable: the archive could only come from
one GitHub repo, the connectivity precheck pinged github.com whatever the
source was, and the product name was duplicated across install.sh, the CLI
banner and two spots in App.tsx.

install.sh now reads REPO_BASE (default the Gitea mirror), REPO_FALLBACK
(default GitHub), ARCHIVE_URL and BRAND from the environment. Gitea and
GitHub share the same release path, so one scheme covers both:
download_extract tries the primary, warns and falls back to the secondary,
and fails with both URLs listed. The fallback carries real weight today —
the Gitea repo is a pull mirror that does not sync releases, so artifacts
live only on GitHub until release sync is enabled there. The precheck now
probes the hosts actually used.

BRAND flows install.sh -> cli.env -> CLI banner and awg-ui, which exposes
it via GET /ui/brand along with the package version. That route is
unauthenticated because the wordmark is on the login screen, before a JWT
exists; the SPA falls back to a constant if it fails. Renaming a fork is
one environment variable, and no version string is hardcoded in the UI or
the CLI any more.

Also adds /ui to the Vite dev proxy (GET /ui/brand and the API-keys tab
were unreachable in dev), documents the overrides in the README, fixes a
typo in the API.md base URL and states there that the API is not bound to
any host.
2026-08-29 03:08:51 +03:00
maeneko 38e76da84f Make AmneziaWG 3.1 the default generation
install.sh now defaults to AWG_GEN=3.1: an incompatible module or kernel
fails with diagnostics instead of silently falling back to 2.0 and handing
out a server with weaker obfuscation. AWG_GEN=auto keeps the old fallback
for old kernels, AWG_GEN=2.0 still forces 2.0.

Servers already installed on 2.0 no longer need a reinstall: POST
/awg/upgrade (button in the users tab) backs up awg1.conf, rewrites
[Interface] with HeaderProtectionKey and the 3.1 block install.sh writes,
raises any S1-S4 below 12 (header protection needs a 12-byte nonce and the
module only reports "Invalid argument"), restarts the interface and
reissues every vpn:// key. Bringing the interface up is the only real proof
the kernel accepted the params, so a failure restores the previous conf and
brings 2.0 back up. Reissue is not optional: 2.0-era keys stop working the
moment the generation changes.

restartAwg() now re-reads the obfuscation params, generation and keepalive
from awg1.conf before syncing peers. The conf can change while the
interface is down, and a stale CONFIG.gen meant new keys were built on the
old params.

README: install from git.ma7neko.ru (Gitea) instead of raw.githubusercontent,
and document the 3.1 default with the AWG_GEN=auto escape hatch.
2026-08-29 03:08:07 +03:00
maeneko 0dbb13f120 com 2026-08-27 01:39:06 +03:00
Ivan df1e8ce7a8 Update README.md 2026-07-10 01:42:06 +03:00
Ivan 2cfe8e60e2 Change installation script 2026-07-10 01:40:31 +03:00
Ivan 72747c6902 Add README documentation for Forgetting VPN project
Added detailed documentation for the Forgetting VPN project, including architecture, requirements, installation, management, and API usage.
2026-07-10 01:01:40 +03:00