vpn-router (0.21.0-1) unstable; urgency=medium

  feature: the router has a two-level CA with an optional offline root, issuing CAs for P2S, site-to-site and general use, templates, published certificates and CRLs and an ACME server, site-to-site connections authenticate with certificates, and setup installs Caddy from Ubuntu or Caddy's repository.

  * The root CA signs the issuing CAs p2s, which issues the router's VPN
    server certificate and the users' certificates, s2s, which issues
    the site-to-site certificates, and the general-purpose CAs of
    pki.issuing_cas; road-warrior and OpenVPN accept certificates of p2s
    only.
  * The pki section of vpn-router.json sets the names, lifetimes and
    key type of the CAs, the validity of the CRLs, where certificates
    and CRLs are published, the general-purpose CAs and the certificate
    templates; p2s.ca_name and the vpn-router/p2s_ca_name question are
    replaced by pki.root_name and vpn-router/pki_root_name.
  * Without the root key on the router, new issuing CAs wait with a CSR
    for an offline signature; vpn-router-ca exports, removes and imports
    the root key, imports the signed certificates and a root CRL, issues
    certificates from a CSR or into a PFX file, lists and revokes them.
  * Certificates name their issuer's certificate and CRL at the
    endpoints of pki.publish: the status port over HTTP, or Caddy on port
    80, on the HTTPS status port or on port 443; the CRLs are signed
    again at every revocation and by vpn-router-pki.timer.
  * A general-purpose CA with acme backs an ACME server of Caddy.
  * The router renews its own certificates before they expire.
  * A site-to-site connection with auth certificate authenticates with
    the router's site-to-site certificate and trusts the s2s CA or the
    connection's remote_ca.
  * /ca of the status web service shows and changes the PKI; /pki/
    serves the published certificates and CRLs; /config shows the
    installed Caddy and its source; request bodies may be 64 KiB.
  * vpn-router no longer depends on caddy: vpn-router-setup installs it
    from https.caddy_source, the Ubuntu archive or Caddy's repository,
    and vpn-router-caddy use-upstream switches an installed router to
    Caddy's repository for good.
  * The package depends on python3-cryptography instead of openssl, and
    simple-ca is gone.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Thu, 29 Oct 2026 10:00:00 +0100

vpn-router (0.20.0-1) unstable; urgency=medium

  feature: the router makes scheduled backups to a local folder, copied to the cloud with rclone, or to a Proxmox Backup Server, and vpn-router-backup restores them.

  * The backup section of vpn-router.json switches on backups and sets
    the schedule (hourly, daily or weekly), the target (local or pbs),
    the folder, the retention of local archives, whether the metrics
    database is included, the rclone remote and mode, and the Proxmox
    Backup Server repository, token secret, fingerprint, namespace and
    key file.
  * A backup holds /etc/vpn-router, /etc/wireguard, the ufw rules, the
    Router Manager's settings, PSK files outside /etc/vpn-router, the
    user directory as slapcat writes it and, optionally, the database as
    pg_dump writes it, copied while the configuration and the users are
    locked.
  * Local backups are tar archives compressed with zstd. Archives the
    retention settings no longer keep are deleted by the rules of Proxmox
    Backup Server's prune, and rclone can sync or copy the archives to a
    remote of /etc/vpn-router/rclone.conf.
  * Backups to a Proxmox Backup Server are made with
    proxmox-backup-client-static, which the package suggests; the server
    keeps them.
  * vpn-router-backup runs a backup, lists the backups and restores a
    local archive or a snapshot; vpn-router-backup.timer runs it on the
    schedule.
  * /backup of the status web service shows and changes the backup
    settings, shows the last run, the local archives and the next run,
    and starts a backup.
  * The package depends on zstd and suggests rclone and
    proxmox-backup-client-static.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Wed, 28 Oct 2026 10:00:00 +0100

