Files

4.8 KiB

Wireguard helper scripts

Lightweight Bash helpers for managing WireGuard peers without container restarts. They operate on a local wg0.conf, keep client artifacts under wireguard_scripts/logs/, and prefer wg syncconf over bring-the-interface-down workflows.

Introduction

Assumptions

  • WireGuard interface: wg0
  • Network: 10.0.0.0/24
  • Config lives in wireguard_scripts/
  • Client names must not contain spaces
  • Client keys and configs are stored under wireguard_scripts/logs/<client_name>/

Features

  • Zero-downtime apply: Uses wg syncconf wg0 <(wg-quick strip wg0) instead of restarting the interface.
  • Auto IP assignment: Reads existing AllowedIPs entries and increments the last /32 address.
  • Template-driven config: Replaces placeholders in client_template for private/public keys, IP, and domain.
  • QR code output: Generates an ANSI QR code for terminal scanning and a PNG for clients to import on mobile.
  • CSV audit log: Records timestamp, keys, IP, and peer status in logs/client_log.csv.
  • Save output file of the client: Generated file like: public and private key, configuration and QR image, are saved to wireguard_scripts/logs/<client_name>.

Note: Current Auto IP assignment isn't capable to detect the free addresses between current existing clients. For example, if there are only two clients with the addresses 10.0.0.2 and 10.0.0.6, it will not be capable to create the new client with address 10.0.0.3, but it will be 10.0.0.7.

Quick Start

From the wireguard_scripts/ directory, run:

./next_client.sh

This prints the server public key, current clients, next available IP, and renders the filled client config template - without touching wg0.conf.

Note: This is just a template generation on how the configuration file would look. Copying it and pasting in your wireguard client would not create a VPN connection to the server.

Technical Description

Notes

  • Removing a peer uses exact # BEGIN_PEER <name> / # END_PEER <name> tags and will also remove one preceding blank line if present.
  • If qrencode is missing, the add script still succeeds but skips QR generation with a notice.

File Structure

  • logs/: Per-client directories with keys, configs, QR PNGs, and the shared client_log.csv.
  • .env: Environment specific variables which affects the script run and generated configuration file.
  • client_template: WireGuard client template with <%CLIENT_PRIVATE_KEY%>, <%CLIENT_IP%>, <%SERVER_PUBLIC_KEY%>, <%DOMAIN_NAME%>.
  • next_client.sh: Preview next client config and IP.
  • next_client_add.sh: Create client keys, config, QR code, save output files, update CSV log and add peer.
  • next_client_remove.sh: Remove peer and update CSV log.

Scripts

Make sure that <client_name> has no spaces. When running the script make sure that the following conditions are met to be able to add/remove a new client:

  • add/remove - <client_name> has no space and it canot be blanc.
  • add - <client_name> must not exist in wg0.conf.
  • remove - <client_name> must exist in wg0.conf.

Script description:

  • Preview the next client config/IP.

    ./next_client.sh <client_name>
    
  • Generate client keys, render config from client_template, append the peer block to wg0.conf, apply with wg syncconf, and mark the client as active in CSV log file.

    ./next_client_add.sh <client_name>
    
  • Remove the tagged peer block from wg0.conf, apply with wg syncconf and mark the client as removed in the CSV log file.

    ./next_client_remove.sh <client_name>
    

Environment

The scripts look for a .env file in the same directory. If it is missing, they continue with built-in defaults and print a warning.

Documented variables used by the scripts:

  • DOMAIN_NAME - inserted into the client config as the server endpoint hostname.
  • WG0_DIR - directory containing wg0.conf and publickey.
  • TOOLS_DIR - directory containing client_template and logs/.

This file should not be committed. Treat it as machine-specific configuration.

client_template

The template is processed with sed to generate each client config. Supported placeholders:

  • <%CLIENT_PRIVATE_KEY%> - newly generated client private key.
  • <%CLIENT_IP%> - next assigned /32 client IP, without CIDR suffix.
  • <%SERVER_PUBLIC_KEY%> - server public key read from ${WG0_DIR}/publickey.
  • <%DOMAIN_NAME%> - endpoint hostname from .env.

Example template:

[Interface]
PrivateKey = <%CLIENT_PRIVATE_KEY%>
Address = <%CLIENT_IP%>/24
ListenPort = 51820

[Peer]
PublicKey = <%SERVER_PUBLIC_KEY%>
AllowedIPs = 10.0.0.0/24
Endpoint = <%DOMAIN_NAME%>:51820
PersistentKeepalive = 25