Files
OpenGFW/web/README.md
T
meiandClaude Opus 5 5a7722d1d2 feat: add embedded web UI
Adds an optional web dashboard served by OpenGFW itself, enabled with a new
`web` section in the config file.

Backend (web package, decoupled from engine/io so it builds on any OS):
- hub.go collects statistics off the engine logger callbacks: atomic counters,
  two ring-buffered time series (10s and 1min buckets), top N hosts/blocked
  destinations/rules/analyzers, and a 512 entry event buffer fanned out to
  connected clients over SSE. Slow clients drop frames instead of blocking
  the engine.
- api.go exposes /api/v1 for info, meta, metrics, events, the SSE stream and
  ruleset read/validate/replace.
- auth.go implements password login with in-memory session tokens and login
  rate limiting. Mutating endpoints require the bearer token (the session
  cookie is only accepted for GET), which makes them CSRF-safe.
- cmd/web.go implements the rule manager: rules are compiled before anything
  is written, the file is replaced atomically and the engine is hot reloaded.
  The SIGHUP handler now shares that same path.
- web/devserver serves the UI with synthetic traffic for frontend work on
  machines where the engine itself cannot be built.

Frontend (web/frontend, Vue 3 + Vite + Tailwind CSS v4 + Reka UI):
dashboard, live event feed with analyzer property inspection, visual and YAML
rule editors, analyzer overview and settings. Responsive down to phone sizes
with a bottom tab bar and bottom-sheet dialogs, plus light/dark themes and
English/Chinese translations.

The built UI in web/dist is committed and embedded with go:embed so that
`go build` works without Node; CI builds the frontend and checks that the
committed output is up to date.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 08:09:11 +08:00

3.6 KiB

OpenGFW Web UI

A Vue 3 + Tailwind CSS dashboard for OpenGFW, built with shadcn/ui style components on top of Reka UI primitives. It is embedded into the OpenGFW binary and served by the web package.

  • Dashboard — live counters, traffic chart, verdict/protocol split, top hosts, blocked destinations and triggered rules
  • Events — real-time feed of verdicts, rule logs and errors with filters and a detail view showing raw analyzer properties
  • Rules — visual rule editor and a raw YAML editor, both validated by the engine itself; saving writes the rule file and hot reloads the running engine
  • Analyzers — which analyzers are compiled in and how much traffic each one saw
  • Settings — theme (light/dark/system), language (English/中文) and instance info

The layout is responsive: a sidebar on desktop, a bottom tab bar and bottom-sheet dialogs on phones.

Enabling it

# config.yaml
web:
  enabled: true
  listen: :8080
  secret: your-password-here
  # cert: /path/to/fullchain.pem
  # key: /path/to/privkey.pem

If secret is empty a random password is generated and printed to the log on startup.

Layout

web/
├── api.go          HTTP handlers (JSON API + SSE)
├── auth.go         password login, session tokens
├── hub.go          statistics collection and the live event fan-out
├── server.go       routes, static file serving, public types
├── embed.go        //go:embed of dist
├── devserver/      standalone server with synthetic data (any OS)
├── dist/           built UI, embedded into the binary (committed)
└── frontend/       Vue sources

Development

The engine only builds on Linux, so for UI work there is a standalone server that feeds the UI synthetic traffic and an in-memory ruleset:

go run ./web/devserver     # http://127.0.0.1:8080, password: opengfw

Then, in another terminal, run Vite with hot reload (it proxies /api to :8080):

cd web/frontend
npm install
npm run dev

To produce the embedded build (this is what make web runs):

cd web/frontend && npm run build   # writes ../dist

web/dist is committed so that go build works without Node installed. Rebuild it whenever you change the frontend.

API

All endpoints live under /api/v1 and return JSON. Except for login, every request must carry Authorization: Bearer <token>; GET endpoints also accept the session cookie set at login, which is what the EventSource connection uses. Mutating endpoints only accept the bearer token, which makes them immune to CSRF.

Method Path Description
POST /login exchange the password for a session token
POST /logout invalidate the current session
GET /info version, platform and engine configuration
GET /meta available analyzers, modifiers, actions, functions
GET /metrics counters, time series and top N lists
GET /events?limit= recent events from the ring buffer
GET /live server-sent events: event and metrics frames
GET/PUT /rules read / replace the ruleset (raw YAML or rules)
POST /rules/validate compile without applying; also converts YAML ⇄ rules