WireGuard itself is not difficult.

What's really troublesome are the trivial tasks that follow: adding a phone, deleting an old device, generating a QR code, modifying configurations, reloading the service, and checking if peers have handshaked.

Manually editing wg0.conf is doable, but it gets annoying if you do it often. Moreover, if you accidentally mistype a private key, public key, or AllowedIPs, you have to go back and troubleshoot all over again.

So I wrote wg-manager.sh. The goal is simple: wrap up common WireGuard operations so you don't have to type them from scratch every time.

Applicable Scenarios

This script is suitable for a small WireGuard environment on a personal VPS:

  • Want to quickly add or remove clients.
  • Want to generate a QR code directly in the terminal to scan with a phone.
  • Don't want to manually edit wg0.conf every time.
  • Want to use a menu to check the status, reload the configuration, and export client files.

If you already have a complex environment with policy routing, multiple network interfaces, and multiple exits, this script might not be suitable for taking over directly.

Prerequisites

It's written by default for common server environments like Debian / Ubuntu. Before using it, you need at least:

  • A Linux server with root privileges.
  • A system that can normally install WireGuard-related packages.
  • A firewall or cloud provider security group that allows the UDP port used by WireGuard.
  • To roughly know the network segment you want to assign to your clients.

Final Result

In the end, you can just run:

sudo ./wg-manager.sh

Then use the menu to add/remove clients, view QR codes, check service status, and reload the configuration. You don't have to repeatedly look up commands for common operations.

What This Script Does

wg-manager is a Bash script mainly used to manage WireGuard servers and clients.

Currently, it can do the following:

  • Install the WireGuard server.
  • Create the first client.
  • Add / remove clients.
  • Automatically allocate client IPs.
  • Generate client configuration files.
  • Display a QR code in the terminal for direct scanning with a phone.
  • Support global mode and simple split tunneling mode.
  • Check service status and peer information.
  • Rebuild configurations and reload.
  • Uninstall configurations managed by the script.

It's suitable for a Debian / Ubuntu cloud server.

It is not suitable for scenarios that already have a complex WireGuard production environment, lots of policy routing, and highly specific split tunneling rules. This script isn't meant to take over complex networks; it's mainly to streamline the most common workflows for everyday users.

Why Write a Menu Mode

Usually, scripts like this start out using command-line arguments:

sudo ./wg-manager.sh add-client iphone
sudo ./wg-manager.sh qr iphone
sudo ./wg-manager.sh status

It works, but you have to memorize the commands.

When doing manual operations on a day-to-day basis, I'd rather just see a menu:

sudo ./wg-manager.sh

And then choose:

1) Install WireGuard
2) Add a client
3) Delete a client
4) List clients
5) View client configuration
6) Show client QR code
7) Check service status
8) Reload configuration
9) Uninstall

This way, you don't have to check the README every time.

There is also a detail: when starting in menu mode, it will first check if you are root.

If you didn't use sudo, it exits immediately. You don't want someone filling out a bunch of prompts only to be told at the end that they lack permissions. That kind of experience is a bit absurd.

Getting the Script

If the repository is already public, you can clone it directly:

git clone https://github.com/Kaurisss/wg-manager.git
cd wg-manager
chmod +x wg-manager.sh

Or you can just download the single file:

curl -fsSL -o wg-manager.sh https://raw.githubusercontent.com/Kaurisss/wg-manager/main/wg-manager.sh
chmod +x wg-manager.sh

It is recommended to run the script on a server. Don't force it to run locally on Windows; this thing is intended for Linux servers anyway.

Using the Menu Mode

The simplest way:

sudo ./wg-manager.sh

For the first time, choose to install WireGuard.

The script will ask you to fill in these details:

  • WireGuard interface name, default wg0
  • UDP port, default 51820
  • IPv4 subnet, default 10.66.66.0/24
  • Whether to enable IPv6
  • Client DNS
  • Name of the first client
  • Client mode: Global / Split tunneling

For most of them, you can just press Enter to use the default values.

After installation, it will generate the server configuration and conveniently generate the first client configuration as well.

If qrencode is installed, it can also display a QR code right in the terminal. You can just scan and import it with the WireGuard mobile client, which is quite handy.

Command-Line Mode

The menu is great for manual clicking.