vpn-router (0.19.1-3) unstable; urgency=medium

  update: ADR-24 names Ubuntu's apt-daily timer, not a cron job, as what updates the package lists.

  * ADR-24 says that Ubuntu's apt-daily timer updates the package lists
    twice a day, and that apt-daily or unattended-upgrades may hold the
    dpkg lock the upgrade waits for.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Tue, 27 Oct 2026 10:00:00 +0100

vpn-router (0.19.1-2) unstable; urgency=medium

  update: ADR-24 says that the Router Manager checks for updates on demand.

  * ADR-24 describes Check update of the Router Manager, which updates
    apt's package lists in the transient unit vpn-router-manager-check.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Tue, 27 Oct 2026 09:00:00 +0100

vpn-router (0.19.1-1) unstable; urgency=medium

  fix: /metrics/history gives the availability of each site-to-site connection as the percentage of time it was up in slots of the view.

  * site_to_site_up of /metrics/history divides the view into slots of 5
    minutes for an hour, 1 hour for a day, 1 day for a month and 1 month
    for a year, and gives for each slot and connection the percentage of
    the samples in which the connection was up.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 21:00:00 +0100

vpn-router (0.19.0-1) unstable; urgency=medium

  feature: service accounts have a display name and a description, which the router sets for its internal ones.

  * vpnRouterAccount of the package's schema also takes displayName and
    description; vpn-router-setup updates the schema of an existing
    directory.
  * /service-accounts shows display_name and description, takes them when
    adding a service account and changes them with PUT; "" removes one.
    /users shows them as null.
  * vpn-router-user add --service and update take --display-name and
    --description.
  * vpn-router-setup gives the metrics service's internal account the
    display name Metrics and its description, and sets them again when
    they differ.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 20:00:00 +0100

vpn-router (0.18.3-1) unstable; urgency=medium

  fix: internal service accounts are the router's own, of which the metrics service's is the one at present, and the documentation says what a service account is.

  * /service-accounts, /groups and the internal field of the answers
    take every internal service account, the accounts the router creates
    and manages for its own services, instead of only the metrics
    service's; the 403 answers say that the router manages them.
  * The README, the ADR and the users module describe a service account
    as the account another system, such as an OpenTelemetry Collector
    reading /metrics, signs in with, and the internal ones as managed by
    the router.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 19:00:00 +0100

vpn-router (0.18.2-1) unstable; urgency=medium

  fix: service accounts are managed at /service-accounts, not /users, and the internal one of the metrics service is only listed.

  * /service-accounts, for members of admins and admin tokens, lists the
    service accounts, adds one with a password and an optional e-mail
    address, changes the e-mail address, sets the password, disables,
    enables, unlocks and removes them.
  * /users no longer lists service accounts or takes "service" on POST,
    and answers 404 to a request naming one.
  * /service-accounts answers 403 to every request but the list on the
    account metrics.service_account names while metrics are enabled, and
    /groups to putting it in or taking it out of a group;
    vpn-router-setup and root's vpn-router-user still change it.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 18:00:00 +0100

vpn-router (0.18.1-1) unstable; urgency=medium

  fix: vpn-router-setup owns only the creation of the metrics service's account, which is marked internal, and administrators add service accounts with vpn-router-user add --service and /users.

  * POST /users takes "service": true and adds a service account, which
    cannot sign in to /auth; vpn-router-user add takes --service.
  * The users of /users and vpn-router-user have internal, true for the
    account metrics.service_account names while metrics are enabled;
    vpn-router-user list shows its kind as internal.
  * PUT /users/<name>/password refuses the internal service account,
    whose password vpn-router-setup keeps.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 17:00:00 +0100

vpn-router (0.18.0-2) unstable; urgency=medium

  update: release.py tags a Debian revision other than 1 as x.y.z-n.

  * release.py tags the newest entry x.y.z for the Debian revision 1 and
    x.y.z-n for a later revision, so a packaging change gets a release
    of its own.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Mon, 26 Oct 2026 14:00:00 +0100

