Overview

This document synthesizes architectural patterns for securing homelab infrastructure through hardened SSH configuration, bastion/jump host design, fleet management protocols, and zero-trust overlay networks. It represents the evolution from “functional” to “professional-grade” homelab operations, emphasizing identity-based access, minimal attack surface, and operational sanity for solopreneur infrastructure.

SSH Hardening Fundamentals

Modern Cryptographic Standards

The operational standard has definitively moved from RSA to Ed25519 keys. These provide superior cryptographic resilience with smaller key sizes and faster performance.

Key Generation:

ssh-keygen -t ed25519 -C "homelab-key-2026" -f ~/.ssh/id_ed25519_homelab

Distribution Workflow:

ssh-copy-id -i ~/.ssh/id_ed25519_homelab.pub user@192.168.1.10
ssh-copy-id -i ~/.ssh/id_ed25519_homelab.pub user@192.168.1.20
# Repeat for all managed nodes

For environments with multiple devices, a “One Key, Many Machines” strategy is the baseline for personal fleets. Mature setups evolve to:

  • Phase 1: One key, many machines
  • Phase 2: One key per role (human vs. automation)
  • Phase 3: One key per device
  • Phase 4: Short-lived SSH certificates (advanced)

Passphrase Strategy: Using a passphrase adds encryption to the key file itself. For operational convenience, use ssh-agent or AddKeysToAgent yes in your SSH config to avoid repeated prompts.

SSH Daemon Hardening

Default SSH configurations are built for compatibility, not security. The /etc/ssh/sshd_config file on every managed node must be explicitly hardened to enforce a Zero-Password posture.

Mandatory Hardening Settings:

SettingValueRationale
PasswordAuthenticationnoForces key-only authentication, neutralizing brute-force password attacks
PermitRootLoginnoPrevents attackers from targeting the administrative account directly
PubkeyAuthenticationyesEnables cryptographic key authentication
MaxAuthTries3Limits failed attempts per connection, reducing bot noise
ChallengeResponseAuthenticationnoDisables keyboard-interactive authentication
UsePAMyesMaintains PAM integration for session management
AllowUsersyouruserRestricts SSH access to specific user accounts
ClientAliveInterval300Sends keepalive messages every 5 minutes
ClientAliveCountMax2Disconnects after 2 failed keepalives

Optional Port Changes: While changing the default port (22 to 2222) is “security by obscurity” and not a primary defense, it significantly reduces log noise from internet-wide scanning bots. This is noise reduction, not real security.

Implementation Protocol:

sudo nano /etc/ssh/sshd_config
# Apply settings above
sudo systemctl restart ssh

Critical Safety Rule: Always keep your current SSH session open while testing new configurations in a separate terminal to avoid self-lockout.

Active Defense Layers

Fail2Ban/CrowdSec: Mandatory for any internet-facing node. These tools monitor authentication logs and automatically ban IP addresses exhibiting brute-force behavior.

MFA for SSH (Advanced): For high-value nodes, layer SSH keys with Time-based One-Time Passwords (TOTP) to require a physical second factor during login. This combines “something you have” (the key) with “something you know” (the TOTP code).

Network Hygiene and Infrastructure Foundation

Static IP Strategy

Do not set static IPs on devices themselves. Use DHCP Reservations at the router level. This centralizes management—if you change subnets later, you only change it in one place.

Rationale: Configuration-driven SSH environments fail if the underlying addressing is volatile. DHCP reservations guarantee deterministic addressing (NAS always gets .20, Pi always gets .10) while keeping network configuration centralized and auditable.

Example Allocation:

  • 192.168.1.10 → Raspberry Pi
  • 192.168.1.20 → NAS
  • 192.168.1.30 → Desktop
  • 192.168.1.5 → Jump Host/Bastion

Installation Checklist

Linux (Ubuntu/Debian/RPi OS):

sudo apt update && sudo apt install openssh-server -y
sudo systemctl enable --now ssh

Windows 10/11:

  • Settings → Apps → Optional features → Add a feature → OpenSSH Server → Install
  • Services → OpenSSH SSH Server → Startup type: Automatic, Start service

Config-Driven Fleet Management

The SSH Config as Infrastructure Atlas

