aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md122
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.