vpn-router (0.18.0-1) unstable; urgency=medium

  feature: site_to_site holds any number of named site-to-site connections, which /site-to-site lists, adds, changes and removes.

  * site_to_site maps a connection name to addrs, id, cidrs, local_cidrs,
    local_id_mode, psk and psk_file; it replaces remote and
    wan.local_id_mode, and a configuration with them is refused.
  * The install answers fill the connection remote-site; the local subnets
    fill both its local_cidrs and local.cidrs.
  * Every ready connection is written to
    /etc/swanctl/conf.d/site-to-site.conf as the swanctl connection and
    child of its name with the secret ike-psk-<name>; remote-site.conf is
    no longer written.
  * Traffic from each connection's local_cidrs to its cidrs is not
    masqueraded.
  * /site-to-site, for members of admins and admin tokens, lists the
    connections without their keys, adds, changes and removes them, and
    restarts vpn-router-setup to apply the change.
  * vpn-config-edit sets site_to_site.NAME.option, creating the
    connection, and removes site_to_site.NAME; it and the web service
    write vpn-router.json under one lock.
  * The status shows site_to_site.connections, whether each connection is
    established.
  * The metrics service keeps, per site-to-site connection, whether it is
    up, the bytes and packets per second received and sent, and the
    seconds its IKE SA has been up, in metrics_site_to_site and its
    summaries; /metrics/history has them in site_to_site of each point.
  * /metrics serves vpn_router_site_to_site_up,
    vpn_router_site_to_site_uptime_seconds,
    vpn_router_site_to_site_io_bytes_per_second and
    vpn_router_site_to_site_packets_per_second by connection, and the
    OTLP push the vpn_router.site_to_site gauges; vpn_router_clients and
    metrics_vpn no longer have the kind site_to_site.
  * /config shows each connection in network.site_to_site, and no psk at
    any level of the configuration.
  * Removing the package terminates every site-to-site connection; purging
    removes site-to-site.conf.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 23:00:00 +0100

vpn-router (0.17.0-1) unstable; urgency=medium

  feature: /config shows the router's PostgreSQL clusters and their settings, and /postgresql their databases with their sizes.

  * /config has a postgresql section: each cluster of pg_lsclusters with
    its version, name, port, status and data directory, and the main
    settings of each online cluster.
  * /postgresql, protected like /config, lists the databases of each
    online cluster with owner, encoding and size, and the total size.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 21:00:00 +0200

vpn-router (0.16.0-1) unstable; urgency=medium

  feature: the router keeps its metrics in PostgreSQL, serves them for an OpenTelemetry Collector and pushes them over OTLP.

  * vpn-router-metrics takes a sample every minute: CPU, memory, free
    space of /, bytes per second on the external and the internal
    interface, the load averages, and the VPN clients of each enabled
    system.
  * The samples are kept in metrics_system, metrics_network and
    metrics_vpn, and summarized hourly, daily, monthly and yearly in
    their _hourly, _daily, _monthly and _yearly tables; once a day the
    rows older than metrics.keep_details, keep_hourly, keep_daily,
    keep_monthly and keep_yearly are deleted.
  * /metrics serves the last sample in the Prometheus format on the
    interfaces metrics.listen names (internal by default) at
    metrics.port, and over HTTPS by Caddy at metrics.https_port, with
    HTTP Basic authentication of the service account
    metrics.service_account names (metrics by default).
  * metrics.otlp_endpoint pushes every sample as OTLP/HTTP JSON, with
    metrics.otlp_username and metrics.otlp_password.
  * /metrics/history of the web service answers the hour, day, month
    and year views for the Router Manager.
  * vpn-router-setup adds and keeps that service account, which cannot
    sign in to /auth, with a random password in
    /etc/vpn-router/metrics.secret, set anew when the file is missing.
  * Depends on python3-psutil and python3-prometheus-client.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 19:00:00 +0200

vpn-router (0.15.0-1) unstable; urgency=medium

  feature: vpn-config-edit shows and changes the router's configuration.

  * vpn-config-edit show prints /etc/vpn-router/vpn-router.json as
    indented JSON.
  * vpn-config-edit set SECTION.OPTION VALUE converts the value to the
    setting's type, checks the whole configuration as vpn-router-setup
    does, writes the file indented with mode 0600, and reminds that
    vpn-router-setup applies it.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 18:00:00 +0200

