Skip to content

StealthSurf-VPN/awg-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

awg-server

HTTP API server for managing AmneziaWG 2.0 VPN clients. Uses the AmneziaWG kernel module on the host with the awg CLI tool — kernel-level performance with DPI obfuscation via CPS (Custom Protocol Signature).

Supports per-client obfuscation profiles — each unique set of CPS parameters gets its own AWG interface, created on demand.

Quick Install (Linux)

One-liner that installs AmneziaWG 2.0, downloads the latest awg-server binary, and gets you ready to run:

# 1. Install AmneziaWG 2.0 kernel module (DKMS, from source)
apt update && apt install -y build-essential git dkms linux-headers-$(uname -r)
git clone --depth 1 https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git /tmp/amneziawg-module
cd /tmp/amneziawg-module/src
make dkms-install
dkms add -m amneziawg -v 1.0.0
dkms build -m amneziawg -v 1.0.0
dkms install -m amneziawg -v 1.0.0
modprobe amneziawg
cd ~ && rm -rf /tmp/amneziawg-module

# 2. Install AmneziaWG 2.0 tools (awg CLI)
git clone --depth 1 https://github.com/amnezia-vpn/amneziawg-tools.git /tmp/amneziawg-tools
make -C /tmp/amneziawg-tools/src && make -C /tmp/amneziawg-tools/src install
rm -rf /tmp/amneziawg-tools

# 3. Enable IP forwarding
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

# 4. Download latest awg-server
curl -fsSL https://github.com/stealthsurf-vpn/awg-server/releases/latest/download/awg-server-linux-$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') -o /usr/local/bin/awg-server
chmod +x /usr/local/bin/awg-server

# 5. Create data directory
mkdir -p /data

# 6. Create systemd service
cat > /etc/systemd/system/awg-server.service <<EOF
[Unit]
Description=AmneziaWG Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/awg-server
Restart=always
RestartSec=5

Environment=AWG_API_TOKEN=your-secret-token
Environment=AWG_ADDRESS=10.0.0.1/24
Environment=AWG_ENDPOINT=your.server.ip

# Optional (shown values are defaults):
# Environment=AWG_JC=5
# Environment=AWG_JMIN=50
# Environment=AWG_JMAX=1000
# Environment=AWG_LISTEN_PORT=51820
# Environment=AWG_HTTP_PORT=7777
# Environment=AWG_DNS=1.1.1.1
# Environment=AWG_MTU=1420
# Environment=AWG_MAX_INTERFACES=0

[Install]
WantedBy=multi-user.target
EOF

# 7. Start and enable on boot
systemctl daemon-reload
systemctl enable --now awg-server

Check status:

systemctl status awg-server
journalctl -u awg-server -f

Prerequisites

CLI Commands

# Check current version
awg-server version

# Self-update to latest GitHub release
awg-server update

# Start the server (default, no arguments)
awg-server

After awg-server update, restart the service: systemctl restart awg-server.

Build

# Build for current platform (with version)
make build VERSION=1.0.0

# Build for all platforms (linux, darwin, windows × amd64, arm64)
make build-all

# Static analysis
make vet

# Clean build artifacts
make clean

Requires Go 1.24+. Binaries are output to dist/.

Deploy

Copy awg-server binary to the VPN server and run:

AWG_API_TOKEN=your-secret-token \
AWG_ADDRESS=10.0.0.1/24 \
AWG_ENDPOINT=your.server.ip \
./awg-server

API

All endpoints require Authorization: Bearer <AWG_API_TOKEN>.

# Health check (no auth)
curl http://localhost:7777/health

# List clients
curl http://localhost:7777/api/clients -H "Authorization: Bearer $TOKEN"

# Create client (default obfuscation params from env)
curl -X POST http://localhost:7777/api/clients \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"my-client-uuid"}'

# Create client with custom obfuscation params and port
curl -X POST http://localhost:7777/api/clients \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"my-client-uuid","awg_params":{"port":51825,"jc":5,"jmin":50,"jmax":1000,"s1":40,"s3":20,"h1":"100000-800000"}}'

# Update client obfuscation params
curl -X PATCH http://localhost:7777/api/clients/my-client-uuid \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"awg_params":{"port":51825,"jc":10,"jmin":100,"jmax":2000}}'

# Get client config (.conf)
curl http://localhost:7777/api/clients/my-client-uuid/configuration \
  -H "Authorization: Bearer $TOKEN"