Relying on raw IP addresses (ssh user@192.168.1.50) is an unscalable practice that hinders velocity. The ~/.ssh/config file functions as the infrastructure atlas, codifying connection parameters and abstracting the network layer from the management layer.

Example Advanced Configuration:

# Global defaults
Host *
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_ed25519_homelab
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
 
# Specific Machines
Host pi
    HostName 192.168.1.10
    User pi
 
Host nas
    HostName 192.168.1.20
    User admin
 
Host media-server
    HostName 192.168.1.50
    User logic
    ProxyJump jump
 
Host jump
    HostName 192.168.1.5
    User admin

Operational Value:

  • No IP memorization required
  • No port juggling
  • Easy machine rotation
  • Clear mental topology
  • Complex connectivity requirements defined once, executed effortlessly

Usage:

ssh pi        # Instant login to Pi
ssh nas       # Instant login to NAS
scp file.txt pi:/home/pi/
rsync -avz project/ nas:/backups/
ssh pi "sudo apt update && sudo apt upgrade -y"

Advanced Traversal: The ProxyJump Pattern

As networks segment, direct access to every node becomes undesirable or impossible. A Jump Host serves as a trusted intermediary.

The Magic: Transparent Traversal

Instead of manually hopping between servers (SSH into bastion, then SSH into internal node), use the ProxyJump directive to automate this traversal:

# The Bastion (Exposed Entry Point)
Host bastion
    HostName lab.yourdomain.com  # or public IP
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
 
# Internal Nodes (Not Exposed)
Host internal-db
    HostName 192.168.1.50
    User dev
    ProxyJump bastion
 
Host internal-*
    ProxyJump bastion

Workflow:

ssh internal-db
# Client transparently:
# 1. Authenticates with bastion
# 2. Establishes secure tunnel
# 3. Forwards connection to internal-db

File Transfer Works Too:

scp project.zip internal-db:~/deployments/

Bastion/Jump Host Architecture

The Hardened Choke Point

Instead of forwarding ports for every machine (which creates a massive attack surface), expose exactly one device to the internet as a secure gateway. This architecture creates a “Hardened Choke Point” where:

  • Ingress: All external traffic hits the Jump Host first
  • Tunnel: Authorized traffic is proxied through to internal IPs
  • Result: Internal servers have no internet footprint

Bastion Hardening Requirements

The Jump Host must be bulletproof because it is your only shield.

Mandatory Security Posture:

  1. Zero-Password Authentication: PasswordAuthentication no is non-negotiable. Forces attackers to have your physical private key.
  2. No Root Access: PermitRootLogin no prevents direct targeting of administrative accounts.
  3. Rate Limiting: MaxAuthTries 3 kicks off bots after three failed attempts.
  4. Active Defense: Install Fail2Ban or CrowdSec to automatically ban IPs showing scanning/brute-forcing behavior.
  5. Minimal Services: Run only sshd and essential monitoring tools. Disable all unnecessary services.
  6. Regular Updates: Automate security updates on the bastion.

Additional Hardening:

# On bastion /etc/ssh/sshd_config
Port 2222                    # Non-standard port for noise reduction
MaxSessions 3                # Limit concurrent sessions
LoginGraceTime 30            # Reduce connection timeout window
PermitEmptyPasswords no
X11Forwarding no
AllowTcpForwarding yes       # Required for ProxyJump
GatewayPorts no

Bastion vs. Overlay Networks

Jump Host Pattern: Use when you require raw SSH access without relying on third-party coordination servers. This is the “Reliable Baseline.”

Overlay Networks (Tailscale/WireGuard): The “Modern Standard” for solopreneurs. Achieve the same zero-trust result without opening any ports on your router. See zero-trust-external-access for detailed comparison.

External Access Patterns

The Strategic Pivot: From Exposure to Encapsulation

The operational standard has shifted from “perimeter management” (opening ports 2222, 8080) to identity-based overlay networks. The objective is Zero Trust connectivity: reducing the internet-facing attack surface to near zero while maintaining seamless access.

The Access Hierarchy

Tier 1: Modern Standard - Overlay Networks (Tailscale/ZeroTier)