vpn-router (0.14.1-1) unstable; urgency=medium

  fix: web.status_content is basic by default.

  * Without web.status_content, or with a value that is not allowed, /
    and /status show only the overall status, the time and the Client
    IP; set it to standard or full to show more.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 17:00:00 +0200

vpn-router (0.14.0-1) unstable; urgency=medium

  feature: the status page shows the Client IP, and web.status_content sets how much it shows.

  * / and /status show the Client IP, the address the request came from:
    the last X-Forwarded-For entry for a request from a trusted proxy, so
    behind Caddy or the Router Manager the browser's; /status has it as
    client_ip.
  * web.status_content sets what / and /status show: basic the overall
    status, the time and the Client IP; standard also the package
    versions and the number of active and failed services; full, the
    default, everything as before. /status names it in content.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 16:00:00 +0200

vpn-router (0.13.0-1) unstable; urgency=medium

  feature: Caddy serves the status page and the Router Manager over HTTPS with a certificate from Let's Encrypt.

  * The package depends on caddy. While https.enabled is true, the
    default, and wan.local_fqdn is set, vpn-router-setup writes
    /etc/caddy/vpn-router.Caddyfile and runs Caddy, which serves the
    status page on https.web_port (7444) and the Router Manager, when it
    is installed, on https.manager_port (7443) for wan.local_fqdn, and
    obtains the certificate from Let's Encrypt with the HTTP challenge.
  * The package's drop-in for caddy.service makes Caddy read that file
    and keeps it from starting before the file exists. The file belongs
    to root and the group caddy, which Caddy runs as, with mode 0640.
  * The firewall opens port 80 on the external interface and the HTTPS
    ports on both interfaces while HTTPS is on.
  * The web service also listens on 127.0.0.1, where Caddy calls it.
  * docker.exposed_ports may not take port 80 or the HTTPS ports while
    HTTPS is on.
  * Removing the package stops and disables caddy; purging it removes
    /etc/caddy/vpn-router.Caddyfile.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 15:00:00 +0200

vpn-router (0.12.3-1) unstable; urgency=medium

  fix: the web service listens on the internal address, the external address or both.

  * web.listen in vpn-router.json sets the interfaces the web service
    listens on: internal, external or both, the default. It is read
    every 30 seconds, so a change takes effect without running setup,
    at the latest when vpn-router-web restarts.
  * The firewall opens the ports of the web service and of the Router
    Manager on the internal and the external interface.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 13:00:00 +0200

vpn-router (0.12.2-1) unstable; urgency=medium

  fix: the web service manages users also when it started before setup.

  * vpn-router-web creates /run/vpn-router when it starts, so the user
    operations take their lock there; started before vpn-router-setup had
    made the directory, they failed with "Read-only file system".

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 12:00:00 +0200

vpn-router (0.12.1-1) unstable; urgency=medium

  fix: the status page shows whether the Router Manager runs.

  * When vpn-router-manager is installed, the services show the state of
    vpn-router-manager, and status is degraded while it is not active.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 11:00:00 +0200

vpn-router (0.12.0-1) unstable; urgency=medium

  feature: every user manages their own account through /account.

  * /account serves the signed-in user, admin or not: GET shows the user
    and whether they are a member of admins; PUT /account/password sets
    the password and POST and PUT /account/otp enrol or replace the TOTP
    enrolment, given the current password and, when enrolled, a current
    code. A wrong one is 403 and counts as a failed login. Tokens of
    vpn-router-token get 403 there.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 10:00:00 +0200

vpn-router (0.11.0-1) unstable; urgency=medium

  feature: the status page shows the Router Manager's version.

  * / and /status show the installed version of vpn-router-manager, as
    manager_version in JSON, or that it is not installed.
  * The services show the state of each PostgreSQL cluster, as
    postgresql@<version>-<cluster>, or postgresql: no cluster without one.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 09:00:00 +0200

