Self-hosting guide
Self-hosted remote desktop, on servers you control
Nelkira is remote desktop software where the directory, the relay and every session record run on servers you choose, in the country you choose. Sign-up, downloads and updates still come from nelkira.com. This guide says what runs where, what you control, and how a relay is installed.
What runs where
On each machine: the app
One small Windows installer on every machine you want to reach. Each picks up a nine-digit number and an access password, and keeps its own session record. Linux and macOS versions are to follow.
On your server: the relay
One file and no database. It introduces machines to each other and copies encrypted bytes between them when a direct path is blocked. Apart from its settings and a small file of which device key answers for each number, everything it knows is in memory, and after a restart machines reconnect within seconds.
On the machine accessed: the record
Who connected, how they got in, when it ended, which files moved and their names. Never the content. It is a plain file on that machine, and it is not yet tamper-evident.
On nelkira.com: your account
Sign-up, the download, and Nelkira Go, the phone web app at nelkira.com/app. Screen traffic never passes through the website. A session is direct where the network allows, and otherwise goes through the relay.
What you control
Where the relay sits. Every frame of a relayed session crosses it, so distance decides how the session feels. We measured a Kansas relay from Dhaka at 216 ms each way, roughly 430 ms between moving the mouse and seeing it move. A relay in Dhaka, for a session in Dhaka, measures about 75 ms. Put the relay near the users.
Who can use it. The install script generates a shared key and puts it in the address it prints. Without that key, anyone who found the address could carry their own traffic through your relay. It is not a replacement for the access password, which is checked between the two machines and never on the relay.
How much it carries. A relayed session carries the whole video stream, so plan bandwidth per relayed session, not per machine. The relay can be capped at a number of sessions at once; a second key the script generates, the admin key, guards changing that cap.
What it can read: nothing, while it only copies. The two machines agree their keys with each other and seal everything before it reaches the relay. The relay copies encrypted bytes it holds no key for. A relay changed to attack sessions could still sit in the middle of a connection let in by clicking Allow with no password. It could also pose as the machine being reached during a password sign-in from a viewer older than release 0.4.0 (from 0.4.0 the password is proved, not sent), because an older viewer still sends the password to whichever machine answers the number. Both are in the security statement.
Wrong passwords are counted per caller only when the relay says who is calling. Relay 0.3.0 does. Through an older relay, a PC on 0.4.0 counts every caller in one shared count, so four wrong passwords from anyone stop password sign-ins through that relay for up to ten minutes. Update your relay along with the PCs.
Installing a relay
Prepare a Linux box
A small virtual server (VPS) with systemd is enough, because the relay copies bytes and nothing else. Point a hostname such as relay.example.com at it, and leave port 443 reachable from the networks your machines are on.
Run the script
From the published relay folder: sudo bash ./install-relay.sh relay.example.com. It creates a service user, installs the one file and generates the shared key and the admin key. Then it registers a systemd service and waits for the relay to answer. If the new relay does not come up, it puts the previous one back.
Let Caddy get the certificate
With a hostname, the script installs Caddy, which obtains a TLS certificate on its own and puts the relay on 443 over wss://, the encrypted form. Without a hostname the relay listens on 8730 over plain, unencrypted ws://, which is fine for a trial and blocked on many networks.
Point the machines at it
The script prints relay.example.com?k=… to the terminal, and only to a terminal. On each machine, run Setup again with /RELAY="relay.example.com?k=…" (add /ALLUSERS on a PC set up for access when nobody is there); a managed rollout passes the same option. A relay named this way becomes the machine’s only relay, from the next start of Nelkira. The app has no setting for it; a rollout can also set it in the environment instead, as Agent__RelayUrl.
Keeping it running
Check it with curl https://relay.example.com/health and watch it with journalctl -u nelkira-rendezvous -f. Then time a session between two machines you own, and read the record on the accessed machine afterwards.
Running the script again installs a later version. It stops the service, replaces the file, starts it back up and keeps both keys, so machines keep the address they have. The relay we run gets later versions and its session cap from the website’s admin panel, with the same script underneath. Either way a deploy restarts the relay for a few seconds, and the sessions it was carrying reconnect on their own.
Three questions people ask
Do the machines need port forwarding or a public IP?
No. Both machines dial out to the relay, so neither needs a forwarded port or a public address. Two machines that can reach each other directly, on the same subnet and where Windows Firewall allows it, send the session straight to each other. The relay is still asked where the PC is, and a relayed path is opened and dropped while the call is set up; the session itself does not cross it.
What happens when the relay restarts?
Everything it knows is in memory and disappears. Machines reconnect within seconds, and a session it was carrying reconnects on its own after the short drop. Nothing about a session is stored on the relay.
Does the phone app use my relay?
Nelkira Go always connects through a relay, so a relay near your users is what makes phone sessions feel right. From a PC, the relay is used only when a direct path is blocked.