Nodes
…

Scored so the worst comes first: one machine offline is 5 points; a whole site offline (every machine behind one internet address — a power cut or a dead line) is 10 per machine; a watched laptop on battery is 15 (30 when low). 30+ is critical, 15+ high, 5+ warning. Site and power problems also raise an alert — see Settings.

Pick a node from the list on the right.
Pick a node from the list to reach it.

Coming soon. A gateway turns a node into a doorway onto its network: point your browser or apps at the gateway and reach hosts behind it as if you were on-site, without setting up a tunnel per service.

No gateways set up yet.

When this feature ships, you will pick a node, choose what it may reach (whole subnet, or selected hosts), and get a single address to connect through — with access controlled per user.

Names under this server's domain, each with its own Let's Encrypt certificate, renewed for as long as the name is here. Every name resolves already — a wildcard record points the whole domain at this server — so a certificate normally arrives within seconds of adding one.

…
HostnameCertificate IssuedCreated
A name is only a name here. Point one at something from the page that uses it — the VPN today. Pointing one at a port on a node, so a camera or a web page answers at its own address, is the next thing this grows into.
Primary…
Backup…
In use…

Profiles

ProfileNetwork Clients hereMay use Clients

Clients

NameProfile AddressEnabled Last seen — primary Last seen — backup

Xray — VLESS with REALITY

…
Every code you have handed out stops working the moment you do.

AmneziaWG

Obfuscation numbers

Profiles

ProfileNetwork Clients hereMay use Clients

Clients

NameProfile AddressEnabled On the VPN Added
Pick a node from the list to browse its files.

A mount makes a folder on a node appear as an ordinary folder on your own computer, so you can open its files in your editor and file browser. The node serves its files itself, and the node on your computer mounts them with rclone, which it fetches from this server into its own folder the first time; nothing is installed on either machine. Your computer must be a node too: that is where the connection comes out. Where folders land is set on the Settings page. Access is full (root). For one-off transfers, use Files.

New mount

Mounts

Files fromMounted onStatePassword

Each node has its own password, kept by this server. New password changes it for every mount of that node: folders already mounted stay mounted, but the next connection needs the new command.

A mount looks after itself: if rclone stops, the folder disappears, or it stops answering (checked every 30 seconds), the node mounts it again. remount does the same on demand.

… Group:

Uptime checks run from a node against something on its network. Add one from the Map — pick a node, open its Ping tab. The reserved Excluded group keeps a host in the config but stops testing it.

NameHostMethodVia nodeEvery StatusLatencyLast onlineMissed sinceGroup
… · connections, policy changes, and remote actions across all nodes
TimestampNodeActionResult
UsernameLast loginFromCountrySigned inTwo-factor
Sessions are cookies the server does not keep a list of, so Signed in means the account has used the panel in the last few minutes.

Change your password

Changing a password does not sign anything out: a session already open stays open until it expires.

Two-factor sign-in

Works with Authy, Google Authenticator, Microsoft Authenticator, Aegis, 1Password — any app that scans a QR code and shows six-digit codes.

Require it for everyone

With this on, an account that has not set one up is made to during its next sign-in — the password alone gets it no further than the QR code, and no session is opened until a code from the new phone is accepted. Sessions already open are asked the same thing before they can do anything else. Turning it on applies to you too.

Add user

An existing username has its password reset, and keeps its login history.

Every platform this server can enroll, and what is built for each right now. A name listed but not built would 404 if an installer asked for it — which is why the missing ones are still shown rather than quietly left out.

PlatformArchFileVersionglibcMin distroSizeBuiltChecksum

Download pinned certificate (unicomplex-cert.der)

Run this on any Linux machine to enroll it as a node (detects arch, installs a root systemd service):

…

The x86_64 build carries the system tray, so it links GTK at load time, and on a headless x86_64 box with no GTK it will not start. The installer handles that itself — before installing anything it runs the client once, and if it will not start it falls back to node-docker-x86_64, the same node built static with the tray compiled out, and says so while it does it. Nothing to pick: the command above is the right one on a desktop and on a headless server alike.

