Own Your Outbox: Running Haven as Your Personal Nostr Relay

Own Your Outbox: Running Haven as Your Personal Nostr Relay

Nostr promises censorship resistance through decentralization. Your identity lives in a keypair you control. Your notes carry cryptographic signatures no relay can forge. You choose which relays to use.

But there's a gap between the promise and the implementation. If you rely on third-party relays, you depend on their uptime, their retention policies, their willingness to serve your content. They can go offline, get banned, or simply decide your notes aren't worth storing. Your query patterns are visible to every relay you connect to. Your data persists only as long as someone else chooses to keep it.

The fix is straightforward. Own the relay.

If you operate the machine, there is no adversary to hide from. Your query patterns exist only in logs you control. Your data persists as long as you choose. No third party can ban you, go offline unexpectedly, or hand over records. The outbox model described in NIP-65 assumes users control their outbox relays. Running your own makes that assumption true.

Haven's Architecture

Haven, created by the bitvora team, packages everything you need for personal relay infrastructure in a single binary:

Private relay (/private): Auth-protected storage for drafts, eCash tokens, and data nobody else should access. No external reads or writes.

Chat relay (/chat): Web-of-trust filtered endpoint for DMs and group chats. Only contacts within your WoT can interact.

Inbox relay (/inbox): Receives notifications when you're tagged. Zaps, reactions, replies land here. Haven automatically pulls mentions from other relays.

Outbox relay (root path): Your public notes. Import historical content, blast new posts to other relays. You write, anyone reads.

Blossom media server: Self-hosted images and videos with shareable URLs.

The database is embedded (BadgerDB by default, LMDB optional), eliminating external dependencies. Smart features include Web of Trust spam filtering, automatic note import from other relays, cloud backup to S3-compatible storage, and blastr republishing.

VPS Over Home Hosting

Running a relay at home exposes your residential IP address to the internet. Services like Shodan and Censys catalog open ports within hours. Your home network becomes visible to anyone who queries your relay URL. DDoS attacks can knock your household offline. Port forwarding punches holes in your router's firewall.

A VPS isolates this risk. Your home IP stays private. Attacks target infrastructure designed for public exposure. The hosting provider handles physical security, power redundancy, and network uptime.

The cost is negligible. Hetzner offers 2 vCPU, 4GB RAM, and 40GB NVMe for roughly €4/month. Vultr and DigitalOcean start at $6/month. For privacy-focused hosting, Mynymbox (mynymbox.net) accepts Bitcoin and Lightning via self-hosted BTCPayServer, requires no personal information, and operates from privacy-friendly jurisdictions including the Netherlands, Finland, and Germany.

Haven's resource requirements are modest. Personal relay usage needs perhaps 1GB RAM and minimal CPU. Text events are small; years of notes fit in a few gigabytes. NVMe storage helps if using LMDB.

Deployment Guide

The following assumes Ubuntu 24.04 on a fresh VPS. Adapt paths and package managers for other distributions.

Initial Access and User Setup

SSH into your server as root, then create a non-root user:

adduser haven
usermod -aG sudo haven

Copy your SSH public key to the new user:

mkdir -p /home/haven/.ssh
cp ~/.ssh/authorized_keys /home/haven/.ssh/
chown -R haven:haven /home/haven/.ssh
chmod 700 /home/haven/.ssh
chmod 600 /home/haven/.ssh/authorized_keys

SSH Hardening

Edit /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
X11Forwarding no

Restart SSH:

systemctl restart sshd

Before disconnecting, verify you can log in as the new user from another terminal.

Firewall Configuration

ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

System Updates

apt update && apt upgrade -y
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Download and Configure Haven

Switch to the haven user:

su - haven
mkdir haven && cd haven

Download the latest release from GitHub:

curl -sL https://api.github.com/repos/bitvora/haven/releases/latest | grep "browser_download_url.*linux_amd64" | cut -d '"' -f 4 | xargs curl -L -o haven.tar.gz
tar -xzf haven.tar.gz

Create configuration files:

cp .env.example .env
cp relays_import.example.json relays_import.json
cp relays_blastr.example.json relays_blastr.json

Edit .env with your settings:

RELAY_NAME="Your Relay Name"
RELAY_PUBKEY="your_hex_pubkey"
RELAY_DESCRIPTION="Personal relay"
RELAY_URL="wss://relay.yourdomain.com"

Your hex pubkey can be derived from your npub using any Nostr tool or library.

Create Systemd Service

Create /etc/systemd/system/haven.service:

[Unit]
Description=Haven Relay
After=network.target

[Service]
ExecStart=/home/haven/haven/haven
WorkingDirectory=/home/haven/haven
User=haven
Group=haven
Restart=always
MemoryLimit=1000M

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable haven
sudo systemctl start haven

Verify it's running:

sudo systemctl status haven

Reverse Proxy with Caddy

Caddy handles TLS automatically:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf ' https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf ' https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Edit /etc/caddy/Caddyfile:

relay.yourdomain.com {
    reverse_proxy localhost:3355 {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
    request_body {
        max_size 100MB
    }
}

Reload Caddy:

sudo systemctl reload caddy

Ensure your domain's A record points to the VPS IP before Caddy attempts certificate issuance.

Import Historical Notes

After initial setup, import your existing notes:

sudo systemctl stop haven
cd /home/haven/haven
./haven --import
sudo systemctl start haven

Verify Operation

Your relay endpoints:

  • wss://relay.yourdomain.com (outbox + Blossom)
  • wss://relay.yourdomain.com/private
  • wss://relay.yourdomain.com/chat
  • wss://relay.yourdomain.com/inbox

Test with any Nostr client by adding your relay URL to your relay list. Update your NIP-65 relay list (kind 10002) to advertise your new outbox.

What You've Built

Your notes now persist on infrastructure you control. Query patterns exist only in your logs. The inbox relay receives mentions automatically. The outbox blasts your content to the broader network. Web of trust filtering keeps spam out of your DMs.

The outbox model works better when you control your outbox. Now you do.