But for writing documentation, automation, and copying commands, subcommands still need to be preserved.

Install and create the first client:

sudo ./wg-manager.sh install --client-name phone

Enable IPv6:

sudo ./wg-manager.sh install --enable-ipv6 --client-name phone

Custom port and subnet:

sudo ./wg-manager.sh install \
  --port 51820 \
  --ipv4-net 10.66.66.0/24 \
  --enable-ipv6 \
  --ipv6-net fd66:66:66::/64 \
  --client-name laptop

Add a client:

sudo ./wg-manager.sh add-client iphone

Show QR code:

sudo ./wg-manager.sh qr iphone

Check status:

sudo ./wg-manager.sh status

List clients:

./wg-manager.sh list-clients

Reload configuration:

sudo ./wg-manager.sh reload

Uninstall:

sudo ./wg-manager.sh uninstall --yes

Global Mode and Split Tunneling Mode

The script offers two client modes.

Global Mode

Global mode means all client traffic goes through WireGuard:

AllowedIPs = 0.0.0.0/0,::/0

Suitable for:

  • Connecting back to the server when you're out with your phone.
  • Wanting all traffic to pass through this VPS.
  • Not wanting to bother with split tunneling rules.

Split Tunneling Mode

Split tunneling mode means only designated subnets go through WireGuard.

For example, routing only intranet addresses:

sudo ./wg-manager.sh add-client office \
  --mode split \
  --allowed-ips 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

Note that this only uses AllowedIPs for simple split tunneling.

It is not intelligent routing; it won't automatically recognize games, websites, or domains. If you want highly specific rules, you'll have to use a more complex solution.

Where Are the Generated Files Stored?

By default, they are all in /etc/wireguard/:

/etc/wireguard/
├── wg0.conf
├── clients/
│   ├── phone.conf
│   └── iphone.conf
├── peers/
│   └── iphone/
│       ├── private.key
│       ├── public.key
│       ├── psk.key
│       └── meta
├── backup/
└── .wg-manager/
    ├── server.env
    ├── server_private.key
    └── server_public.key

This contains private keys, PSKs, and client configurations.

Do not push these to GitHub.

In a public repository, you should only put the script, README, and example configurations. Uploading real configuration files is basically digging a hole for yourself.

Security Groups and Firewalls

The script attempts to handle UFW and firewalld, automatically allowing WireGuard's UDP port.

But cloud servers also have security groups.

This script cannot manage the cloud provider's console.

If you can't connect, check these first:

  • Has the cloud server's security group allowed UDP 51820?
  • Is the local firewall blocking it?
  • Did you mistype the endpoint in the client?
  • Has the server's public IP changed?
  • Is there any handshake in sudo ./wg-manager.sh status?

Don't immediately blame the script if you can't connect.

With networking, it's often not that the configuration wasn't generated; it's that the traffic simply didn't come in.

Troubleshooting Order

I generally follow this order:

1. Is the Service Up?

sudo ./wg-manager.sh status

Or:

sudo systemctl status wg-quick@wg0

2. Is the Client Configuration Generated?

ls -l /etc/wireguard/clients/

3. Can the QR Code Be Scanned?

sudo ./wg-manager.sh qr iphone

4. Have the Peers Handshaked?

sudo wg

Having a latest handshake is the only way to prove the client has actually connected.

If there's no handshake, continue checking the port, security group, endpoint, and public/private keys.

Known Limitations

This script is not a silver bullet.

Current limitations include roughly:

  • Only supports Debian / Ubuntu.
  • IPv4 subnets are only handled as /24.
  • IPv6 subnets are only handled as /64.
  • Uses iptables / ip6tables for NAT by default.
  • Does not take over existing complex WireGuard environments.
  • Split tunneling is just simple AllowedIPs; no intelligent rules.

These limitations aren't bugs; they are a deliberate control of scope.

For scripts like this, the worst thing is trying to cover everything from the start, and ending up with a mess that no one dares to run.

Final Words

wg-manager isn't meant to replace the official WireGuard tools.

It merely wraps the few things I frequently do into a script: installing, adding clients, deleting clients, scanning QR codes, checking status, and reloading configurations.

Every time I can avoid manually editing wg0.conf is one less chance to write the configuration incorrectly.

Getting it to run stably first, and then slowly adding features later. That direction feels a lot more human.