Debug install — writes a log file (for when an install succeeds but the node then won't run)

Same install, with the node's log turned on → /var/log/interlink-node.log. Read it with journalctl -u interlink-node.

…

From PowerShell — run it as Administrator to install for the whole machine and start at boot; run it as yourself to install for your account and start at logon:

…

From cmd.exe — cmd cannot run a script straight off a pipe, so this fetches one with the curl Windows ships with, runs it and deletes it. This one is cmd syntax: in PowerShell && is not a separator and curl means Invoke-WebRequest, so it will not run there.

…
Debug install — writes a log file (for when an install succeeds but the node then won't run)

Same install, with the node's log turned on → node.log in the install dir. Read it with Get-Content …\node.log -Tail 40.

…

Coming soon. macOS enrollment will work the same way as Linux: one command that fetches the client, installs it as a launchd service, and brings the machine into the collective at next login.

No macOS client built yet.

Apple silicon cannot be cross-compiled from this project's build host — the SDK is Apple's to hand out, not ours to ship — so the binary has to be built on a Mac and dropped in. The download name is reserved either way, and the Overview tab shows it as not built rather than pretending the platform is unsupported.
curl -fsSL "https://…/install.sh?token=…" | bash

The node, in a container — for a machine where installing a service is not wanted or not possible: a NAS with a read-only system partition, an immutable host, or a box that is only ever managed through its container manager.

This build is static: x86_64 musl, with the system tray compiled out. It links nothing at all, so it starts on any image — including one with no libraries. The ordinary x86_64 Linux build cannot, because the tray links GTK at load time.

On a headless machine you do not have to come here for it — the Linux installer falls back to this same binary by itself when the ordinary one will not start. This tab is for when you want it in a container.

How do you run containers on that machine?

TrueNAS SCALE

Nothing to build and nothing to download first. TrueNAS cannot build an image from its own web interface, so this YAML does not ask it to: it starts a stock Alpine container which fetches the node on first run and keeps it in the data directory, reusing it on every start after that.

Make the dataset first — before you deploy anything. It has to exist, and it has to be on one of your data pools. If the path in the YAML does not exist, Docker quietly creates it on the system filesystem instead, and TrueNAS mounts that noexec. Everything then looks like it worked — the app deploys, the node downloads — and it silently never starts, because a binary on a noexec filesystem cannot be run. The app flaps and ends up stopped, with nothing in any log to say why.

  1. Find your pool's real name. Storage — the name at the top of each pool. tank is only the usual example; yours is very likely called something else.
  2. Make the dataset. Datasets → Add Dataset, for example yourpool/apps/unimatrix. This is what keeps the node's identity — without it, it joins as a brand-new machine every redeploy.
  3. Apps → Discover Apps → the three dots → Install via YAML. Give it a name.
  4. Paste the YAML and deploy. Change the two lines marked CHANGE ME: the dataset path you just made, and the hostname you want in the roster.

Portainer, Synology, Unraid, or any YAML box

The same single paste as TrueNAS — only the menu differs. Portainer: Stacks → Add stack → Web editor. Synology: Container Manager → Project → Create. Unraid: Docker → Compose.

Make the data directory first, on real storage, and point the volume line at it. If the path does not exist Docker invents it somewhere of its own choosing — on a NAS that is often a system filesystem mounted noexec, where the node downloads perfectly and then cannot be started.

A shell on the machine

With a shell you can build a proper image, which is tidier than bootstrapping at start-up: the node is baked in, so a start needs nothing from the network and nothing is fetched twice.

Save this as Dockerfile — that is the whole recipe. It fetches the binary itself while building, so there is nothing to download first. Alpine rather than an empty image because two of the node's features want a userland: a remote shell spawns bash, and network discovery uses nmap when it is there. Nothing is needed for TLS — the certificate roots are compiled into the binary.

…

Then, in the same folder:

…

And run it with the compose file below.

copied ✓

File mounts

{node} becomes the name of the node the files come from, so seg-lab1's files land in /net/seg-lab1. Used for new mounts and for the commands on the File mounts page; a mount already running keeps its folder until you mount it again.

Alerts

A whole site going offline, or a watched laptop switching to battery, is written to the Log and shown as a desktop notification on the computers ticked here (Linux for now), when it starts and again when it is over.

A user group is a set of people that reaches one or more node groups. Somebody in a user group sees and manages only the nodes inside the node groups it reaches — everything else is not merely hidden from the roster, it is refused if asked for directly.

Granting All grants every node, now and in future — that is the plain way to say "this person sees everything". Every node is in All whatever else it is filed under, so no machine is ever invisible for want of being filed.

An account in no user group is unrestricted and sees every node, which is what every account was before this page existed. Restricting somebody is a deliberate act, so nobody is shut out by surprise.

Anyone signed in can edit this page, including their own group. This decides what people see by default; it is not a wall. Rights come later.

Accounts

AccountIn user groupsSees

The groups nodes are arranged into — the same ones the node roster and the map use. Click a name to rename it. All is built in: every node is in it, nothing can be taken out of it, and it cannot be removed.

To put nodes in a group, tick them in the node roster and choose Move to group from Actions. Any number at once, and the ticks respect whatever you have filtered or searched for.

GroupNodes Reached by

Dark mode
Overrides your system theme for this browser.