<a href="https://github.com/anywherelan/awl/blob/master/LICENSE"><img alt="GitHub license" src="https://img.shields.io/github/license/anywherelan/awl?color=brightgreen"></a>
<a href="https://github.com/anywherelan/awl/releases"><img alt="GitHub release" src="https://img.shields.io/github/v/release/anywherelan/awl" /></a>
<a href="https://github.com/anywherelan/awl/actions/workflows/test.yml"><img alt="Test build status" src="https://github.com/anywherelan/awl/actions/workflows/test.yml/badge.svg" /></a>
awl-tray)awl-tray)awl)Anywherelan (awl for brevity) is a peer-to-peer mesh VPN for connecting your own devices to each other, at the IP level, from wherever they are. A laptop behind a NAT, a home server, an old phone — give each one a stable .awl address and they can reach each other as if they were on the same LAN.
awl is fully decentralized: no coordination server, no account, no control plane — nothing to pay for, nothing to sign up for, nothing that can be shut down from the outside. Everything awl needs is in this repository, under an open-source license.
awl is aimed at personal use: selfhosters, groups of friends, small device fleets (roughly ~10s). It is not a replacement for commercial mesh VPNs in a team setting — there are no ACLs, tags, SSO, or admin dashboards.
Some things people use it for:
Tailscale, Netbird and ZeroTier are excellent products, especially for teams. awl is a different shape:
Tradeoffs worth knowing about:
work-laptop.awl instead of typing IPs
|
|
|
|
awl combines two things: a virtual network interface (TUN on Linux/macOS/Android, wintun on Windows) and a peer-to-peer networking stack built on libp2p. IP packets sent into the awl interface are wrapped into libp2p streams and delivered directly to the addressed peer.
awl's transport security comes from libp2p.
ed25519 keypair; the peer_id is the public key, so identity and authentication aren't separate layers. There is no CA, no certificate to revoke.peer_ids out-of-band (copy/paste, QR, messenger, whatever works), one side invites, the other accepts. No trust-on-first-use; unknown peers can't connect to you.awl ships in two desktop flavors:
awl-tray — desktop build with a system-tray indicator: status at a glance, start/stop/restart, peer list, and quick exit-node selection (SOCKS5 proxy / VPN gateway). Use this for regular desktop usage.awl — headless server build, no GUI. Use this for servers and embedded devices.Both share the same web UI and the same CLI.
Grab the archive for your platform/arch from the releases page and extract it wherever you like.
Once awl is running, open http://admin.awl in a browser. admin.awl is a magic local domain that awl's built-in DNS resolves to the local web UI (default http://127.0.0.1:8639). On awl-tray you can also right-click the tray icon → Open Web UI.
Install the APK from the releases page and open the app.
awl-tray)Unpack the zip and run the binary as administrator (right-click → Run as administrator). Admin rights are required to create the virtual network interface.
Some antivirus engines flag awl as a false positive; if that happens you'll need to allowlist it manually.
Unpack the zip, right-click awl-tray, choose Open. You'll see an "unidentified developer" warning (the binary isn't signed — signing costs money); click Open to run it anyway. awl will then prompt for admin rights, which are needed to create the virtual network interface.
awl-tray)For working notifications and modal dialogs, make sure zenity is installed:
sudo apt install -y zenity
Then run the binary like any other app. It will prompt for root (needed for /dev/tun and the virtual network interface) and automatically create a desktop entry, so next time you can launch awl from the applications menu.
awl)To install as a systemd service — binary and config in /etc/anywherelan/, autostart on boot — run:
curl -sL https://raw.githubusercontent.com/anywherelan/awl/master/install.sh | sudo bash
Then:
awl cli me status # server status
awl cli me rename --name your-name-here # set a name
awl cli me id # print your peer id
awl cli -h # full help
systemctl status awl.service # systemd status
See Terminal-based client for more.
To connect two devices you exchange their peer_ids. A peer_id is the device's permanent identifier (and public key — see Security). One peer sends a friend invitation, the other accepts or blocks it. After acceptance, both can reach each other by VPN IP or by .awl domain.
For testing, there is a public peer that auto-accepts invitations, so you don't need a second device to try awl out.
Open the web UI at http://admin.awl (or the Android app). On the Status / Overview page, click the QR icon next to your device name to show your own peer_id. To invite someone, click Add peer (on Android, the + floating button on the Peers tab).
To try the public tester: enter 12D3KooWJMUjt9b5T1umzgzjLv5yG2ViuuF4qjmN65tsRXZGS1p8 as peer id, name it awl-tester, save. After a few seconds it will appear in your peer list. Open http://awl-tester.awl/ — you should see a network speed-test page.
.awlDNS is not yet available on Android (#17); on Android you access peers by IP.
When someone invites you, a notification will appear; accept or block in the admin UI.
# print your peer_id
awl cli me id
# print server status
awl cli me status
# print all incoming friend requests
awl cli peers requests
# invite peer or accept incoming request
awl cli peers add --pid 12D3KooWJMUjt9b5T1umzgzjLv5yG2ViuuF4qjmN65tsRXZGS1p8 --name awl-tester
# print all known peers
awl cli peers status
# try to access new peer
ping 10.66.0.2
# or by domain name
ping awl-tester.awl
Once you have at least one connected device, you can route your outbound traffic through it. Any device can act as a SOCKS5 exit node (Android included) as long as they allow it.
To let a peer use your device as an exit node (desktop web UI): open http://admin.awl, select the peer, press Settings, tick Allow as exit node, save.
Via the CLI:
# list connected peers and their EXIT NODE status (whether they allow you, or you allow them)
awl cli peers status
# let `peer-name` use this device as a SOCKS5 exit node
awl cli peers allow_exit_node --name="peer-name" --allow=true
# list exit nodes available to you
awl cli me list_proxies
# route local SOCKS5 traffic through a peer (default listener: 127.0.0.66:8080, no auth)
awl cli me set_proxy --name="peer-name"
On desktop you can also pick the active exit node from the web UI or the system tray menu.
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.
awl can route all of your IPv4 traffic through a remote device at the IP layer — the same model as classic full-tunnel WireGuard/OpenVPN. The remote device becomes your exit node: your traffic reaches the internet from its IP, not yours.
awl has two independent ways to send your traffic through another device, and a device can offer either one without the other. The SOCKS5 proxy works per-application: you point a specific app (a browser, say) at awl's local proxy, and only that app's traffic goes through the peer — nothing on your system changes. The VPN gateway is system-wide: it routes all of your IPv4 traffic through the exit node at the IP layer, so every app is covered without configuring anything.
In short: reach for SOCKS5 to send a single app through a peer, and for the VPN gateway when you want the whole device to look like it's at the exit node.
| Platform | As client | As exit node | Notes |
|---|---|---|---|
| Linux | ✅ | ✅ | fully supported |
| Android | ✅ | ❌ | exit-node role needs root — not planned |
| Windows | ⏳ | ⏳ | coming next |
| macOS | ❌ | ❌ | needs volunteers for testing |
On macOS and Windows awl currently refuses to start with VPN gateway enabled.
⚠️ IPv6 is not tunnelled. The gateway only carries IPv4. While it's on, all IPv6 traffic is dropped so that your real IPv6 address is never exposed past the exit node: - Dual-stack (IPv4 + IPv6): everything aut