Wren Linux

wren-linux / docs / vps.md (as a page)

# 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`), and `ssh`.

## 1. Try it first, in a VM here

```bash
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
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
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](#reinstalling-this-computer-or-a-new-one).

## 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:

```bash
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:

```bash
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.org` and `www`.

- **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
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
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:

```bash
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
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
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
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.