diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..97a2e0c --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +# wg-connect + +Bring a WireGuard tunnel up and down on BusyBox-based systems without +`wg-quick`, systemd, or bash. + +## Requirements + +- `wg` - WireGuard userspace tool +- `ip` - iproute2 or BusyBox `ip` +- `grep` - BusyBox grep (with `-E` support) +- POSIX `/bin/sh` + +Root privileges are required (the script creates and configures network +interfaces). + +## Installation + +```sh +make install # to /usr/local +make install PREFIX=/usr # to /usr +make install DESTDIR=/tmp/pkg # for packaging +``` + +Or manually: + +```sh +install -m 0755 wg-connect /usr/local/bin/wg-connect +install -m 0644 wg-connect.1 /usr/local/share/man/man1/wg-connect.1 +``` + +## Usage + +```sh +wg-connect up <config> # bring a tunnel up +wg-connect down [name] # tear a tunnel down +``` + +**`up`** requires a config argument, resolved as follows: + +| Argument | Resolves to | +|---|---| +| `myvpn` | `/etc/wireguard/myvpn.conf` | +| `myvpn.conf` | `./myvpn.conf`, then `/etc/wireguard/myvpn.conf` | +| `./foo.conf` | `./foo.conf` (path with `/` - used as-is) | +| `/any/path/c.conf` | `/any/path/c.conf` (absolute path) | + +The interface name is derived from the config file's basename (minus +`.conf`). For example, `wg-connect up myvpn` creates interface `myvpn`, +and `wg-connect up /etc/wireguard/home.conf` creates interface `home`. + +**`down`** accepts an optional name to tear down a specific tunnel. +Without a name it defaults to `wg0`. + +## Config format + +Standard WireGuard `[Interface]` + `[Peer]` sections. `wg-quick` +extensions (`Address`, `DNS`, etc.) are accepted. The script strips +them before passing the config to `wg setconf` and handles them itself. + +```ini +[Interface] +Address = 10.0.0.2/24 +PrivateKey = oBKGh1W0UeO7R2aV5pLkdMn8Xq3TcFyRbzJwZsPvCg= +DNS = 1.1.1.1 + +[Peer] +PublicKey = xTIBA5rboUvnH4htjbDs6TFeFHS4k0mrKV4xJCzO0H8= +PresharedKey = /pUcv4j6DZ1UGm0PwR7aBr9Lk2sFdXq3OcVy5Jh8Tg= +Endpoint = 203.0.113.45:51820 +AllowedIPs = 0.0.0.0/0 +``` + +Multiple `[Peer]` sections are supported; `AllowedIPs` and `Endpoint` +values are accumulated across all of them. + +Note: if you run multiple tunnels, each must have a unique `ListenPort` +(or omit it entirely). The script detects port conflicts before +setting up the interface. + +## What it does + +**`up`** + +1. Resolves the config path and derives the interface name. +2. Checks for port conflicts with any existing WireGuard interface. +3. Parses the config for `Address`, `DNS`, `Endpoint`, `AllowedIPs`, + and `ListenPort`. +4. Adds explicit routes for each peer endpoint through the current + default gateway, so encrypted UDP packets are not caught in the + tunnel's own routing. +5. Creates the WireGuard interface and applies the config. +6. Assigns the `Address` (appending `/32` if no CIDR is given). +7. Brings the interface up. +8. Installs routes for each `AllowedIPs` entry. `0.0.0.0/0` replaces + the default route. +9. If `DNS` is set, backs up `/etc/resolv.conf` and writes the VPN + nameserver. +10. Saves state to `/tmp/wg-connect.<iface>.state` for teardown. + +If any step fails, the trap handler rolls back everything created so +far (interface, endpoint routes, state file). + +**`down`** + +1. Reads `/tmp/wg-connect.<name>.state`. +2. Restores the original `/etc/resolv.conf`. +3. Removes the endpoint-specific routes. +4. Deletes the interface (which also removes its addresses and routes). +5. Restores the original default route if one was saved. +6. Removes the state file. + +If the state file is missing but the interface still exists, `down` +falls back to cleaning up the leftover interface. + +## Limitations + +- IPv6 addresses and routes are skipped (BusyBox `ip` may lack `-6` + support). +- `DNS` supports a single nameserver only. +- PostUp / PostDown / PreUp / PreDown hooks are not executed. +- No firewall rules are added. If you need a kill switch, configure + `iptables` separately. |