vpn-router (0.10.0-1) unstable; urgency=medium

  feature: Manager-only accounts, and the Router Manager's first administrator.

  * vpn-router-user add without the person options, and POST /users without
    them, add a Manager-only account: a name and a password, no names, no
    e-mail address and no certificate, so no VPN access. Giving only some of
    the three is refused. The answers show the kind as manager_only, list
    shows a KIND column, and update refuses a Manager-only account.
  * vpn-router-setup creates the administrator the Router Manager's package
    leaves in /etc/vpn-router-manager/admin.json as a Manager-only account in
    the group admins, which it creates when missing, and removes the file.
  * The directory has the package's own schema, with the auxiliary class
    vpnRouterAccount and the attribute vpnRouterScope. A Manager-only account
    can have an e-mail address: add --email, update --email ('' removes it),
    and email in POST and PUT /users.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 08:00:00 +0200

vpn-router (0.9.2-1) unstable; urgency=medium

  fix: the web service starts once libpq can be found.

  * The web service unit waits, with wait-for-libpq, until libpq is in the
    linker cache before it starts the service, for at most 5 minutes; the
    service imports psycopg at start again.
  * The package starts the web service without waiting for it.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 06:00:00 +0200

vpn-router (0.9.1-1) unstable; urgency=medium

  fix: the web service waits for the PostgreSQL driver instead of failing at start.

  * The web service imports psycopg as the first step of its
    initialization, retrying every 15 seconds and logging the failure while
    libpq cannot be found yet during an installation.
  * vpn-router-user and vpn-router-token load without psycopg; a command
    that needs the token database then reports that the driver cannot be
    loaded, as it reports every failure of that database.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 05:00:00 +0200

vpn-router (0.9.0-1) unstable; urgency=medium

  feature: bootstrap diagnostics on port 17081 during the first setup.

  * vpn-router-bootstrap serves, on port 17081, the setup state, the
    services, the failed units, the addresses, cloud-init status and the end
    of the logs of setup and the web service, as plain text.
  * vpn-router-setup starts it, and the Router Manager's bootstrap on port
    17080, until a run has succeeded, and opens both ports on the internal
    interface; the first successful run writes
    /var/lib/vpn-router/setup.done, closes the ports and stops them. A
    failed run leaves them running.
  * The web service no longer has a starting phase: it creates its key and
    database, then listens.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 04:00:00 +0200

vpn-router (0.8.0-1) unstable; urgency=medium

  feature: the web service creates its key and database itself and shows its starting phase.

  * vpn-router-web makes its signing key and creates the refresh tokens'
    database on its first run, retrying every 15 seconds until PostgreSQL
    answers; vpn-router-setup no longer creates them.
  * Until then / and /status show the web service's phase and its failure,
    with the state, the step and the failure of the last run of
    vpn-router-setup, and every page answers 503.
  * vpn-router-setup records its state, current step and failure in
    /run/vpn-router/setup.json.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 03:00:00 +0200

vpn-router (0.7.1-1) unstable; urgency=medium

  fix: a failing user directory or token database no longer leaves the tunnels down.

  * vpn-router-setup brings up strongSwan and WireGuard before it provisions
    the user directory and the token database. A failure of either no
    longer stops the other steps; setup reports it and fails at the end.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 02:00:00 +0200

vpn-router (0.7.0-1) unstable; urgency=medium

  feature: users sign in to the web service, and only members of admins manage the router.

  * POST /auth signs a user in with the password, and the TOTP code for an
    enrolled user, and answers a 5 minute access token and an 8 hour refresh
    token; /auth/refresh renews them and /auth/logout revokes the refresh
    token.
  * /config, /users and /groups take tokens of users in the group admins,
    and tokens of the new vpn-router-token, which has an admin claim and a
    chosen lifetime. Only these may change the group admins.
  * The tokens are signed with /etc/vpn-router/web.key, which
    vpn-router-setup makes on the router; web.jwt_secret is ignored.
  * Five failed logins lock an account for 15 minutes, for OpenVPN and
    /auth. vpn-router-user unlock and POST /users/<name>/unlock end the
    lockout, and the users show locked.
  * /auth takes at most 10 calls a minute per client address; for calls from
    web.trusted_proxies the address is read from X-Forwarded-For.
  * Users enrolled for TOTP log in to OpenVPN with the password followed by
    the code.
  * Refresh tokens are kept in PostgreSQL, in the database web.database
    names or in the vpn-router database vpn-router-setup creates. The
    package depends on postgresql and python3-psycopg.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sun, 25 Oct 2026 01:00:00 +0200

