Commit Graph

39 Commits

Author SHA1 Message Date
Daniel Redetzke 9ecc188269 Keep IPv6 router announcements working with forwarding on
With net.ipv6.conf.all.forwarding=1, Linux ignores router announcements
unless accept_ra is 2, so a server that gets its IPv6 route by SLAAC
(e.g. a Raspberry Pi at home) lost IPv6 once the route expired.

The sysctl file now also sets accept_ra=2 for the default and for every
network card and the IPv6 default-route interface, except where
accept_ra is 0. "update" rewrites the file, which fixes existing
installs. A new health check warns while the uplink still has
accept_ra=1.
v0.3.2
2026-10-05 00:10:13 +03:00
Daniel Redetzke ebd3ceacd7 README: dashboard screenshot from v0.3.1 2026-10-04 23:01:17 +03:00
Daniel Redetzke c218a9665b README: bring iOS app, tokens, config.json and lockout up to date 2026-10-04 22:54:48 +03:00
Daniel Redetzke 436485d627 README: keep only the dashboard screenshot 2026-10-04 22:50:13 +03:00
Daniel Redetzke 490d055cec Delete stored security keys v0.3.1 2026-10-04 22:35:19 +03:00
Daniel Redetzke 56978b28e9 Passkeys only: drop adding security keys 2026-10-04 22:13:31 +03:00
Daniel Redetzke 2cbe344d74 Japanese hover label on the passkey button 2026-10-04 22:03:12 +03:00
Daniel Redetzke 3e44022b0b Two-step sign-in: authenticator app, security keys and passkeys v0.3.0 2026-10-04 21:55:53 +03:00
Daniel Redetzke 1e8175cad4 Drop the tagline from the sign-in page 2026-10-04 21:02:37 +03:00
Daniel Redetzke f5e0da5ccd Fingerprint app.js, setup.js and app.css 2026-10-04 20:56:35 +03:00
Daniel Redetzke 542ee98a85 Sortable peers table, shorter connection history 2026-10-04 20:53:56 +03:00
Daniel Redetzke 82228faeba More web interface pages 2026-10-04 20:47:12 +03:00
Daniel Redetzke 6afef85b2b Full-access tokens manage users, passwords and tokens v0.2.0 2026-10-04 20:37:46 +03:00
Daniel Redetzke 207f3f4172 Sign out from an icon in the account row 2026-10-04 20:21:00 +03:00
Daniel Redetzke bbbef00329 Web interface setting 2026-10-04 20:16:57 +03:00
Daniel Redetzke 606b3fe89f Keep the sidebar in view on long pages
Beside the page, the sidebar now stays in place while the page scrolls,
so the account link and Sign out are always visible; it scrolls by
itself in very short windows. On a phone it still stacks above the page.
Also show the version with one 'v': release builds already start with it.
v0.1.1
2026-10-04 16:36:30 +03:00
Daniel Redetzke c7340d011a README: screenshots of the web interface
Seven pages captured from a demo instance with sample data from the
simulator: dashboard (under the introduction), peers, peer, server,
settings, my account and sign-in. Images live in screenshots/.
2026-10-04 16:31:01 +03:00
Daniel Redetzke 9220ff54aa README: show the Hannya logo at the top 2026-10-04 16:14:54 +03:00
Daniel Redetzke 19008f8a33 My account page
The signed-in user's profile, password and own app tokens move from the
Settings card to their own page at #/account, ready for more user
functions. The sidebar footer links to it with the user's name. Users
can now set their own note; the page header shows when and from where
the session started, which the server now records. Settings keeps the
Users table, where your own row links to My account.
v0.1.0
2026-10-04 16:07:21 +03:00
Daniel Redetzke 4ecfddf06a Multiple users, all admins
The single admin account becomes a list of users; config.json moves to
version 2 and the old admin is migrated on first start. Every user is an
admin. Sessions are tied to a user and their password, so deleting a user
or resetting a password signs them out at once. API tokens belong to the
user who made them and go away with that user.

