admin

package
v1.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

CaptchaBroker mediates VK Calls captcha challenges between the inbound runners (the "asker") and the operator's browser (the "solver"). When an inbound's auth chain hits a captcha:

  1. The vkcalls AdminWebviewCaptchaSolver calls Broker.Register, gets back a proxy URL + a wait channel
  2. Broker mounts a per-challenge reverse-proxy at /captcha-proxy/<id>/ using vkauth.MountAdminCaptchaProxy, so the operator's browser can navigate to the challenge with the same JS-shim experience as AutoProxy.
  3. Admin UI surfaces a pending-captcha badge with the proxy URL.
  4. Operator opens it, solves the I-am-not-a-robot click, the JS shim posts the captured success_token to /captcha-proxy/<id>/local-captcha-result. The proxy's onToken callback fires the wait channel; the solver returns; auth retries.
  5. Tokens expire fast (~1 min) — Broker.expireOldChallenges() sweeps stale entries and closes their channels so nobody hangs.

Concurrent challenges are isolated by a per-id URL path (/captcha-proxy/{id}). Multiple inbounds can be solving captchas at once — they get their own entries in Pending() and their own open-in-browser links.

Package admin is the HTTP control panel for goloom-wg-server.

Endpoints:

GET    /                                dashboard HTML
GET    /static/style.css                styling
GET    /login                           login form
POST   /login                           username+password → session cookie
POST   /logout                          revoke session cookie
GET    /api/admin/state                 { username, is_default_password }
POST   /api/admin/password              change password (current+new)
GET    /api/inbounds                    list (JSON)
POST   /api/inbounds                    create
DELETE /api/inbounds/{id}               remove
POST   /api/inbounds/{id}/toggle        pause/resume
GET    /api/inbounds/{id}/client.conf   wg client config
GET    /api/inbounds/{id}/connstr       goloom:// connection string
GET    /api/inbounds/{id}/qr.png        QR PNG of the connection string
GET    /api/inbounds/{id}/vkturn-link   vkturnproxy:// link (anton48 clients)
GET    /api/inbounds/{id}/vkturn-qr.png QR PNG of the vkturnproxy:// link
GET    /api/inbounds/{id}/history       per-inbound traffic samples
GET    /api/system/wg-interfaces        live wg interface list

Auth is username + password (bcrypt-hashed) stored in a JSON file alongside the YAML config. On first start a random "admin" password is generated and printed to the log; the operator changes it via the dashboard. Sessions are in-memory (revoked on server restart).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CaptchaBroker

type CaptchaBroker struct {
	// contains filtered or unexported fields
}

CaptchaBroker is the admin-side captcha mediator. Implements vkauth.AdminCaptchaBroker.

func NewCaptchaBroker

func NewCaptchaBroker() *CaptchaBroker

NewCaptchaBroker returns a fresh broker. AttachToMux must be called once before Register can be used.

func (*CaptchaBroker) AttachToMux

func (b *CaptchaBroker) AttachToMux(mux *http.ServeMux)

AttachToMux installs the broker's HTTP routes on mux:

GET  /captcha-proxy/{id}/...   — per-challenge reverse-proxy +
                                 JS shim, mounted dynamically by
                                 [Register].
GET  /api/captcha/pending      — JSON list of pending challenges

Must be called exactly once. Subsequent Register calls require this.

func (*CaptchaBroker) Pending

func (b *CaptchaBroker) Pending() []PendingCaptcha

Pending returns a snapshot of the in-flight challenges for the admin UI / API.

func (*CaptchaBroker) Register

func (b *CaptchaBroker) Register(ctx context.Context, ch sfu.VKCaptchaChallenge, tag string) (string, <-chan string)

Register implements vkauth.AdminCaptchaBroker. Called by vkauth.AdminWebviewCaptchaSolver each time an inbound auth chain hits a captcha challenge.

func (*CaptchaBroker) SetFingerprintSink

func (b *CaptchaBroker) SetFingerprintSink(sink vkauth.CaptureSink, lg *log.Logger)