vpn-router (0.6.0-1) unstable; urgency=medium

  feature: users can be enrolled for TOTP one-time passwords.

  * vpn-router-user otp-new makes a TOTP secret and its otpauth URI,
    otp-enrol stores the secret, read from standard input, given a code of
    it, and otp-remove removes it. list and every answer show whether a user
    is enrolled, as otp.
  * The web service enrols with POST, PUT and DELETE /users/<name>/otp.
  * The secret is kept in the user's entry with the OATH-LDAP schema of
    slapd's otp module; only the user manager account may set it, and no
    one can read it. Logins do not ask for the codes.
  * The package depends on python3-pyotp.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 23:30:00 +0200

vpn-router (0.5.9-1) unstable; urgency=medium

  fix: package upgrades no longer ask the configuration questions.

  * The configuration questions are asked only on a fresh installation and
    by dpkg-reconfigure.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 21:00:00 +0200

vpn-router (0.5.8-1) unstable; urgency=medium

  fix: an upgrade keeps the configuration and asks nothing.

  * postinst passes on only the debconf answers that were given. The
    defaults of questions never asked, such as platform none, no longer
    replace settings of vpn-router.json.
  * Without an answer that changes it, the configuration ucf is given is
    vpn-router.json byte for byte, so an upgrade has no conflict to ask
    about; settings the file leaves out keep their defaults when it is read.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 20:00:00 +0200

vpn-router (0.5.7-1) unstable; urgency=medium

  feature: users have a first name, a last name and an e-mail address.

  * vpn-router-user add needs --first-name, --last-name and --email, kept as
    givenName, sn and mail, with cn set to the first and the last name.
    vpn-router-user update changes them, and list and every answer show
    them as first_name, last_name and email.
  * POST /users needs first_name, last_name and email, and PUT
    /users/<name> changes them.
  * vpn-router-user answers in text: a table of the users, the client
    profile or a short message, with failures on standard error. --json
    gives the JSON answers. -h and --help show the commands and their
    options.
  * The web service manages users with vpnrouter_users, the module
    vpn-router-user uses, instead of running vpn-router-user for each
    request.
  * Groups of users, kept as groupOfNames entries in ou=groups with a
    description and at least one member. vpn-router-group lists, adds,
    renames, describes and removes them and adds and takes out members, and
    the web service serves the same under /groups. Removing a user takes it
    out of its groups and is refused while it is the last member of one.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 19:00:00 +0200

vpn-router (0.5.6-1) unstable; urgency=medium

  update: the status web service listens on port 7081 by default.

  * web.port defaults to 7081.
  * vpn-router-setup opens the Router Manager's port, 7080 by default, on
    the internal interface.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 18:00:00 +0200

vpn-router (0.5.5-1) unstable; urgency=medium

  feature: users and their certificates no longer need a P2S system enabled.

  * vpn-router-setup provisions the user directory, the CA and its CRL once
    a platform is chosen, whether or not OpenVPN or road-warrior access is
    enabled. The server certificate is issued once wan.local_fqdn is set,
    also for an existing CA that has none.
  * /users and vpn-router-user manage users and issue and revoke their
    certificates without a P2S system; only the OpenVPN client profile
    needs OpenVPN.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 16:00:00 +0200

vpn-router (0.5.4-1) unstable; urgency=medium

  feature: the firewall lets the Router Manager in on the internal interface.

  * While vpn-router-manager is installed, vpn-router-setup opens its port,
    port in /etc/vpn-router-manager/manager.json or 8090, on the internal
    interface. Purging the package removes the rule.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 13:00:00 +0200

