You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+68Lines changed: 68 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -231,6 +231,74 @@ On desktop you can also pick the active exit node from the web UI or the system
231
231
232
232
Traffic through a peer has no restrictions beyond the connection between the two of you — direct and relayed paths both work. You can reach the remote peer's LAN, but not the remote peer's `localhost`.
233
233
234
+
## VPN gateway (full-tunnel exit node)
235
+
236
+
In addition to the per-application SOCKS5 proxy, awl can route **all** of your IPv4 traffic through a peer at the IP layer — same model as Tailscale exit nodes or a classic full-tunnel WireGuard/OpenVPN. This is a separate feature from SOCKS5: a peer can allow being used for SOCKS5 without serving as a VPN gateway, and vice versa.
237
+
238
+
### Status
239
+
240
+
-**Linux:** supported (this is the platform we have tested on).
241
+
-**Android:** client mode is supported via the awl Android app (uses `VpnService` for routing). Serving as an exit node from Android is **not** supported.
242
+
-**macOS / Windows / other:****not supported yet** — awl will refuse to start with VPN gateway enabled. Windows-side code exists but is unfinished; see `vpn/sockmark/sockmark_windows.go` and `vpn/routes/nat_windows.go` for the open work items.
243
+
- IPv6 traffic is not tunnelled through the gateway in either direction (it is forwarded as a regular awl peer packet instead).
244
+
- Both client and exit-node sides require **CAP_NET_ADMIN** on Linux. AWL needs that already to bring up the TUN, so there is no extra capability to grant.
245
+
246
+
### Use a friend as your exit node (client side)
247
+
248
+
1. Make sure you and the peer are friends and the peer has VPN gateway service enabled on their side (see "Serve as an exit node" below). The CLI exposes the candidates:
249
+
```bash
250
+
awl cli gateway list
251
+
```
252
+
2. Enable gateway client mode:
253
+
```bash
254
+
awl cli gateway client use --name="peer-name"
255
+
# or: awl cli gateway client use --pid=<peer-id>
256
+
```
257
+
Calling `client use` again with a different peer atomically switches to the new gateway.
258
+
3.**Restart `awl`** for the change to take effect. The OS-level routes and the libp2p socket marking that prevent the gateway from looping back through itself are wired up only at startup.
259
+
4. Verify:
260
+
```bash
261
+
awl cli gateway status
262
+
curl ifconfig.me # should show the exit node's public IP
263
+
```
264
+
265
+
To turn the gateway off:
266
+
267
+
```bash
268
+
awl cli gateway client stop
269
+
# then restart awl to remove the OS-level routes
270
+
```
271
+
272
+
You can also flip these settings from the web UI / system-tray menu, or by editing `config_awl.json` directly while awl is stopped (`gateway.enabled`, `gateway.exitNodePeerID`).
273
+
274
+
### Serve as an exit node
275
+
276
+
To allow others to route their internet traffic through this device:
277
+
278
+
1. Set `gateway.serveAsVPNGateway: true` in `config_awl.json` (it is **off by default** — see "Why off by default" below) and restart awl. Equivalent: `awl cli gateway server enable` (and `awl cli gateway server disable` to turn it back off).
279
+
2. For each friend you want to permit, also tick *Allow as exit node* in their per-peer settings (or `awl cli peers allow_exit_node --name=… --allow=true`). The same flag governs SOCKS5; if you want different per-peer policies for SOCKS5 vs VPN gateway, file a request and we'll split it.
280
+
3. Restart awl. On startup AWL will:
281
+
- flip `net.ipv4.ip_forward` on,
282
+
- install a dedicated `AWL-FORWARD` iptables chain that DROPs traffic to your LAN/CGNAT/link-local subnets and ACCEPTs the rest,
283
+
- add a `MASQUERADE` rule for the awl subnet,
284
+
- reverse all of the above on a clean shutdown.
285
+
4. Connected friends can now pick you in their `gateway list` output once the next status exchange propagates the new state (≤ 5 minutes, or on next reconnect).
286
+
287
+
### Why off by default
288
+
289
+
Every mainstream VPN solution we surveyed — Tailscale, Headscale, ZeroTier, Nebula, WireGuard, OpenVPN, strongSwan — makes accepting other peers' internet traffic strictly opt-in, and AWL follows the same convention. The reasons are the same here:
290
+
291
+
-**Trust:** any friend in `KnownPeers` whom you have allowed will appear as your IP in destination logs, takedown notices, and abuse reports. That is a load-bearing trust position; the user should sign up for it explicitly, not inherit it from a default.
292
+
-**Host side-effects:** flipping `net.ipv4.ip_forward` and installing iptables rules is global system state, not something AWL can sandbox. We don't want a routine awl install to silently change those.
293
+
-**Conntrack/CPU cost:** the exit node sees every connection from every gateway client through `nf_conntrack`. On low-end hardware the load is non-trivial.
294
+
295
+
### Security and privacy notes
296
+
297
+
-**Your IP is exposed.** Once you serve as an exit node, the public IPs of your friends' destinations see your IP, not theirs.
298
+
-**Your LAN is not.** AWL drops forwarded traffic to RFC 1918 / RFC 6598 / RFC 3927 ranges (`10/8`, `172.16/12`, `192.168/16`, `100.64/10`, `169.254/16`) so a gateway client cannot reach the exit node's home network.
299
+
-**DNS:** in client gateway mode AWL forces upstream DNS to a public resolver to prevent the LAN resolver from leaking queries past the tunnel.
300
+
-**No mutual auth at the IP layer.** Every gateway client's traffic is masqueraded out from the same NIC; you cannot per-flow attribute traffic back to a specific peer at the kernel level. The exit node only filters by `WeAllowUsingAsExitNode` at the awl protocol entry, so revoke aggressively if a peer abuses it.
301
+
234
302
## Configuration
235
303
236
304
Awl stores all its state in a single JSON file called `config_awl.json`. The file is created automatically on the first launch and is rewritten by the application every time you change something through the web UI or CLI. You can also edit it by hand while awl is stopped.
0 commit comments