Recommended as the primary solution for solopreneurs due to near-zero friction and automatic NAT traversal.

How It Works:

  • Install small agent on lab machines and client devices
  • Creates mesh VPN with devices receiving private IPs (100.64.x.x range)
  • Automatic peer discovery behind NAT/CGNAT
  • “MagicDNS” allows ssh machine1 instead of remembering IP addresses

Why It’s Better:

  • No ports opened on router - lab is invisible to internet scanners
  • NAT traversal handled automatically - works behind restrictive firewalls
  • Identity-based access - authentication via SSO (Google, GitHub, etc.)
  • Uniform access - coffee shop or home office, access is identical

Tailscale Installation:

# Linux/RPi
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
 
# Windows: Download from tailscale.com

Operational Benefit: A laptop at a coffee shop connects to a server at home as if they were on the same switch, without requiring router configuration or dynamic DNS.

Tier 2: Reliable Baseline - VPN-First Access (WireGuard)

Instead of exposing multiple SSH ports, a single VPN server provides secure access to the entire LAN.

Why WireGuard:

  • Small codebase (easier to audit)
  • Superior performance vs. OpenVPN
  • Modern cryptography
  • Stateless design

Implementation:

  1. Install WireGuard on central machine (e.g., Raspberry Pi)
  2. Generate keys and configure peers
  3. Forward single UDP port on router (e.g., 51820)
  4. Connect via WireGuard app on client devices
  5. Access internal machines via private IPs

Security Advantage: Only one port open, traffic is end-to-end encrypted. No direct internet-facing SSH.

Tier 3: Hardened Choke Point - SSH Bastion

For those requiring direct SSH without overlay networks. See Bastion/Jump Host Architecture section above.

When Acceptable:

  • 1-2 machines
  • Non-critical workloads
  • You are disciplined with keys, updates, and logs

Verdict: Viable, but you’ll outgrow this fast as fleet scales.

Comparison of External Access Methods

MethodSecurity LevelEase of Setup (1-5)Best ForAttack Surface
Port ForwardingLow4Testing/quick fixesLinear with machines
WireGuard VPNHigh3Full network accessSingle UDP port
Tailscale/ZeroTierVery High5Solopreneurs/remote workZero (NAT traversal)
Cloudflare TunnelsVery High3Web-based GUIsZero (outbound only)
SSH BastionHigh3CLI puristsSingle TCP port

Application-Layer Access: Tunnels vs. Proxies

For web-based services (dashboards, wikis, UIs), giving direct network access is often overkill.

Cloudflare Tunnels:

  • Small daemon (cloudflared) establishes outbound connection to Cloudflare
  • Point domain (e.g., lab.yourdomain.com) to tunnel
  • Layer Cloudflare Access on top for SSO authentication (Google/GitHub login)
  • Critical: Traffic proxied through Cloudflare edge - home IP never exposed

Use Case: Web-based dashboards (Proxmox, Home Assistant, private wikis)

Limitation: Primarily for HTTP/HTTPS traffic. SSH over tunnels is complex.

Reverse Proxies (Nginx/Caddy):

  • Centralized entry point for multiple services
  • SSL termination with Let’s Encrypt
  • Authentication layers (Authelia/OAuth)
  • Route to internal services based on domain/path

Security: High with proper authentication + TLS certificates

Drawback: Typically requires open inbound port (443), creating single point of exposure

Dynamic DNS for Home Networks

Home ISPs typically assign dynamic IPs. Solutions:

  • No-IP - Free tier available
  • DuckDNS - Free, simple
  • Cloudflare - Free tier, automatic updates

Map a domain (e.g., myhomelab.ddns.net) to your changing public IP.

The “No Port Forward” Rule

Never expose Port 22 directly to the open internet. It will be hammered by bots within seconds. Automated scanners constantly probe common ports.

If You Must Expose SSH:

  1. Use non-standard port (noise reduction only)
  2. Enforce key-only authentication
  3. Deploy Fail2Ban/CrowdSec immediately
  4. Monitor logs actively
  5. Keep bastion patched religiously
  6. Consider this temporary until VPN/overlay is configured

Operational Workflows and Automation

Fleet Management Commands

# Basic connectivity
ssh pi                              # Instant login
ssh nas                             # Instant login
 
