wgprovision

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: 12 Imported by: 0

Documentation

Overview

Package wgprovision provisions WireGuard interfaces from goloom-wg-server: generates keypairs, allocates subnets/ports from a pool, writes wgN.conf files, and brings interfaces up via wg-quick. Linux-only — Windows just uses the existing official client.

This is the engine behind the admin panel's "Add Inbound" flow: instead of asking the operator to manually run `wg genkey`, edit /etc/wireguard, `systemctl start wg-quick@wg1`, etc., they click a button and we do it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IfaceFor

func IfaceFor(idx int) string

IfaceFor returns the conventional wgN interface name for a given index.

Types

type Allocation

type Allocation struct {
	Iface      string // "wg1"
	IfaceIndex int    // 1
	Subnet     string // "10.66.66.0/24"
	ServerIP   net.IP // 10.66.66.1
	ClientIP   net.IP // 10.66.66.2
	Port       int    // 51820
	Server     KeyPair
	Client     KeyPair

	// PresharedKey — optional 32-byte base64 PSK. Empty by default;
	// caller (e.g. admin handler for vk-turn inbounds) may set this
	// before [CreateInterface] to bake `PresharedKey = …` into the
	// peer section of the wg-quick config.
	PresharedKey string
}

Allocation describes one freshly-provisioned WG endpoint.

type InterfaceInfo

type InterfaceInfo struct {
	Name        string `json:"name"`
	ListenPort  int    `json:"listen_port"`
	PublicKey   string `json:"public_key"`
	NumPeers    int    `json:"num_peers"`
	UpSeconds   int    `json:"up_seconds"`
	HasConfFile bool   `json:"has_conf_file"`
}

InterfaceInfo describes one wgN interface as seen by `wg show`.

func InspectInterfaces

func InspectInterfaces() []InterfaceInfo

InspectInterfaces shells out to `wg show all dump` and returns one entry per active WG interface. Lightweight enough to call on every panel refresh without blowing up CPU.

type KeyPair

type KeyPair struct {
	Private string
	Public  string
}

KeyPair holds a Curve25519 keypair in the same base64 form WireGuard uses on the wire (wg pubkey output).

func GenerateKeyPair

func GenerateKeyPair() (KeyPair, error)

GenerateKeyPair produces a fresh WireGuard-compatible keypair. Equivalent to `wg genkey | tee priv | wg pubkey` but pure-Go so we don't shell out for every inbound creation.

type PortAllocator

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

PortAllocator hands out unique UDP ports for WG endpoints.

func NewPortAllocator

func NewPortAllocator(base int) *PortAllocator

func (*PortAllocator) Allocate

func (p *PortAllocator) Allocate() (int, error)

func (*PortAllocator) Release

func (p *PortAllocator) Release(port int)

func (*PortAllocator) Reserve

func (p *PortAllocator) Reserve(port int)

type Provisioner

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

Provisioner is the high-level API the admin panel uses.

CreateInbound:

  1. allocates a /24 + UDP port + wgN name
  2. generates server+client keypairs
  3. writes /etc/wireguard/wgN.conf
  4. systemctl start wg-quick@wgN

DeleteInbound undoes all of that.

All file/system operations are gated behind a sync.Mutex because multiple admin requests can race.

func NewProvisioner

func NewProvisioner(subnetBase string, portBase int, externalIface string) (*Provisioner, error)

func (*Provisioner) Allocate

func (p *Provisioner) Allocate() (*Allocation, error)

Allocate reserves the next free (subnet, port, iface) triple WITHOUT touching the filesystem yet. CreateInbound persists it.

func (*Provisioner) ClientConfig

func (p *Provisioner) ClientConfig(a *Allocation, dns []string, publicEndpoint string) string

ClientConfig builds a wg-client.conf the user pastes into their WireGuard app. publicEndpoint is what the user's WG dials — for the goloom architecture this is "127.0.0.1:51820" because they run the joiner locally; for a direct WG setup it'd be "<vps_public_ip>:port".

func (*Provisioner) CreateInterface

func (p *Provisioner) CreateInterface(a *Allocation) error

CreateInterface writes /etc/wireguard/<iface>.conf and brings the interface up. The MASQUERADE rule covers only the inbound's /24.

func (*Provisioner) DestroyInterface

func (p *Provisioner) DestroyInterface(iface, subnet string, port int) error

DestroyInterface stops the interface and removes its config file. Releases pool resources so the next inbound can reuse them.

func (*Provisioner) ExternalIface

func (p *Provisioner) ExternalIface() string

ExternalIface returns the egress interface name MASQUERADE rules use.

func (*Provisioner) Reserve

func (p *Provisioner) Reserve(subnet, iface string, port int)

Reserve marks an existing inbound's resources as in-use. Called at startup once for each inbound loaded from disk.

type SubnetAllocator

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

SubnetAllocator hands out non-overlapping /24 subnets from a /16 (or larger) pool. Tracks which /24 indexes are in use so removed inbounds can give them back.

func NewSubnetAllocator

func NewSubnetAllocator(baseCIDR string) (*SubnetAllocator, error)

func (*SubnetAllocator) Allocate

func (a *SubnetAllocator) Allocate() (string, error)

Allocate returns the next free /24 inside the pool.

func (*SubnetAllocator) Release

func (a *SubnetAllocator) Release(cidr string)

Release frees a previously allocated /24 so it can be re-handed.

func (*SubnetAllocator) Reserve

func (a *SubnetAllocator) Reserve(cidr string) error

Reserve marks the given /24 inside the pool as used. Used at startup when reading existing inbounds back from config.

Jump to

Keyboard shortcuts

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