vpn-router (0.5.3-1) unstable; urgency=medium

  fix: the status always shows the state of slapd.

  * /status and the status page show the state of slapd whether or not
    OpenVPN or road-warrior access is configured, since the package always
    runs it.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 12:00:00 +0200

vpn-router (0.5.2-1) unstable; urgency=medium

  fix: /config no longer shows secret options.

  * The configuration shown by /config leaves out the secret options (psk,
    jwt_secret, and options named like a password, token or key) instead of
    showing them masked.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 11:00:00 +0200

vpn-router (0.5.1-1) unstable; urgency=medium

  fix: the web service works in every state of the router.

  * vpn-router-web works whether /etc/vpn-router/pki and
    /etc/swanctl/x509crl exist or not; they exist only while OpenVPN or
    road-warrior access is configured. The paths the unit may write are
    used when they exist and ignored when they do not.
  * vpn-router-web starts on its own and keeps running. Every 30 seconds a
    discovery thread works out the internal address from vpn-router.json as
    general.mode directs, with web.port and web.enabled, and starts, moves
    or stops the server thread to match. Each request reads the token
    secret, the features and the facts it shows. The service is no longer
    ordered after vpn-router-setup, which no longer restarts it, and
    web.json no longer holds the address, the port or the secret.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Sat, 24 Oct 2026 10:00:00 +0200

vpn-router (0.5.0-1) unstable; urgency=medium

  * OpenVPN P2S access, set in the openvpn section (enabled, address_pool,
    port, protocol). Clients need a certificate of the router CA and the
    password of the user named in it; the password is checked against a
    local LDAP directory by openvpn-auth-ldap.
  * The users live in the package's own slapd database, dc=vpn-router,
    dc=local, which vpn-router-setup provisions while OpenVPN or road-warrior
    access is configured. slapd listens on its local socket only. Passwords
    are stored as ARGON2 hashes, and a disabled user is locked with the
    password policy.
  * vpn-router-user lists, adds, disables, enables and removes users, sets
    passwords and gives OpenVPN client profiles. Adding a user also issues
    the user's client certificate; removing one revokes it.
  * The web service manages users under /users, with the same token as
    /config, and /status shows the OpenVPN clients.
  * The CA gets a certificate revocation list when it is created, and an
    existing CA without one gets one.
  * Purging the package removes the firewall rules of the web service, which
    it left behind before.
  * The status page follows the browser's light or dark colour scheme,
    uses a proportional font and reloads itself every minute.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 23:00:00 +0200

vpn-router (0.4.3-1) unstable; urgency=medium

  * swanctl output with more closing than opening lines is read as not
    available instead of failing the request.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 22:00:00 +0200

vpn-router (0.4.2-1) unstable; urgency=medium

  * /config gives the IPsec connections and SAs as objects, read from
    swanctl --pretty, and the routes as objects from ip -j, instead of
    lines of text. The site-to-site and road-warrior state of /status is
    counted from the same swanctl objects.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 21:30:00 +0200

vpn-router (0.4.1-1) unstable; urgency=medium

  * Fix the start of vpn-router-setup hanging on a host that runs Docker.
    vpn-router-setup restarted vpn-router-docker and waited for it, but that
    unit was ordered after vpn-router-setup, so each waited for the other,
    the installation of the package never finished and vpn-router-web was
    never enabled or started. vpn-router-docker is no longer ordered after
    vpn-router-setup, so vpn-router-setup still waits for it and the Docker
    rules are in place when it ends. The restart of vpn-router-web is queued
    without waiting.
  * Start vpn-router-setup after docker.service, so that Docker is up when
    the setup looks for it and does not start in parallel with it. The
    ordering applies only when Docker is installed.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 20:10:00 +0200