SetFingerprintSink включает перехват browser_fp/device/UA на captcha-proxy для всех будущих challenges. Должно вызываться один раз при старте сервера, до первого Register; thread-safe но менять sink в runtime нет смысла. Передай nil чтобы выключить.

type CredentialStore

type CredentialStore struct {
	// contains filtered or unexported fields
}

CredentialStore wraps Credentials with a path and a mutex so that the password-change endpoint can persist atomically.

func LoadOrInit

func LoadOrInit(path string) (store *CredentialStore, defaultPassword string, err error)

LoadOrInit returns a store backed by `path`. If the file does not exist, a fresh `admin` user is created with a 16-byte hex-encoded random password and IsDefaultPassword=true. The plaintext default password is returned (only on first init) so the caller can print it once for the operator — it cannot be recovered later.

func (*CredentialStore) ChangePassword

func (s *CredentialStore) ChangePassword(newPassword string) error

ChangePassword swaps the stored hash. Caller is responsible for verifying the *current* password through Verify first.

func (*CredentialStore) State

func (s *CredentialStore) State() Credentials

State returns a non-secret snapshot for the UI (no password hash).

func (*CredentialStore) Verify

func (s *CredentialStore) Verify(username, password string) bool

Verify returns true if `password` matches the stored hash for `username`. Constant-time username comparison; bcrypt is naturally constant-time.

type Credentials

type Credentials struct {
	Username     string `json:"username"`
	PasswordHash string `json:"password_hash"`
	// IsDefaultPassword stays true until the operator changes the
	// auto-generated bootstrap password. The dashboard renders a "change
	// me" banner while this is set.
	IsDefaultPassword bool `json:"is_default_password"`
}

Credentials describes who can sign into the admin panel. Stored on disk separately from the YAML config (bcrypt hash + flags), so panel- initiated password changes don't churn the YAML on every save.

type Options

type Options struct {
	Listen         string
	Credentials    *CredentialStore
	TLSCert        string
	TLSKey         string
	AutoSelfSigned bool
	Manager        *inbound.Manager
	Provisioner    *wgprovision.Provisioner
	Logger         *log.Logger

	// PublicEndpointHint fills in [Peer] Endpoint when generating
	// client wg-quick configs. For the goloom architecture this is
	// always loopback because the user runs the joiner locally; a
	// future direct-WG mode would use the VPS's public IP here.
	PublicEndpointHint string

	// PublicURL — внешний URL admin-сервера. Используется для построения
	// public ссылок на UI (admin dashboard, client connstrs где нужно
	// показать оператору). Пример: "https://vps.example.com:9443".
	// Если пусто — fallback на Listen со схемой https.
	PublicURL string

	// CaptchaBroker, when non-nil, exposes the VK Calls admin-webview
	// captcha solver via /captcha-proxy/<id>/* and /api/captcha/*.
	// The broker is also passed into the inbound.Manager so VK
	// inbounds with captcha_mode=admin-webview can delegate solves to
	// the operator's browser. nil disables the admin-webview path
	// (auto/none modes still work via the Manager's other knobs).
	CaptchaBroker *CaptchaBroker
}

type PendingCaptcha

type PendingCaptcha struct {
	ID           string    `json:"id"`
	InboundTag   string    `json:"inbound_tag,omitempty"`
	ProxyURL     string    `json:"proxy_url"`
	RegisteredAt time.Time `json:"registered_at"`
	ExpiresAt    time.Time `json:"expires_at"`
}

PendingCaptcha is the JSON-friendly view of an in-flight challenge.

type Server

type Server struct {
	// contains filtered or unexported fields
}

func New

func New(opts Options) (*Server, error)

func (*Server) Run

func (s *Server) Run(ctx context.Context) error

Directories

Path Synopsis
ui
components
templ: version: v0.3.1001
templ: version: v0.3.1001
pages
templ: version: v0.3.1001
templ: version: v0.3.1001

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL