wren-linux / docs / vps.md (as plain text)
The website on a VPS
Wren Linux's website, a mirror of its code, and an onion address for both, on a rented server, set
up by tools/setup-vps.sh. It is Wren Linux's home: its git copy is what pins.sh names, what new
installs clone and what computers update from. Everything here runs
as your user except where it says the server.
What you need
A VPS with Debian 13, KVM-based, with a web console (your way in if SSH ever fails). One CPU and 1 GB of RAM are plenty. For privacy, look at where the company is and what it hands over: Iceland, Switzerland and Sweden are often chosen; check the current terms yourself.
A domain (optional at first): a registrar with WHOIS privacy and DNSSEC. Without one the site is still reachable at its onion address.
On your computer: this git copy, with the signing key set up (
wren-key status), andssh.
1. Try it first, in a VM here
wrenctl install mockvps-kvm # once: QEMU, and the VM tool try-vps.sh uses
bash tools/try-vps.sh # 5-15 minutes the first time: a Debian VM, then setup-vps.sh in it
bash tools/try-vps.sh --publish # this copy's site on it
bash tools/try-vps.sh --status # its onion addresses: open the site one in Tor Browser
bash tools/try-vps.sh --uninstall
The VM is reachable from this computer only. The sandboxed Firefox can't open 127.0.0.1 (its
firewall keeps it off this computer's own services): use Tor Browser at the test site's onion
address, or curl.
The short way: one command, through Tor
Make your SSH key first (step 2's --ssh-key) and give its line to the provider when you order. Once
the server is up, with its address:
bash tools/vps-client.sh --setup SERVER-IP # --login NAME if the provider's user isn't root
It says what it will do and asks before it starts. Then steps 2, 3 and 5 below, every connection
through Tor (the server and its provider never see your address): Tor, netcat-openbsd and torsocks
installed here if missing (after asking), the onion client key, setup-vps.sh run on the server, the
second login that confirms, your Tor given the client key, the wren-vps entry in ~/.ssh/config,
and port 22 closed. Before the first login it fetches the server's key through three separate Tor
connections and goes on only if they agree: someone on one path can't slip you a false key. It keeps
that key, so no login asks about it. (For more certainty, ask the provider's support for the server's
ED25519 fingerprint and compare.)
Stay at the keyboard until it says Done. Over Tor, a login waits only about a minute for what
it asks. It offers to take your SSH key's passphrase once, at the start, into an ssh-agent of that
run alone, stopped when it ends; otherwise each login asks it. Each sudo on the server asks your
user's password there (that one waits 5 minutes). With the sound extra, it offers a gong each time
it waits for you to type something. If it stops anyway, nothing is lost: wait 10
minutes, while the server puts back what wasn't confirmed, then run it again.
Without a domain yet, press Enter at its question and add it later (step 4). If it stops after the
first confirmation, bash tools/vps-client.sh --onion-only does the rest.
If it installs Tor, it asks first whether you need a bridge, which kind, and your bridge lines, as
Wren's other Tor scripts do. To add, change or remove them later: bash tools/vps-client.sh --bridges.
This computer's Tor is shared: if apt over Tor or remote access set up its bridges, change them
there instead (it says so).
The steps below are the same, by hand.
2. Your keys
bash tools/vps-client.sh --ssh-key # ~/.ssh/wren-vps, with a passphrase; prints its public line
bash tools/vps-client.sh --keygen # the onion client key; prints its public half
Back up ~/.ssh/wren-vps and ~/.config/wren/vps/wren-vps.key with your other keys (KeePassXC can
hold the files). The public halves aren't secret. Reinstalling this computer later: see
Reinstalling this computer.
3. Set up the server
Most providers let you log in as root with a key or a password the first time. Copy the script there and run it:
scp tools/setup-vps.sh root@SERVER:
ssh -t root@SERVER bash setup-vps.sh
(-t gives it a terminal to ask on.)
It asks what it needs, each question explaining its choice: your user's name, your SSH public key (from step 2), the domain, the email for certificate notices, the onion site, onion SSH and your onion client key (from step 2).
It asks a password for your user (sudo, and the web console; SSH never takes it). Keep it in your password manager.
To set it up without questions, or the same way on a second server, put the answers in a file (the
names are in the script's header) and run bash setup-vps.sh --config FILE --yes.
Then confirm, from a second terminal, while the first stays open:
ssh -i ~/.ssh/wren-vps wren@SERVER
sudo wren-vps --confirm
Until you do, the new SSH and firewall settings undo themselves after ten minutes, so a mistake can't lock you out. If the second login fails, wait: the old settings come back.
4. The domain's DNS
At your registrar, for example.org (yours):
A (and AAAA for IPv6): the server's address, for
example.organdwww.CAA:
0 issue "letsencrypt.org": no other company may issue a certificate for your domain.DNSSEC: on, so nobody on the way can fake these answers.
Caddy fetches the HTTPS certificate by itself once the A record points at the server. Give setup-vps.sh the domain only when it is ready (registered, not "pending", and its A record already at the server): otherwise press Enter at its question, and once it is ready, on your computer:
bash tools/vps-client.sh --domain example.org
It looks the domain up through Tor, checks it points at the server, gives it to the server through
the onion login, confirms from a second one, and waits for the certificate. (By hand: VPS_DOMAIN= in
/etc/wren-vps.conf, then sudo wren-vps, and sudo wren-vps --confirm from a new login.)
5. SSH through the onion, then close port 22
The script printed the SSH onion address. On your computer:
bash tools/vps-client.sh --tor-auth ONION.onion # prints a few sudo commands: run them
bash tools/vps-client.sh --ssh-config wren ONION.onion # add what it prints to ~/.ssh/config
ssh wren-vps # through Tor
Once that login works, from it:
sudo wren-vps --ssh-onion-only
Port 22 then closes to the whole internet: nobody can find SSH, scan it or guess at it, and the
server's logs no longer see your home address. Confirm from another onion login (ssh wren-vps,
sudo wren-vps --confirm).
If Tor is ever down, the provider's web console still lets you in; sudo wren-vps --ssh-public
opens port 22 again.
6. Publish
bash tools/vps-client.sh --origin # once: this copy's server is your own mirror, over ssh through Tor
bash tools/git-push.sh # signs the newest commit and pushes it there (or: wren-release)
bash tools/publish-site.sh # the same commit as the site
--setup writes ~/.config/wren/vps/site.conf (the server's ssh name and the site's onion address)
for publish-site.sh; by hand:
printf 'VPS_HOST=wren-vps\nVPS_SITE_ONION=%s\n' SITE-ONION.onion >~/.config/wren/vps/site.conf.
The first push sends the whole history to the new mirror, and from then on your copy follows it, so
update.sh fetches from it. No CI looks at what is pushed there: run bash test.sh --offline first.
publish-site.sh builds the site only from a commit your key signed, so the site shows exactly what
the key vouched for, and its pages say so.
Reinstalling this computer (or a new one)
The server needs nothing new: this computer gets back what it needs to reach it. Before you wipe it,
with a USB stick mounted (usb mount):
bash tools/vps-client.sh --backup /media/$USER/STICK # one file, encrypted with a passphrase you choose
It writes wren-vps-backup-DATE.gpg there: AES-256 with gpg's slowest key derivation, packed in
memory (/dev/shm) so nothing unencrypted touches a disk, and opened again from the stick before
it says it is done. It asks before using a folder on this computer. Keep the passphrase on paper,
apart from the stick, and a copy of the file on a second stick. At its end it lists, in red, what
else this computer has that a reinstall would wipe (KeePassXC's databases, a vault, wallets, keys, a
git copy's unpushed work, your documents), each with the command that backs it up to that folder.
What the backup itself holds:
| What | Where | Why |
|---|---|---|
| Your SSH key, both halves | ~/.ssh/wren-vps, ~/.ssh/wren-vps.pub | the only key the server takes |
| The onion client key | ~/.config/wren/vps/wren-vps.key | without it this computer can't even find the server's SSH address |
| The publish settings | ~/.config/wren/vps/site.conf | the site's onion address (it can be fetched again) |
| Your user there, and the SSH onion address | the wren-vps entry in ~/.ssh/config (User, HostName) | what --reconnect asks for |
| The server's key | its line in ~/.ssh/known_hosts (ssh-keygen -F wren-vps shows it) | so a server showing another key is refused |
| Your bridge lines, if you use any | /etc/tor/torrc | used again if --reconnect sets up Tor here; otherwise Tor asks for them |
After the reinstall, with the stick mounted:
bash tools/vps-client.sh --reconnect --from /media/$USER/STICK # the newest backup there (or name the file)
bash tools/vps-client.sh --origin # a new git copy: push to the server again
It asks the backup's passphrase and puts each file back, yours alone, never over a different key
already there. Without the backup, put the keys back by hand and give what it can't know:
--reconnect wren SSH-ONION.onion (your user there, and its SSH onion address).
Then it installs Tor here (after asking; with the backup's bridges, checked as typed ones are, or it
asks about bridges), gives it the onion client key, writes the
wren-vps entry, and logs in through the onion address. It changes nothing on the server. With
the known_hosts line put back, a server that shows another key is refused. Without it, the key the
server shows is kept: the onion address vouches for it (only the server holds what answers there),
so that is as safe as the address you typed is right. Lost the onion client key? Make a new one
(--keygen) and give its public half to the server from the provider's web console.
What it sets up, and why
| What | Why |
|---|---|
| Your own user; SSH keys only, no root, no passwords | Nothing to guess: without your key file, SSH can't be got into. |
| nftables: only SSH (rate-limited) and the web in | Nothing else on the server can be reached, even by mistake. |
| Caddy, with HTTPS from Let's Encrypt, renewed by itself | Visitors get an encrypted, checked connection with no work from you. |
| Strict headers: no script, frame or outside resource | A page can't be turned into an attack, even if a file on it is changed. |
| No log of visitors | There is nothing to hand over about who read what. |
| Caddy locked down by systemd | A hole in the web server reaches little: it can read the site and nothing more. |
The onion site, and Onion-Location | Tor Browser visitors stay inside Tor: nobody on the way sees what they read. |
| Onion SSH with a client key | Only your key can even find SSH, and port 22 can close for good. |
| Daily security updates, a nightly reboot when needed | Known holes close by themselves. |
| The never-locked-out switch | Every SSH or firewall change must prove itself from a new login. |
What it doesn't protect
The provider can see everything. It runs the machine: it can read the disk and the memory. Keep nothing on the server that the site doesn't need, and never the signing key.
The onion site hides the readers, not the server. The same site is on the normal web at the server's address.
A first download is only as good as its check. If the server were ever broken into, computers with Wren Linux's pin would still refuse anything the key didn't sign; but someone downloading for the first time must compare the fingerprint somewhere else too (the Verify page says so).
Traffic analysis. The provider and the networks on the way still see that the server is visited, when, and how much.