# File operations
scp file.txt pi:/home/pi/
rsync -avz localdir/ pi:/remote/dir/
 
# Remote execution (headless management)
ssh pi "sudo apt update && sudo apt upgrade -y"
ssh nas "docker ps"
 
# Multi-machine updates
for host in pi nas media-server; do
    ssh $host "sudo apt update && sudo apt upgrade -y"
done

Transport and Logistics

A hardened SSH layer becomes the backbone for internal logistics. Tools like scp and rsync inherit SSH config aliases, turning complex backup scripts into readable one-line commands:

# Backup to NAS using configured alias
rsync -avz --delete ~/projects/ nas:/backups/projects/
 
# Database dump transfer
ssh db-server "pg_dump mydb | gzip" > ~/backups/mydb-$(date +%Y%m%d).sql.gz

SSH Tunneling for Service Access

Secure non-encrypted services by tunneling them through SSH:

# Local port forwarding (access remote web service locally)
ssh -L 8080:localhost:80 pi
 
# Then access in browser: http://localhost:8080
 
# Dynamic port forwarding (SOCKS proxy)
ssh -D 1080 bastion
# Configure browser to use localhost:1080 as SOCKS5 proxy

Integrated Security Architecture

Tiered Access Model

A mature architecture applies the right tool to the right access pattern:

Admin/Root Access:

  • Strictly via Tailscale/WireGuard overlay
  • No public exposure
  • MFA required for high-value nodes

Web Services:

  • Via Cloudflare Tunnels or authenticated reverse proxy
  • SSL/TLS mandatory
  • OAuth/SSO authentication (Authelia, Keycloak)

Legacy/Break-Glass Access:

  • Single SSH Bastion with Fail2Ban
  • Key-only authentication
  • Kept as emergency fallback only

The Bootstrap Problem: Where Secrets Meet

Challenge: OpenBao/Vault-style secret managers need their own bootstrapping credentials secured.

Solution: Use Bitwarden (or similar) to secure the “Keys to the Kingdom” for infrastructure secrets:

  • Unseal Keys: Store OpenBao/Vault shamir shards in restricted Bitwarden collection
  • Root Tokens: Store emergency admin tokens with “Master Password Re-prompt” enabled
  • Recovery Codes: Backup MFA recovery codes

Separation of Concerns:

  • Bitwarden: Human-centric secrets (passwords, personal API keys, root credentials)
  • OpenBao/Vault: Machine-centric secrets (dynamic DB credentials, API keys for applications, short-lived tokens)

Unified Identity: Use same SSO provider (Keycloak/Authentik) for both:

  • Bitwarden uses OIDC for human login
  • OpenBao uses OIDC auth method for CLI (bao login -method=oidc)
  • Employee departure = disable in IdP = immediate loss of all access

Monitoring and Governance

Audit Logging:

  • Enable SSH logging on all nodes
  • Centralize logs (rsyslog, Loki, etc.)
  • Monitor for unusual access patterns
  • Track all secret access in OpenBao

Configuration Management:

  • Store SSH configs, hardening scripts, and access patterns in “Organization as Code” repository
  • Version control all configuration changes
  • Ensure lab is reproducible and self-healing

Regular Security Tasks:

  • Weekly OS updates on all nodes
  • Monthly SSH key rotation review
  • Quarterly access audit (revoke unused keys/accounts)
  • Annual architecture review

Implementation Checklist

Phase 1: Foundation

  • Assign DHCP reservations for all homelab nodes
  • Update all OSes fully
  • Install openssh-server on all Linux machines
  • Enable SSH service on all nodes

Phase 2: Cryptographic Hardening

  • Generate Ed25519 keys on primary client
  • Distribute public keys to all servers (ssh-copy-id)
  • Harden /etc/ssh/sshd_config on all servers
  • Set PasswordAuthentication no on all nodes
  • Set PermitRootLogin no on all nodes
  • Configure AllowUsers on critical nodes
  • Restart SSH daemon on all nodes

Phase 3: Operational Efficiency

  • Create ~/.ssh/config on primary client
  • Define host aliases for all machines
  • Set global defaults (ServerAliveInterval, etc.)
  • Test passwordless access to all nodes

