Release candidate. Please test it on a copy of your setup and report problems before v1.3.0. Take a backup of the database first: after the upgrade, v1.2.1 refuses to start on it (see Upgrade notes). The image is ghcr.io/freifunkmuc/wg-access-server:v1.3.0-rc.1; latest stays on v1.2.1.
Highlights
- Sign-in: two-factor authentication (TOTP, recovery codes, passkeys as the second factor) for the built-in users, who can also change their own password. GitHub as a provider. The browser sessions are stored, so you can list and end them.
- API tokens for scripts, with an optional maximum lifetime (
apiTokenMaxLifetime). - Firewall: nftables as an alternative to iptables (
vpn.firewall), and access policies built from identity-provider claims (nftables only). - Devices: route the networks behind a device through its peer, rename a device, give it a new key, block it or set an expiry, and limit how many devices a user may create.
- Admin: take somebody's access away in one action, act on many devices at once, and tables that stay usable with hundreds of devices.
- API served through connectrpc (Connect, gRPC and gRPC-Web on the same handlers; the separate grpc-web wrapper is gone). The account settings sit under one menu.
Security
Fixes from an audit of master:
- Rebuilding the iptables rules no longer leaves them open for a moment (#1399).
- Traffic from a device's routed networks is filtered like the device's own (#1401).
- A policy can no longer be named so that it takes the set of all members (#1400).
- Turning on a second factor needs the password (#1403).
- API tokens cannot reset a second factor or manage the account (#1402, #1348).
- Revoking access sticks against old devices, sessions and tokens (#1398, #1404).
- Passkeys and used codes cannot be reused (#1337).
- A subject that belongs to another provider is refused (#1349).
Upgrade notes
- Schema migrations: the first start records the existing tables and applies 15 migrations (
schema_migrations). Replicas on a shared database take turns. A downgrade is refused once the new version has migrated the database, so keep the backup. - SQLite: the first start rebuilds the
devicestable once. - MySQL:
- The unique index on
public_key, missing since the silent migration failure up to v1.2.0, is created. If two devices already share a key, the server refuses to start and names the query that finds them (docs/storage.md). users.policies,users.totp_recoveryanddevices.routesbecometext(#1409; withvarchar(255)turning on 2FA failed). That rewrites both tables once.
- The unique index on
- Tested in a lab with SQLite, PostgreSQL 17 and MySQL 8.4, iptables and nftables: upgrade from v1.2.1 with existing devices (clients reconnect by themselves), and the audit findings. Not tested: MariaDB, HA setups, IPv6 traffic.
Full Changelog: v1.2.1...v1.3.0-rc.1