Files
wireguard-ui/README.md
T
2026-10-21 09:13:59 +01:00

301 lines
13 KiB
Markdown

# Wireguard UI
An admin dashboard for Wireguard — manage hosts, clients, tunnels, and IP rules through a web interface.
## Features
- **Host Management** — Create and configure WireGuard hosts with public keys, IP addresses, and listen ports
- **Client Management** — Add clients per host with WireGuard configs, allowed IPs, and notes
- **Client Rules** — Define IP table rules per client (rule type, destination, ports, protocol)
- **Media Management** — Upload and manage media assets (images, documents, etc.) with tagging, thumbnails, and RAG ingestion
- **User Management** — Multi-user support with role-based access (user types)
- **Persistent Storage** — SQLite database with automatic schema generation
- **WebSocket Support** — Real-time updates via WebSocket connections
- **Responsive UI** — Tailwind CSS v4 with twui design system components
## Prerequisites
- **Bun** 1.3.1 or later ([install](https://bun.sh/install))
- **SQLite** (via `@moduletrace/bun-sqlite`)
- **git**
- **zip** and **unzip**
- **Linux** (Debian, Ubuntu, Fedora, Arch, Alpine, or similar)
- Root access (for installation script and system service setup)
## Installation
### Automatic (Recommended)
Run the install script on a fresh machine:
```bash
curl -fsSL https://url.tben.me/wg-ui | sudo bash
```
Or clone the repo and run the script manually:
```bash
git clone https://git.tben.me/Moduletrace/wireguard-ui.git
cd wireguard-ui
bash src/scripts/install-wg-ui.sh
```
The install script will:
1. Install system dependencies (git, curl, ca-certificates, openssl)
2. Install Bun 1.3.14 to `/opt/bun`
3. Set up library directories under `/var/lib/wgui` (keys, clients, hosts, iptables, scripts)
4. Clone or update the repo to `/var/lib/wgui/webapp`
5. Install app dependencies (`bun install`)
6. Generate `.env` with encryption secrets
7. Run WireGuard setup (if available)
8. Install Caddy (`/opt/caddy`)
9. Install the `wg-quick` helper script
10. Set up systemd/OpenRC services for `wgui`, `wgui-caddy`, and certificate renewal
The installer **never modifies your firewall** — it will print the commands to
temporarily allow the dashboard port so you can reach the first login, and then
point you to **Setup → Firewall** for reviewing and removing rules.
### Firewall
Firewall rules are managed per host, automatically:
1. **Bootstrap (manual, temporary)** — allow the dashboard port so you can
reach the web UI once:
```bash
ufw allow 10752/tcp # ufw (Debian/Ubuntu)
firewall-cmd --permanent --add-port=10752/tcp && firewall-cmd --reload # firewalld (RHEL/Fedora)
```
2. **Host creation** — every host setup automatically allows its entire
wireguard subnet (e.g. `10.5.0.1` → `10.5.0.0/24` from anywhere) and the
host's wireguard listen port (e.g. `51821/udp`) in ufw or firewalld.
Detailed per-client traffic rules are enforced by the existing iptables
chain scripts, not the host firewall.
3. **Host deletion** — the host's subnet and listen-port rules are removed
automatically.
4. **Cleanup** — once everything is reachable via the tunnel, remove the
temporary bootstrap rule and review all rules under **Setup → Firewall**:
```bash
ufw delete allow 10752/tcp
firewall-cmd --permanent --remove-port=10752/tcp && firewall-cmd --reload
```
Rules that no longer match any host (`temporary`/`orphaned`) are flagged
with copyable removal commands on the setup page.
### TLS for Tunnel Services
Client routes expose internal services to WireGuard clients over HTTPS. The
data plane is a dedicated Caddy service (`wgui-caddy`) on `8443`; wg-ui owns
the route and certificate records and regenerates the Caddyfile. Caddy never
binds ports 80 or 443, and the host's existing proxy is left alone.
1. If Caddy isn't installed yet, open **Setup → TLS ingress** and click
**Install Caddy** (or use the Caddy action on **Setup → Maintenance**).
The installer sets up the binary, the `wgui-caddy` service and certificate support.
2. Open a route form from **Routes** (or a host's **Routes** panel) and set
the ACME email and staging toggle. No DNS provider token is needed:
certificates use manual DNS-01.
Let's Encrypt requires a public domain you control; internal-only names such
as `home.arpa` or `.local` need a private CA instead.
3. Add an A/AAAA record for each route hostname pointing at the host's
WireGuard IP. Caddy also restricts each route to the subnet of the host that
owns it.
4. Open the route page and click **Issue** (or **Renew**). The dashboard shows
the exact `_acme-challenge.<hostname>` TXT record. Add it at Cloudflare,
wait for propagation, then click **Validate**.
5. Clients use `https://<hostname>:8443/`. Portless URLs require the host's
existing 443 proxy to forward to `127.0.0.1:8443`; wg-ui does not take over
443. Caddy allows localhost so that proxy can reach it, which means the
proxy itself must enforce who may use those portless URLs.
Manual DNS-01 certificates are renewed from the route page because validation
needs your registrar. The route list shows expiry warnings. A successful
issuance reloads Caddy without restarting wg-ui. Check
`journalctl -u wgui-caddy` for reload failures.
### Manual (Development)
```bash
git clone https://git.tben.me/Moduletrace/wireguard-ui.git
cd wireguard-ui
bun install
NODE_ENV=development bun run dev
```
The dev server runs on port **10752** by default.
## Configuration
### Environment Variables
The `.env` file (gitignored) controls runtime behavior. It is auto-generated during installation if missing:
| Variable | Description | Default |
| ----------------- | ---------------------------------------- | -------------------- |
| `NODE_ENV` | Environment (`development`/`production`) | `production` |
| `ENCRYPTION_KEY` | Encryption key for sensitive data | Auto-generated |
| `ENCRYPTION_SALT` | Encryption salt for sensitive data | Auto-generated |
| `DATA_DIR` | Application data directory | `$INSTALL_DIR/.data` |
| `CADDY_HTTPS_PORT`| Caddy ingress HTTPS port (never 80/443) | `8443` |
| `CADDY_HTTP_PORT` | Caddy plain HTTP port (never 80) | `8081` |
| `CADDY_INGRESS_ENABLED` | Set to `0` to skip Caddy config sync | `1` |
| `ACME_STAGING` | Set to `1` to use the Let's Encrypt staging CA | `0` |
### Database Configuration
Edit `bun-sqlite.config.ts` to change database settings:
```typescript
const config: BunSQLiteConfig = {
db_name: "wgui", // Database file name
db_dir: "./db", // Database directory
typedef_file_path: "./db/types/db.ts", // Generated types
db_schema_file_name: "schema.ts", // Schema definition
};
```
### Server Port
The server port is defined in `src/data/site-data.ts`:
```typescript
export const SiteData = {
ServerPort: 10752,
// ...
} as const;
```
## Available Scripts
| Command | Description |
| ------------------- | ----------------------------------------- |
| `bun run dev` | Start development server (requires root) |
| `bun run start` | Start production server |
| `bun run db:schema` | Generate/update database schema and types |
| `bun run db:admin` | Open database admin interface |
## Project Structure
```
wireguard-ui/
├── src/
│ ├── pages/ # File-system based routes (__root.tsx, index.tsx, etc.)
│ │ ├── (sections)/ # Page sections
│ │ ├── (partials)/ # Page-local components
│ │ ├── (data)/ # Page-local data
│ │ ├── (functions)/ # Page-local functions
│ │ ├── (utils)/ # Page-local utilities
│ │ └── (hooks)/ # Page-local hooks
│ ├── components/
│ │ ├── twui/ # Local design system (publishable package)
│ │ ├── ui/ # shadcn/ui components
│ │ ├── shadcnblocks/ # shadcnblocks registry components
│ │ └── general/ # Shared page components (chat, date-picker, logo, etc.)
│ ├── hooks/ # Shared React hooks
│ ├── functions/
│ │ ├── backend/ # Server-only: DB queries, email, media upload, RAG
│ │ ├── frontend/ # Client-safe: CRUD handlers, fetch handlers
│ │ └── general/ # Platform-agnostic: join builders
│ ├── utils/ # Utility modules (auth, crypto, CSRF, hashing, etc.)
│ ├── dict/ # Constants and dictionaries (user types, gates, etc.)
│ ├── data/ # Static data (app constants, location data, etc.)
│ ├── types/ # Type definitions
│ ├── scripts/ # Install and setup scripts
│ └── server.ts # Entry point — starts Bun.serve with WebSocket support
├── db/
│ ├── schema.ts # Database schema definition
│ └── types/db.ts # Generated database types
├── public/ # Static assets served by the server
├── assets/ # Project assets
├── bun-sqlite.config.ts # Database configuration
├── bunext.config.ts # Bunext configuration
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── .env # Environment variables (gitignored)
```
## Database Schema
The database consists of the following tables:
| Table | Description |
| ----------------- | ----------------------------------------------- |
| `users` | User accounts (name, email, username, password) |
| `user_types` | User type assignments per user |
| `media` | Media assets (images, documents, etc.) |
| `media_paradigms` | Media paradigm classifications per media item |
| `clients` | WireGuard clients per host |
| `hosts` | WireGuard host configurations |
| `client_rules` | IP table rules for each client |
| `client_routes` | HTTPS routes exposed to WireGuard clients |
| `tls_certificates`| Certificates used by the Caddy ingress |
| `variables` | Application-wide key-value variables |
Generate types from the schema:
```bash
bun run db:schema
```
## Admin Route Hierarchy
| Route Pattern | Access | Features |
| ----------------------------------------------- | ------------ | ------------------------------------------------------------ |
| `/admin` | Admin | Dashboard overview |
| `/admin/hosts` | Admin | Host management (add, edit, per-host detail) |
| `/admin/routes` | Admin | Global HTTPS route list with host and certificate status |
| `/admin/hosts/[host_id]/routes` | Admin | HTTPS routes and upstreams exposed to tunnel clients |
| `/admin/hosts/[host_id]/routes/[route_id]` | Admin | Route details, TLS settings and certificate issue/renew |
| `/admin/clients` | Admin | Client management (add, edit, client rules per host) |
| `/admin/settings` | Admin | Account settings |
| `/admin/setup` | Super admin | System setup (hosts, WireGuard tools, update, restart) |
| `/admin/setup/tls` | Super admin | Caddy ingress installation and status |
## Development
### Development Mode
Set `NODE_ENV=development` and run:
```bash
NODE_ENV=development bun run dev
```
In development mode, the install script skips cloning and system service setup — the server is assumed to already be running.
### Path Alias
`@/*` resolves from the repository root. Examples:
```typescript
import { Button } from "@/src/components/ui/button";
import type { BUN_SQLITE_WGUI_USERS } from "@/db/types/db";
```
### Type-Checking
Run type checks with:
```bash
bunx tsc --noEmit
```
### Testing
Run individual test files:
```bash
bun test path/to/test.file.test.ts
```
## Repository
- **URL**: [https://git.tben.me/Moduletrace/wireguard-ui](https://git.tben.me/Moduletrace/wireguard-ui)
- **Install Script**: [src/scripts/install-wg-ui.sh](https://git.tben.me/Moduletrace/wireguard-ui/raw/branch/main/src/scripts/install-wg-ui.sh)