# 1. Installing

## What you need

- A server (virtual or physical) with a **fresh** installation of **Debian 13** or **Ubuntu 24.04**, 64-bit.
  A fresh server is best: the installer sets up its own web server and firewall.
- Root access (`sudo`) and some free disk space (the setup check asks for at least 500 MB). The application is light; a small virtual server is enough. A fresh Debian has no `curl` yet (`sudo apt install -y curl`), which you need to download the release.
- A way for people to reach the server: a public IP address or a DNS name, with **UDP 1194** (the VPN) and
  **TCP 8443** (the web interface) allowed through any router or cloud firewall in front of it. SSH stays open.

## Installing

Everything below is run on the server. The [download page](https://tunnelry.com/install/) shows the same commands with
the current version filled in; replace `X.Y.Z` here with that version.

**1. Download the release** into a new directory. The loop fetches the archive, its checksum list and signature, the
installer, the uninstaller and the public signing key:

```bash
mkdir tunnelry && cd tunnelry
BASE=https://updates.tunnelry.com/releases/X.Y.Z
for f in tunnelry-X.Y.Z.tar.gz SHA256SUMS SHA256SUMS.sig install.sh uninstall.sh release-key.pub.pem; do
  curl -fsSL -O "$BASE/$f"
done
```

If the server has no internet access, download the same files on another computer and copy them into one directory on
the server (for example with `scp`).

**2. Check the key.** Compare this fingerprint with the one on the download page, so you know the key is the project's:

```bash
openssl pkey -pubin -in release-key.pub.pem -outform DER | sha256sum
```

**3. Run the installer** as root, from that directory:

```bash
sudo bash install.sh --archive tunnelry-X.Y.Z.tar.gz
```

The installer verifies the signature of the release before it unpacks anything, installs the packages it needs
(nginx, PHP, OpenVPN, easy-rsa, nftables, unbound, sqlite3), creates an unprivileged `tunnelry` user for the web
application, writes the system files and starts the web interface. It takes a few minutes and ends with this:

```
Tunnelry <version> is installed.

  Open:         https://203.0.113.10:8443
  Certificate:  self-signed; SHA-256 fingerprint 54:6B:02:...
  Setup token:  dZIFQnsv1MLAHFjgJvV1lBvYU8cjqUIJ
```

**Write down the setup token.** It is shown once and lets you create the first administrator. If you lose it, run
the installer again with `--new-token`.

The web interface starts with a **self-signed certificate**, so your browser warns you the first time. Compare the
SHA-256 fingerprint in the browser's certificate details with the one the installer printed before you accept.

## Options

| Option | Meaning |
|---|---|
| `--public-key FILE` | verify the signature with this Ed25519 public key (use the key published with the release) |
| `--gui-port PORT` | port of the web interface (default 8443) |
| `--address HOST` | address shown in the URL and certificate (default: the server's main IPv4 address); use a DNS name if people will reach it by name |
| `--update-url URL` | where the **Updates** page looks for new versions (`https` only) |
| `--new-token` | issue a new one-time setup token |
| `--force` | continue although the checks found something unusual (other web sites on the machine, another distribution) |

Running the installer again is safe: it repairs or refreshes the installation without changing its keys.
The installer's log is kept in `/var/log/tunnelry-install.log`.

## What it changed on the server

Everything Tunnelry owns is in a few places, so you always know what it touched:

| Place | What |
|---|---|
| `/opt/tunnelry` | the application (one folder per version, `current` points at the active one) |
| `/var/lib/tunnelry` | its data: the database, settings, backups |
| `/etc/tunnelry` | the certificate authority and the server's state (root only) |
| `/etc/openvpn/server` | the OpenVPN configuration it generates |
| `/usr/lib/tunnelry` | the privileged helper `vpnctl` |
| nginx site, PHP pool, sudoers rule, systemd units, nftables table `tunnelry` | generated by Tunnelry and rewritten on update |

Next: [the setup wizard](https://tunnelry.com/docs/setup-wizard/index.md).