Phase 4: External Access

  • Choose access pattern (Tailscale/WireGuard/Bastion)
  • Install and configure chosen solution
  • Test external access from outside network
  • Document access procedures

Phase 5: Defense in Depth

  • Install Fail2Ban on all internet-facing nodes
  • Configure Fail2Ban jail rules
  • Set up log monitoring
  • Configure automated security updates
  • Test MFA for high-value nodes (optional)

Phase 6: Validation

  • Verify no password auth works on any node
  • Confirm ProxyJump works correctly
  • Test file transfers via scp/rsync
  • Scan external IP from outside (nmap) to verify no unexpected ports
  • Document architecture for future reference

Key Evolution Patterns

From Chaos to Structure

Phase 1: Ad-hoc Access

  • Memorize IPs
  • Type full SSH commands
  • Use passwords
  • No consistent security posture

Phase 2: Config-Driven

  • DHCP reservations
  • SSH config aliases
  • Key-only authentication
  • Standardized hardening

Phase 3: Fleet Management

  • ProxyJump for internal machines
  • Centralized logging
  • Automated updates
  • Security monitoring

Phase 4: Zero-Trust Architecture

  • Overlay networks (Tailscale/WireGuard)
  • No exposed ports
  • Identity-based access
  • Service-specific access patterns

Strategic Growth Path

Now:

  • VPN-first or overlay network (Tailscale recommended)
  • No public SSH exposure
  • SSH keys only
  • One jump host (if needed)
  • Documented access patterns

Soon:

  • VLAN or network segmentation
  • Bastion as policy boundary
  • Service access via reverse proxy
  • SSH becomes exceptional, not default
  • Automated security monitoring

Later:

  • Certificate-based SSH
  • Identity-driven access (OIDC/SAML)
  • Metrics on access events
  • Full infrastructure-as-code
  • Secret rotation automation

Critical Security Reminders

Hard Rules (Violations Are Unrecoverable)

  • Never commit secrets, tokens, keys, or credentials to any repo
  • Never run destructive commands without explicit confirmation
  • Never bypass security workflows or disable CI checks
  • Never expose port 22 directly to internet without Fail2Ban + monitoring

Soft Rules (Violations Require Correction)

  • Do not use RSA keys (migrate to Ed25519)
  • Do not set static IPs on individual devices (use DHCP reservations)
  • Do not reuse passwords across systems
  • Do not disable SSH agent forwarding unless explicitly required
  • Do not install services on bastion beyond essential monitoring

Threat Model for Solopreneur Homelab

Realistic Threats:

  • Internet-wide SSH scanning and brute force
  • Credential reuse or key exfiltration
  • Misconfiguration drift over time
  • Lateral movement after one box is compromised
  • Forgetting your own setup 9 months later

Not Defending Against:

  • Nation-state actors
  • Advanced persistent threats (APTs)
  • Physical security breaches
  • Zero-day exploits (beyond patching)

Core Question: How many things am I willing to expose directly to the internet?

Answer: As few as possible. Ideally zero via overlay networks.

This document connects to broader infrastructure patterns documented in ssh-fleet-management for operational procedures and zero-trust-external-access for advanced overlay network implementations. For service-specific access patterns, see cloudflare-tunnels-setup and wireguard-vpn-architecture.

Source Files

This document synthesizes insights from the following research materials:

  1. Secure Homelab SSH Setup.txt
  2. Secure Homelab SSH Setup Guide.txt
  3. Secure Homelab SSH Operations.txt
  4. Architecting a Hardened SSH Bastion and Jump Host.txt
  5. Architectural Standards for Advanced SSH Protocol Hardening.txt
  6. The Architecture of Secure SSH Fleet Management.txt
  7. Secure External Access.txt
  8. Secure External Homelab Access Options.txt
  9. Secure Homelab External Access Options.txt
  10. Hardened Remote Access Strategies for the Solopreneur Homelab.txt
  11. The Zero Trust Blueprint for Secure External Access.txt
  12. Zero-Trust Security Architecture Blueprint.txt

All source files located in /Users/gordie/dev/ap/library/knowledge-vault/research-lab-materials/logs/notebook outputs/