Network access

Your laptop, or any other machine, can join one project's private network: its services — the private ones included, like a database with no address of its own — are then reachable from it as if it were one of them. It's how you point a database tool at production's Postgres, run a script against a private API, or debug something that only answers inside the project.

alf connect shop
In shop's network as 10.88.128.1. Its services, here:

SERVICE   ON THIS MACHINE   IN SHOP
db        localhost:5432    10.128.4.2:5432
web       localhost:80      10.128.4.3:80

✓ Connected to fsn-1.
Ctrl-C to leave. The device stays registered for next time.

Each service opens on localhost, on the port it listens on (or a free one, if that's taken), until you press Ctrl-C. psql postgres://app:…@localhost:5432/app then talks to the project's database. The list has the rest of the project too: a computer (which has no one port to open: name one, or use --all), and static sites and buckets at their public addresses, since they aren't anything to tunnel to.

Every port, at each service's own address

alf connect shop --all
SERVICE    ADDRESS                     INSIDE
postgres   postgres.shop.internal      10.128.4.4 (listens on 5432)
web        web.shop.internal           10.96.8.2 (listens on 8080)
computer   computer.shop.internal      10.128.4.5

With --all the project's network becomes a network interface of your machine while it runs: every port of every service, at its own address, for any program — psql -h postgres.shop.internal, a browser at http://web.shop.internal:8080, ssh root@computer.shop.internal. The names go into /etc/hosts and come out again when you leave. Making an interface needs root, so it asks for sudo; only that part runs as root, and your sign-in and the device's key stay yours.

A computer has an SSH server already: ssh dev@computer.shop.internal, with your public key in its ~/.ssh/authorized_keys (or use alf ssh, which needs no network access at all).

What happens

The first time, the command-line tool makes a WireGuard key on your machine and registers the device with the project. Only the public half of the key is sent; the private half never leaves the machine. The device gets an address of its own in the project's network, and every server the project runs on adds it as a peer.

WireGuard runs inside the tool, with a network stack of its own: no sudo, no app, no kernel module, and nothing else on your machine sees the project's network. Only what connect opens on localhost reaches it. The connection goes out over UDP to the servers' port 51820, which most networks let through; it's kept alive every 25 seconds, so it works from behind NAT and over Wi-Fi that changes.

On your laptop, programs like psql or a browser connect to localhost:5432, where alf connect listens. The tool runs WireGuard inside itself, with its own network stack: no app and no kernel module. It talks over UDP 51820, kept alive every 25 seconds, to each server project shop runs on. There the device is in shop's network: db at 10.128.4.2:5432, and web, woken by the first connection if it's asleep. What it sends to other projects or to the server itself is dropped. The device's key is made on the laptop and only its public half is sent; every server the project runs on adds the device as a peer until its time is up or it's revoked.

What a device can reach

Pick services and ports

alf connect shop db               # only db, on the port it listens on
alf connect shop db=15432         # db on localhost:15432
alf connect shop worker:9000      # a port the service didn't say it listens on

How long a device works

30 days from when it's made, unless you say otherwise:

alf connect shop --days 7
alf connect shop --forever        # until it's revoked

In the project's Settings → Network access, Keep it… changes that at any time: 7, 30 or 90 days from now, or for good. When a device's time is up it stops working, and connect makes a new one the next time.

Seeing and revoking devices

The project's Settings → Network access lists every device: whose it is, its address, whether it's connected now — to which servers, and from which address — or when it last was, and until when it works. Devices also show on the project's canvas, under the servers they're connected to.

Revoke takes a device off the network at once, wherever it is: every server drops it within seconds. Revoked and expired devices stay in the list (Show revoked and expired ones too), so it still says who had access, and until when.

Joining a device is an owner's or an admin's to do, as opening a shell is. Its owner, or an admin, can revoke it.

On another machine

alf connect shop --config > shop.conf

prints a WireGuard configuration for the device instead of connecting: for the WireGuard app, or wg-quick up ./shop.conf on a server of your own. With it, the whole of the project's network is routed (not only localhost ports), and the services' addresses are listed at the top of the file. It has the device's private key in it: keep it to yourself, and revoke the device if it gets out.

Good to know