Installation#
PosternProxy installs directly on Debian 11/12 or Ubuntu 22.04/24.04. No Docker required.
Prerequisites#
- A fresh Debian or Ubuntu server with root access
- Ports 80, 443, and 81 open in your firewall
- A domain or IP for the management UI
Automated install#
The install script handles everything: installing the bundled Caddy, creating system users, configuring systemd, UFW, fail2ban, and unattended-upgrades.
Step 1 — Download the release binaries
Download the latest release from the
GitHub releases page.
Each release provides three binaries for your server’s architecture (amd64 for
most servers, arm64 for ARM):
| Binary | Purpose |
|---|---|
posternproxy | The controller (management UI + API) |
posternproxy-agent | The remote agent — required to manage remote servers |
caddy | A custom Caddy build with the L4 and rate-limit plugins |
The installer looks for the binaries named exactly posternproxy,
posternproxy-agent, and caddy. If the release assets carry a platform suffix
(e.g. posternproxy-linux-amd64), rename them to the bare names above.
**Prefer to build it yourself?** See [Building from source](/getting-started/building-from-source/) for building the binaries on Linux or Windows.
Step 2 — Copy the binaries and the install script to the server
Put the three binaries and install.sh in one directory — the installer finds the
binaries in the directory it runs from. The install script ships with the release;
it is also available at scripts/install.sh in the repository.
ssh root@your-server 'mkdir -p /tmp/posternproxy'
scp posternproxy posternproxy-agent caddy install.sh root@your-server:/tmp/posternproxy/Notes:
- The
caddybinary is the custom build from Step 1. Shipping it means the installer skips compiling Caddy on the server, so no Go toolchain is installed on production. If you omit it, the installer falls back to building Caddy from source (and installs Go to do so). - The
posternproxy-agentbinary is optional for a controller-only install, but it is required for provisioning remote nodes — copy it now to avoid a second trip.
Step 3 — Run the install script
ssh root@your-server
bash /tmp/posternproxy/install.shThe script will:
- Install the custom Caddy binary you shipped (or, if none was shipped, install Go and build Caddy with the L4 and rate-limit plugins on the server)
- Create
caddyandposternproxysystem users (no login shell) - Generate a random JWT secret and write
/etc/posternproxy/config.env - Install hardened systemd services for both Caddy and PosternProxy
- Apply sysctl hardening (IP forwarding, rp_filter, TCP SYN cookies)
- Configure UFW (allow ports 80, 443, 81)
- Install and configure fail2ban with a PosternProxy login-failure jail
- Enable unattended security upgrades
- Optionally harden SSH (disable root login, enforce key-only auth)
**SSH hardening prompt** The installer asks whether to harden SSH. If you choose yes, ensure your SSH key is in `~/.ssh/authorized_keys` before logging out — password auth will be disabled.
Post-install#
Once complete, the UI is available at:
http://<your-server-ip>:81On first boot, PosternProxy creates an admin account and prints a generated password to stderr, which the systemd service writes to its log file (not the journal). Check it immediately after startup:
grep -A6 "INITIAL SETUP" /var/log/posternproxy/posternproxy.logThe banner looks like:
╔══════════════════════════════════════════════════════╗
║ POSTERNPROXY — INITIAL SETUP ║
╟──────────────────────────────────────────────────────╢
║ Email: admin@posternproxy.local ║
║ Password: <random 20-character password> ║
╟──────────────────────────────────────────────────────╢
║ Change this password immediately after first login. ║
║ Set POSTERNPROXY_ADMIN_PASSWORD to silence this. ║
╚══════════════════════════════════════════════════════╝Log in with the email and generated password shown, then change it immediately.
**Setting a fixed admin password** Set `POSTERNPROXY_ADMIN_PASSWORD` in `/etc/posternproxy/config.env` before the first boot to use a specific password instead of a generated one.
**Lost the generated password?** If you missed the banner, use the `reset-password` subcommand to recover access without running the server. Run it as the `posternproxy` user with the config loaded, so it uses the correct database path and does not create root-owned database files: ```bash sudo -u posternproxy bash -c 'set -a; . /etc/posternproxy/config.env; set +a; \ /usr/local/bin/posternproxy reset-password' # or for a specific account, append: --email admin@posternproxy.local ``` A new random password is printed to the terminal.
Environment variables#
PosternProxy is configured via /etc/posternproxy/config.env. All variables are optional — sensible defaults are used if not set.
| Variable | Default | Description |
|---|---|---|
POSTERNPROXY_LISTEN_ADDR | :81 | Management UI listen address |
POSTERNPROXY_DB_PATH | /var/lib/posternproxy/posternproxy.db | SQLite database path |
POSTERNPROXY_JWT_SECRET | (persisted in <DataDir>/secret.key) | Secret for signing JWT tokens and encrypting SSH credentials — stable across restarts |
POSTERNPROXY_CADDY_API | http://localhost:2019 | Caddy admin API URL |
POSTERNPROXY_CERT_DIR | /var/lib/posternproxy/certs | Custom certificate storage |
POSTERNPROXY_CONTROLLER_URL | http://<host-ip>:81 | URL agents use to connect |
POSTERNPROXY_AGENT_BIN_PATH | /usr/local/bin/posternproxy-agent | Agent binary for provisioning |
POSTERNPROXY_ADMIN_EMAIL | admin@posternproxy.local | Initial admin email (first boot only) |
POSTERNPROXY_ADMIN_PASSWORD | (random generated) | Initial admin password (first boot only — printed to stderr if not set) |
POSTERNPROXY_BEHIND_TLS_PROXY | true | Marks session/CSRF cookies Secure. The installer writes false because the UI is served over HTTP on port 81 — browsers drop Secure cookies over HTTP, causing “missing CSRF token” errors. Set to true only when the UI is fronted by TLS and accessed over HTTPS. |
Systemd management#
# Check status
systemctl status posternproxy
systemctl status caddy
# View logs
journalctl -u posternproxy -f
journalctl -u caddy -f
# Restart
systemctl restart posternproxyCaddy plugins included#
The install script builds Caddy with two plugins beyond the standard distribution:
| Plugin | Purpose |
|---|---|
github.com/mholt/caddy-l4 | Layer 4 routing (stream hosts, TLS passthrough) |
github.com/mholt/caddy-ratelimit | Per-host request rate limiting |