Install Guide: Hermes + Tailscale on VPS
Setting Up Hermes Agent with Tailscale on Hetzner
Architecture: Hermes Agent runs on Hetzner VPS under dedicated user hermes, accessible only via Tailscale WireGuard tunnel (UDP 41641). Public SSH (TCP 22) is blocked at Hetzner Firewall level.
Your Laptop (Tailscale) ---- Tailnet (WireGuard) ----> Hetzner VPS (Tailscale)
├── Hermes Agent (user 'hermes')
└── Gateway (Telegram/Discord/etc.)
Hetzner Firewall: ✅ UDP 41641 (Tailscale) | ❌ TCP 22 (SSH blocked publicly)
Prerequisites
Make sure you have these before you start:
- Hetzner Cloud account + Tailscale account (free tier works)
- Tailscale installed locally on your machine
- SSH key pair (public key registered with Hetzner)
- LLM API key (OpenRouter, Nous Portal, OpenAI, etc.)
Phase 1: VPS Creation
Settings to choose:
| Setting | Recommendation |
|---|---|
| Image | Ubuntu 24.04 or Debian 12 |
| Type | CX22 (2 vCPU, 4GB RAM, |
| SSH Key | Add during creation — critical for initial access |
| Networking | Default public IPv4/IPv6 enabled |
Note the public IP — you’ll need it for initial setup.
Phase 2: Initial System Setup (as root)
SSH in as root using the public IP Hetzner gave you:
# Update system
apt update && apt upgrade -y
# Create dedicated user
adduser hermes
usermod -aG sudo hermes
# Copy SSH key to new user
mkdir -p /home/hermes/.ssh
cp /root/.ssh/authorized_keys /home/hermes/.ssh/authorized_keys
chown -R hermes:hermes /home/hermes/.ssh
chmod 700 /home/hermes/.ssh
chmod 600 /home/hermes/.ssh/authorized_keys
⚠️ Critical: Keep this root session open. Test the new user in a second terminal before closing it.
Verify access in your second terminal:
ssh hermes@<public-ip>
sudo whoami # Should output: root
Harden SSH (back in root session)
nano /etc/ssh/sshd_config
Set these values:
PermRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart SSH:
systemctl restart sshd
Verify hermes user still works, then close root session.
Phase 3: Install Tailscale (BEFORE Firewall)
🚨 CRITICAL: Install and verify Tailscale BEFORE applying Hetzner firewall or you’ll be locked out of your own server.
As hermes user:
# Install
curl -fsSL https://tailscale.com/install.sh | sh
# Authenticate
sudo tailscale up
# Visit the printed URL to authorize your device
# Get Tailscale IP
tailscale ip -4
# Returns: 100.x.y.z (remember this)
Verify SSH over Tailscale
From your local machine:
ssh hermes@100.x.y.z
✅ Do not proceed until this works. If you can’t SSH via Tailscale IP, do not apply the firewall rules yet.
Phase 4: Lock Down Firewall
In Hetzner Console
Go to Firewalls, then Create Firewall.
- Delete all default rules (remove pre-populated SSH/ICMP rules)
- Add this single inbound rule:
| Protocol | Port | Source | Purpose |
|---|---|---|---|
| UDP | 41641 | 0.0.0.0/0, ::/0 | Tailscale WireGuard direct connections |
Apply to server (hermes-vps).
Verification
From local machine — public SSH should now fail:
# This should timeout or refuse
ssh -o ConnectTimeout=5 hermes@<public-ip>
Tailscale SSH should still work:
# This should connect instantly
ssh hermes@100.x.y.z
Phase 5: Install Hermes Agent
As hermes user over Tailscale SSH:
# Install
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
source ~/.bashrc
# Configure LLM provider
hermes setup
# Options: OpenRouter (200+ models, free tier), Nous Portal (OAuth), OpenAI/Anthropic
# Test
hermes
hermes doctor # Run diagnostics
Management Commands
hermes model # Switch provider/model
hermes tools # Enable/disable tools
hermes update # Update agent (preserves config/memory/skills)
Phase 6: Messaging Gateway (Optional)
For Telegram/Discord/Slack integration:
# Configure platforms
hermes gateway setup
# For Telegram: need Bot Token from @BotFather
# Install as systemd user service
hermes gateway install
# Enable persistent boot (run even when not logged in)
sudo loginctl enable-linger hermes
# Manage service
systemctl --user start hermes-gateway
systemctl --user enable hermes-gateway
journalctl --user -u hermes-gateway -f # View logs
Phase 7: Automatic Security Updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades # Select Yes
Optional auto-restart for kernel updates:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Uncomment:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
Quick Reference
| Task | Command |
|---|---|
| SSH Access | ssh hermes@100.x.y.z (Tailscale IP only) |
| Start Hermes CLI | hermes |
| Change Model | hermes model |
| Configure Tools | hermes tools |
| Start Gateway | hermes gateway |
| Gateway Logs | journalctl --user -u hermes-gateway -f |
| Diagnostics | hermes doctor |
| Update Hermes | hermes update |
| Tailscale Status | tailscale status |
Security Layers
| Layer | Protection | Implementation |
|---|---|---|
| Network | SSH access | Hetzner Firewall blocks TCP 22; only UDP 41641 allowed |
| Tunnel | WireGuard encryption | Tailscale handles key rotation, NAT traversal |
| OS | Dedicated unprivileged user | hermes user with sudo for specific commands |
| Application | Least-privilege API tokens | Read-only Calendar, no admin GitHub scopes |