Admins add users with a temporary password and choose whether it must be
changed at first sign-in; until then the API refuses everything but the
password change. Settings gets My account and Users cards, and the token
table shows each token's owner. 'GHOSTWIRE passwd [username]' resets any
user's password. A failed update now also restores config.json, since the
new version may have upgraded it.
2026-10-04 15:51:14 +03:00
Daniel Redetzke f703618b9d Hannya mark and Shippori Mincho B1 wordmark
Replace the Kamon ghost with the horned Hannya mask in favicon.svg,
apple-touch-icon.png, the web UI and the setup page. The wordmark and
katakana use Shippori Mincho B1 ExtraBold, bundled as a subset (ASCII
and katakana, 21 KB) under the SIL OFL and served from the binary.
2026-10-04 15:06:18 +03:00
Daniel Redetzke 7391aac429 Peers: optional latency check with per-peer setting
The server pings a peer's tunnel address every 30 s and shows the median
of the last 5 minutes in the peer list (with a 1-hour sparkline) and a
24-hour chart on the peer page. Off by default; "active" pings only
while the device sends traffic, "always" keeps the tunnel up.
2026-10-04 14:28:44 +03:00
Daniel Redetzke b0be0b0ceb Move the iOS app to its own GHOSTWIRE-Companion repo 2026-10-04 12:10:45 +03:00
Daniel Redetzke 8bc2440e40 Show the Sign in button's label in katakana on hover 2026-10-04 02:36:17 +03:00
Daniel Redetzke 665fb9c916 Keep the login button's text dark on hover 2026-10-04 02:34:29 +03:00
Daniel Redetzke 3e9b9c8a1a Sidebar logo links to the start page 2026-10-04 02:31:36 +03:00
Daniel Redetzke 3a93ec35ee Health: show IPv6 uplink and public IPv4/IPv6 addresses
The uplink check only reported the IPv4 default route. Split it into
IPv4 and IPv6 uplink rows, and add a public address row for each, read
from the uplink interface (private addresses are shown as behind NAT).
2026-10-04 00:39:13 +03:00
Daniel Redetzke 7d4cd48ca4 Interactive install, with flags kept for unattended installs
In a terminal, install now asks for the domain, Let's Encrypt email,
endpoint, WireGuard port and admin password, shows a summary and changes
nothing until confirmed. Re-runs offer the current settings and say how
many devices need a new config when the endpoint or port changes.

Flags still work and skip their question; -y or no terminal skips all
questions. New -port flag sets the WireGuard UDP port. Every value is
checked before the system is touched.
2026-10-03 23:46:04 +03:00
Daniel Redetzke 5feb73100f iOS: show the peer list's Delete swipe action in red
The app-wide ink tint overrode the destructive role's red.
2026-10-03 23:34:39 +03:00
Daniel Redetzke 28415b867e iOS: create and manage setup links like the web interface
Add peer and Issue new config offer the same choice as the web UI: show
the config now or send a one-time setup link (1 h, 24 h or 7 d, PIN on by
default). The link sheet shares the link through the iOS share sheet and
shows the PIN, expiry and a QR code of the link. The peer page gets a
setup link card with share, copy and revoke.
2026-10-03 23:29:28 +03:00
Daniel Redetzke ef1988e4d0 Add one-time setup links as an alternative to the QR code
A config can now be handed over as a one-time link, valid for 1 h, 24 h or
7 days and protected by a PIN by default. Keys are made only when the link
is opened; the link works once and is revoked after 5 wrong PINs. Issuing a
new config offers the same choice, and the current config keeps working
until the link is used.

Remove the option to paste a client's public key, in the web UI, the API
and the iOS app.
2026-10-03 23:10:28 +03:00
Daniel Redetzke 55aaaa3a78 Prepare README for public release and add MIT license 2026-10-03 20:14:38 +03:00
Daniel Redetzke 31629fe904 Redesign login page: dark single column with stacked logo 2026-10-03 20:08:47 +03:00
Daniel Redetzke c620606258 Remove sign-in heading and lockout hint from login form 2026-10-03 20:03:32 +03:00
Daniel Redetzke 37ab26b415 Add connection history per peer with country and network lookup
- The stats sampler records sessions per peer: start, end, address and
  traffic. A session ends when the peer goes quiet or is disabled; a new
  one starts when the device changes networks. Stored in stats.json and
  kept as long as the daily traffic history (max 1000 per peer).