vpn-router (0.4.0-1) unstable; urgency=medium

  * Add the vpn-router-web service, a small status web service that uses only
    the Python standard library. It listens on the internal address and on
    web.port, 8080 by default. / shows the state of the router for people,
    as plain text for curl and wget and as a Tailwind CSS page for a
    browser, and /status shows the same as JSON: the state of the services,
    the package version, whether Docker is installed, and the state of
    site-to-site, road-warrior and WireGuard, with no configuration data.
  * Add the web configuration section. web.enabled (true by default) and
    web.port. vpn-router-setup opens the port on the internal interface in
    UFW and restarts the service.
  * Add /config to the status web service, for a client such as manage-ui. It
    shows the configuration with its secrets masked, the interfaces,
    addresses, identities and routes the router resolved, the IPsec
    connections and SAs, the WireGuard peers (no keys) and the Docker rules.
    It needs a JWT signed with HS256 by web.jwt_secret, with an exp claim
    within ten minutes, and is not served while web.jwt_secret is not set.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 19:00:00 +0200

vpn-router (0.3.2-1) unstable; urgency=medium

  * Accept an IPv4 or IPv6 address as remote.id and as wan.local_fqdn. The
    identities are written to the strongSwan configuration as given, without
    an @ added, and strongSwan reads an address as an IP identity and a name
    as an FQDN. A value that starts with @ is refused with an error, since
    strongSwan 5.0 and later need no @ to avoid resolving a name.
    Road-warrior access still needs a name in wan.local_fqdn.
  * Depend on strongswan-swanctl and charon-systemd 5.0 or later.

 -- Slawomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 18:00:00 +0200

vpn-router (0.3.1-1) unstable; urgency=medium

  * Ignore virtual interfaces when mode auto looks for the internal
    interface. The Docker bridge docker0, which has an address, was counted
    as a second internal interface, so vpn-router-setup and
    vpn-router-docker failed on a host with Docker installed.

 -- Sławomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 13:44:00 +0200

vpn-router (0.3.0-1) unstable; urgency=medium

  * Secure the ports Docker publishes. Rules in a chain of their own,
    VPN-ROUTER-DOCKER, entered by a jump at the top of DOCKER-USER, accept
    IPsec protected traffic, TCP to docker.exposed_ports and established
    connections from the external interface and drop the rest of it. Other
    rules in DOCKER-USER are left alone. The rules cover IPv4 only.
  * Add the docker configuration section. docker.mode is auto (the default,
    secures Docker when docker.service is installed), on (requires Docker) or
    off (removes the rules); docker.exposed_ports lists the TCP ports and port
    ranges reachable from the external interface, none by default.
  * Add the vpn-router-docker service, which applies the Docker rules after
    docker.service starts and removes them when it stops. vpn-router-setup
    restarts it while Docker runs, so a changed configuration takes effect.
  * Installing Docker before this package is recommended. When Docker is
    installed later, restart vpn-router-setup to apply the rules.

 -- Sławomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 12:44:45 +0200

vpn-router (0.2.0-1) unstable; urgency=medium

  * Change the configuration file to JSON, /etc/vpn-router/vpn-router.json.
    Lists are arrays, booleans and the WireGuard listen port are native JSON
    types, and unknown sections, unknown settings and wrong value types are
    rejected.
  * Replace remote.psk_b64 with remote.psk, holding the pre-shared key as a
    plain string. remote.psk_file still takes precedence.
  * Ship /usr/share/doc/vpn-router/vpn-router.json.example in place of
    vpn-router.conf.example.
  * Add platform "none" as the default, so installing the package changes
    nothing on the machine until a platform is chosen.
  * Add the mode setting (manual, interfaces, auto) controlling how much of
    the network configuration is supplied and how much is read from the
    system.
  * Manage the configuration file with ucf, so dpkg-reconfigure reapplies
    debconf answers without overwriting local edits.
  * Apply NAT and forward rules to every local subnet, not only the first.

 -- Sławomir Koszewski <slawek@koszewscy.waw.pl>  Fri, 23 Oct 2026 08:00:06 +0200

vpn-router (0.1.0-1) unstable; urgency=medium

  * Initial release.

 -- Sławomir Koszewski <slawek@koszewscy.waw.pl>  Tue, 26 May 2026 00:00:00 +0200
