Files
roro9stack/site/content/guide/vpn.md
T
twislaandClaude Opus 5.5 b041c7b67c
CI / build (pull_request) Successful in 2m58s
Site / build (pull_request) Successful in 13s
VPN: a WireGuard tunnel (#8)
The device joins a WireGuard network over whatever Wi-Fi it is on: one
peer, IPv4. A client's .conf is imported from the card (/vpn/wg0.conf) and
kept in the device's settings, private key included, never shown; Settings
offers to delete the file. A switch brings the tunnel up until the next
restart, "Start with Wi-Fi" every time; it waits for the clock, which a
handshake needs. VPN shows in the Status Bar.

The protocol is esphome/wireguard 0.4.8. It calls lwIP without lwIP's lock,
which this framework checks: every call into it is made with the lock held.

What goes through the tunnel is everything (AllowedIPs 0.0.0.0/0) or the
one subnet the device's tunnel address is in: lwIP routes by an
interface's subnet or by default, nothing finer. The import says how many
ranges it can't reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
2026-10-07 23:13:28 +02:00

3.5 KiB

+++ title = "VPN" description = "A WireGuard tunnel: reach your own network from any Wi-Fi, or send everything through it on a network you don't trust." weight = 12 [extra] tag = "WireGuard" +++

The Cardputer can join a WireGuard network over whatever Wi-Fi it is on. Two uses: reaching your own machines from anywhere (an IRC bouncer, the device's own Debug Console), and keeping its traffic private on a hotel or café network.

You need a WireGuard server, yours or a provider's, and the configuration file it gives a client: a .conf.

Setting it up

  1. On the server, make a configuration for a new client, as you would for a phone.
  2. Copy the file to the SD card as /vpn/wg0.conf.
  3. On the device: Settings → VPN → Import /vpn/wg0.conf.
  4. Say yes when it offers to delete the file: the configuration is now stored in the device, and the file on the card still holds the private key in clear.

If the file can't be used, the page says which line and why. The key itself is never shown, anywhere, once imported.

Using it

Settings → VPN has a switch. VPN appears in the Status Bar while the tunnel is wanted, and turns bright once the server has answered. The page shows the state, the server, this device's address in the tunnel, what goes through it, and how long ago the server was last heard.

  • The switch is for now. It doesn't survive a restart.
  • Start with Wi-Fi, off by default, starts the tunnel whenever Wi-Fi connects.
  • The tunnel waits for the clock: WireGuard needs the time. The clock is set over plain Wi-Fi first, or from GNSS.
  • A Toast says when the tunnel comes up, and when the server stops answering.

What goes through it

That depends on the AllowedIPs line of the file, and there are only two cases:

The file says What happens
AllowedIPs = 0.0.0.0/0 Everything goes through the tunnel. While the server is silent, nothing leaves the device at all.
Anything else One subnet goes through it: the one the device's own tunnel address is in (for 10.9.0.2 with AllowedIPs = 10.9.0.0/24, that is 10.9.0.x). The rest goes out on Wi-Fi as before.

A home network behind the server can only be reached with the first kind. If the file lists 10.9.0.0/24, 192.168.1.0/24, the second range isn't routed, and the import says so: "through it 10.9.0.0/24, not 1 other range". This is a limit of the device's network software, which can route by one subnet or by default and nothing finer.

The DNS servers in the file are used while the tunnel is up, if they can be reached through it.

Being reached through it

With the tunnel up, the device answers on its tunnel address as it does on Wi-Fi: the Debug Console if you switched it on (it still wants its token), and the port that receives firmware updates (they still have to be signed).

From the Shell

vpn status          what it is doing
vpn up              on, until the next restart
vpn up 120          on for two minutes, then off by itself
vpn down
vpn import          reads /vpn/wg0.conf (or the path you give)
vpn forget          stops it and erases its keys from the device
vpn auto on|off     start with Wi-Fi

vpn up with a number of seconds is for trying a new configuration from a distance: if it cuts you off, it comes back by itself.

Limits

One tunnel, to one server. IPv4 only: IPv6 addresses in the file are left out. The server can be an address or a name.

The keys, as the device lists them

{{ keys(scopes=["vpn"]) }}