- Country and network operator come from the free DB-IP Lite databases
  (CC BY 4.0), downloaded monthly and looked up locally, so peer
  addresses never leave the server. Settings → Data retention can switch
  this off, which deletes the databases.
- API: GET /peers/{id}/sessions; peer stats include the current location;
  settings include the database status.
- Web UI and iOS app: connection history card, location line, country
  code in the peer list (web), switch in data retention.

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
2026-10-03 19:21:10 +03:00
Daniel Redetzke f31bb360c9 Add native iOS app with App Store preparation
iOS app (ios/, SwiftUI, iOS 17+) in the web UI's styling with the Kamon
logo. It covers everything the web interface does except password, API
tokens and backups: dashboard, peers with search and filter, peer detail
with traffic charts, add/edit peers, one-time config with QR code and
share sheet, server settings with apply bar, app settings, data
retention and log viewer.

- Pairing by QR code or pasted pairing code; token kept in the keychain;
  self-signed certificates are pinned by SHA-256 fingerprint.
- Colour providers and logo drawing are nonisolated: SwiftUI's background
  renderer calls them, and main-actor closures crashed there when the
  camera scanner was open.
- App Store: version 1.0, export compliance, privacy manifest, app icon,
  release.sh (archive and upload), listing text, review notes and 6.9"
  screenshots in ios/AppStore.

Server:
- Full-access API tokens may use settings, logs and restart; password,
  tokens, backup/restore and the admin username stay admin-only.
- Web pairing dialog gains "Copy pairing code".
- The development simulator reports health checks in Linux wording.

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
2026-10-03 18:34:41 +03:00
Daniel Redetzke 1543069089 Make log and traffic retention configurable; limit DNS presets to Quad9
- Settings → Data retention: log file size, number of old log files,
  hourly and daily traffic history. Stored as log and stats in
  config.json, validated, and applied without a restart; lowering a
  limit deletes older log files and history after confirmation.
- Traffic history is now pruned by time instead of by bucket count.
- Server page DNS provider list offers only Quad9 and Custom.

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
2026-10-03 17:48:33 +03:00
Daniel Redetzke b394a6d5d9 Add Kamon logo as favicon and brand mark; fix MTU and UI issues
- Kamon logo (crest ring around the ghost) as favicon.svg, 180 px
  apple-touch-icon.png and the brand lockup in sidebar and login page,
  with the katakana reading ゴーストワイヤー
- /favicon.ico redirects to /favicon.svg
- Client configs no longer set an MTU; each device picks its own, as
  pivpn does. Server MTU changes no longer require reissued configs.
- Fix "null" rendered on the dashboard, wrapping activity times, and show
  log lines as readable text instead of raw JSON

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
2026-10-03 17:12:27 +03:00
Daniel Redetzke 4793e8dfba GHOSTWIRE 0.1.2: WireGuard server manager with web UI and API
Single Go binary that manages a WireGuard server based on pivpn's defaults:
- config.json as the single source of truth, reconciled to the kernel via
  netlink, wgctrl and its own nftables table (NAT, forward, input)
- web interface (dashboard, peers, peer detail, add peer, server, settings)
  and a JSON API for the future iOS app, with session and API-token auth
- client private keys are never stored; configs and QR codes shown once
- per-peer traffic statistics in stats.json, logs in GHOSTWIRE.jsonl
- HTTPS via Let's Encrypt, self-signed, certificate files or off
- self-managing: install, update (restores the old binary on failure),
  uninstall and passwd subcommands; systemd unit generated by the binary

Tested end to end on Ubuntu 26.04 (kernel 7.0) at dev.redetzke.aero.

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
2026-10-03 16:54:37 +03:00