# Get client usage stats (accumulated rx/tx, last handshake)
curl http://localhost:7777/api/clients/my-client-uuid/stats \
  -H "Authorization: Bearer $TOKEN"
# → {"rx_bytes":1073741824,"tx_bytes":5368709120,"last_handshake":"2026-04-01T12:00:00Z"}

# Delete client
curl -X DELETE http://localhost:7777/api/clients/my-client-uuid \
  -H "Authorization: Bearer $TOKEN"

Configuration

Environment variables:

Variable Required Default Description
AWG_API_TOKEN yes Bearer token for API auth
AWG_ADDRESS yes Server VPN address (CIDR), e.g. 10.0.0.1/24
AWG_ENDPOINT yes Public IP/hostname for client configs
AWG_LISTEN_PORT no 51820 Base WireGuard UDP port (auto-assigned sequentially; can be overridden per-client via port in awg_params)
AWG_HTTP_PORT no 7777 HTTP API port
AWG_MTU no 1420 MTU value
AWG_DNS no 1.1.1.1 DNS for client configs
AWG_DATA_DIR no /data Persistence directory
AWG_INTERFACE no auto-detect Override outbound network interface for NAT
AWG_MAX_INTERFACES no 0 Max AWG interfaces (0 = unlimited)

Auto-Generated Parameters

On first start, the server generates and persists unique obfuscation values in /data/clients.json:

Parameter Generation Purpose
H1-H4 Random non-overlapping ranges (format min-max) Replace WireGuard message type headers. Zero performance impact.
S1 Random 15-150 Init handshake packet padding
S2 Random 15-150, S1 + 56 ≠ S2 Response handshake packet padding

These are reused across restarts. No env vars needed.

Configurable Parameters

Variable Default What it does Impact
AWG_JC 5 Junk packets sent during handshake 0 = off, 3-8 = good. No effect after connect.
AWG_JMIN 50 Junk packet minimum size (bytes) Wider range = harder to fingerprint.
AWG_JMAX 1000 Junk packet maximum size (bytes) 500-1000 = good.
AWG_S3 0 Extra bytes added to cookie reply packets 0-32 = good. Only under load.
AWG_S4 0 Extra bytes added to every data packet 0 = recommended. Adds overhead to every packet.
AWG_I1-AWG_I5 empty CPS signature packets (client config only) Decoy UDP packets mimicking another protocol. Uses CPS tag format.

Obfuscation Profiles

Rule of thumb: H1-H4 and S1/S2 are auto-generated. Jc/Jmin/Jmax only affect connection time. S4 affects every packet — use with care.

Default (no extra env vars needed) — headers + light junk at handshake:

H1-H4, S1, S2 auto-generated. Jc=5, Jmin=50, Jmax=1000 (defaults).

Ping: same as plain WireGuard after connect. Protection: blocks signature + size-based DPI.

Minimum latency — disable junk packets:

AWG_JC=0 AWG_JMIN=0 AWG_JMAX=0

Auto-generated H1-H4 still provide header masking (zero overhead).

Maximum stealth — for regions with aggressive DPI (China, Iran, Turkmenistan):

AWG_JC=8 AWG_JMIN=50 AWG_JMAX=1000
AWG_I1='<b 0xc0><r 32><c><t>'

Ping: same after connect (~100ms extra at handshake). Protection: maximum without per-packet overhead.

Multi-Interface Architecture

AmneziaWG sets CPS obfuscation parameters at the interface level, not per-peer. To support per-client custom parameters, the server manages a pool of interfaces:

  • Each unique set of CPS parameters gets its own awgN interface (awg0, awg1, awg2, ...)
  • Clients with identical CPS parameters share an interface
  • Each interface listens on its own UDP port (explicit port from awg_params, or auto-assigned sequentially from base port)
  • Interfaces are created on demand and destroyed when their last peer is removed
  • All interfaces share the same server private key
main.go → config → awg (pool, params, keygen) → clients (manager, storage) → api (server, handlers)
  • Kernel moduleamneziawg-linux-kernel-module on host, awg CLI for management
  • Static binaryCGO_ENABLED=0, no external Go dependencies beyond golang.org/x/crypto
  • Persistence via JSON file with atomic writes
  • IP allocation sequential from .2, freed IPs reusable
  • Auth Bearer token on all endpoints

About

AmneziaWG 2.0 HTTP API server for managing VPN clients. Kernel module + awg CLI, DPI obfuscation via CPS, Bearer token auth, JSON persistence. Single static binary. And ready to work with AI agents.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Contributors