mirror of
https://codeberg.org/emmett1/wg-connect
synced 2026-08-16 11:12:04 +08:00
123 lines
3.8 KiB
Markdown
123 lines
3.8 KiB
Markdown
# 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.
|