A modular multi-tunnel orchestrator and manager for VPN connection pairs running inside isolated network namespaces (netns).
Hermit is a modular multi-tunnel orchestrator and manager for VPN connection pairs running inside isolated network namespaces (netns). It decouples configurations into reusable Inbound Profiles (e.g., SOCKS5/HTTP Proxy, Tailscale) and Outbound Profiles (e.g., WireGuard, Local), allowing you to easily pair, share configurations, and manage multiple tunnels side-by-side.
The application provides a real-time web dashboard to monitor bandwidth usage, manage connection states, create and share profiles, and configure global settings.
Important
This project requires elevated system privileges (privileged: true) and advanced networking tools such as nftables, iproute2, wireguard-tools, and tailscale. To avoid impacting your host machine's network configuration and to ensure a consistent development environment, it is highly recommended to develop and run this project completely within Docker.
- Multi-Tunnel Orchestration: Pair inbound (SOCKS5/HTTP Proxy, Tailscale) with outbound (WireGuard, Local) profiles to run multiple independent tunnels side-by-side.
- Isolated Network Namespaces: Run each connection pair in its own Linux network namespace (
netns) with dynamic source-policy routing to prevent routing conflicts. - Decoupled DNS Control Plane: A DNS filtering system with bloom filters, caching, dynamic blocklist loading (AdGuard, GoodbyeAds, adult content), and custom DNS routing rules (Block, Bypass, Redirect, Forward Proxy, Forward DNS).
- DNS Endpoints (DoH / VPN Nodes): Expose secure DNS-over-HTTPS (DoH) endpoints with auto-generated Apple Configuration Profiles (
.mobileconfig) or dedicated Tailscale DNS Nodes. - Tailscale DNS Override: Automatically registers local DNS Nodes as tailnet-wide nameservers.
- EDNS Client Subnet (ECS): Forward client subnet masks to public upstreams (e.g. Google DNS) to optimize CDN routing, with support for LAN privacy filtering and custom fallback IPs.
- VPN Providers Integration: Direct authentication with NordVPN (using Access Tokens) and Mullvad to fetch recommendations, network speed profiles, and public keys.
- Real-Time Web Dashboard: A Phoenix LiveView dashboard to monitor bandwidth, manage tunnel states, view query logs, and edit configurations on the fly.
Hermit creates VPN tunnels by combining an Inbound Profile with an Outbound Profile inside an isolated Linux network namespace. The architecture is split into two planes:
- Traffic Plane: Carries regular network data (HTTP, TCP/UDP) through the tunnel.
- DNS Control Plane: Handles name resolution, caching, and ad/tracker filtering independently from the tunnels.
flowchart TD
Client[Client / Host Application] -->|1. Request In| Inbound[Inbound Profile SOCKS5/HTTP or Tailscale]
subgraph NetNS [VPN Pair Namespace]
Inbound -->|2. Internal Forwarding| Outbound[Outbound Profile WireGuard / Local]
end
Outbound -->|3. Tunnel / Host Out| Internet[VPN / External Internet]
- Inbound Profiles define how traffic enters the namespace:
- SOCKS5/HTTP Proxy: Exposes SOCKS5 and HTTP proxy endpoints for clients to connect to.
- Tailscale: Joins the namespace to your Tailscale network (tailnet) as a node, allowing any tailnet device to route traffic through it.
- Outbound Profiles define how traffic exits the namespace:
- WireGuard: All outbound traffic is routed through a WireGuard tunnel.
- Local: Bypasses VPN tunnels and routes traffic directly through the host network interface (useful for testing, local proxies, or selective routing).
- VPN Pairs: The orchestrator combines one Inbound + one Outbound into a running instance, handling resource allocation and conflict prevention automatically.
The DNS plane is fully decoupled from VPN Pairs and Inbound Networks. Hermit supports DNS Endpoints and DNS Profiles to separate network connection endpoints from routing/filtering logic:
- DNS Profiles: Pre-configure multiple DNS Profiles, each with its own upstream DNS servers (UDP/DoH), custom routing rules (block/bypass/redirect), and toggleable blocklists.
- DNS Endpoints (DoH / VPN Nodes): Expose access points for your devices. You can create multiple Endpoints:
- DoH Only (Default / Lightweight): Runs entirely in-memory using the Phoenix HTTP/HTTPS web port, using 0% extra CPU/RAM. Provides a secure HTTPS DoH URL (
/dns-query/:token) and automatically generates signed Apple configuration profiles (.mobileconfig). - Tailscale Integration (Optional): Link your DNS Endpoint to any Tailscale Inbound Profile. When active, Hermit boots a dedicated DNS Node (
tailscaledinside a network namespacehermit_dns_endpoint_#{id}) on your tailnet, allowing client devices to resolve DNS over UDP/TCP 53.
- DoH Only (Default / Lightweight): Runs entirely in-memory using the Phoenix HTTP/HTTPS web port, using 0% extra CPU/RAM. Provides a secure HTTPS DoH URL (
- Automated Global DNS Configuration: When Tailscale DNS Override is enabled on a Tailscale Endpoint, Hermit registers the local DNS Node IP as the global nameserver for your entire tailnet. All devices on your tailnet will use this node automatically without manual client configuration.
flowchart TD
subgraph Clients [Client Devices]
AppleDev[iOS / macOS Device]
TailnetDev[Tailnet Device]
end
subgraph Endpoints [DNS Endpoints]
DoHEndpoint[DoH Endpoint /dns-query/:token]
TSEndpoint[Tailscale Endpoint Node IP]
end
subgraph Profile [Active DNS Profile]
Rules{Rules & Blocklists}
Upstream[Upstream DNS / DoH]
end
%% Queries to Endpoints
AppleDev -->|HTTPS Query| DoHEndpoint
TailnetDev -->|UDP/TCP Port 53| TSEndpoint
%% Endpoints routing to active profile
DoHEndpoint -->|Internal Forward| Rules
TSEndpoint -->|nftables Redirect| Rules
%% Profile Resolution
Rules -->|Allow & Cache Miss| Upstream
Rules -->|Block / Redirect / Cache Hit| Respond[DNS Response]
Upstream --> Respond
When a DNS query arrives, the server evaluates it through a fast path before reaching the network:
- Custom Rules: User-defined routing rules are matched first. Actions include:
- Block: Instantly block matching domains (NXDOMAIN).
- Bypass: Bypass ad/tracker blocklist filters.
- Redirect: Resolve domain to a specific target IP address (A record).
- Forward Proxy: Proxy the DNS query through the proxy tunnel of a selected VPN pair.
- Forward DNS: Forward the DNS query to a specific DNS Server (UDP/DoH), optionally routed through the SOCKS5/HTTP proxy of a selected VPN pair.
- Blocklists: Checked against built-in ad/tracker blocklists (AdGuard, GoodbyeAds, adult content). Matched domains are blocked instantly.
- Cache: Previously resolved queries are returned from cache.
If none of the above match (cache miss), the query is forwarded to configured upstream DNS servers (UDP or DoH).
In addition to Tailscale integration, Hermit includes a built-in DNS-over-HTTPS (DoH) server. This allows any device (even those not on your Tailnet) to use your secure, filtered DNS configurations.
- Secure DoH Endpoint: Each DNS Endpoint is assigned a unique token, exposing a secure DoH resolver endpoint at
https://<your-host>/dns-query/<doh_token>. - Apple Configuration Profiles (
.mobileconfig): Hermit can dynamically generate Apple configuration profiles for iOS and macOS. Users can download these profiles from the dashboard to configure system-wide secure DNS with zero manual setup. All profile descriptions match your custom Endpoint names.
Hermit supports EDNS Client Subnet (ECS, RFC 7871) to optimize CDN routing (e.g. YouTube, Netflix, Facebook) by forwarding the client's subnet mask (IPv4 /24 or IPv6 /48) to public upstream DNS servers.
- Smart Client Subnet Forwarding: For public client IPs (e.g. via DoH), Hermit forwards the subnet directly. For private client IPs (e.g. loopback, LAN, or Tailscale CGNAT
100.64.0.0/10), Hermit skips ECS injection automatically to protect client privacy. - ECS Fallback IP: You can configure a public IP address as the fallback. When a request originates from a private Tailscale IP, Hermit will inject the fallback IP subnet instead, ensuring you always resolve CDN traffic to your target country.
To simplify creating Outbound Profiles, Hermit provides a dedicated Providers page (/providers) that integrates with popular commercial VPN providers:
- NordVPN: Authenticate using a NordVPN Access Token to retrieve your private key, list recommended countries, and import recommended WireGuard server configurations.
- Mullvad: Fetch active Mullvad WireGuard servers with country/city metadata, network speeds, and public keys.
- Custom Imports: Easily upload or paste custom WireGuard configuration files to generate new Outbound Profiles in one click.
- Docker and Docker Compose
Note
There is no need to install Elixir, Erlang, or SQLite on your host machine as all runtime dependencies are packaged and configured automatically inside the container.
Hermit is packaged as an all-in-one, multi-arch Docker image supporting both x86_64 (amd64) and ARM64 (arm64) architectures (Intel, AMD, Apple Silicon, AWS Graviton, Oracle Cloud ARM, etc.).
We recommend using our automated installer. It automatically prepares ~/.hermit/storage, generates cryptographically strong SECRET_KEY_BASE and random Web Dashboard credentials, detects available ports to prevent conflicts, and provides zero-configuration setup:
curl -fsSL https://raw.githubusercontent.com/quaywin/hermit/main/install.sh | bashOnce installed, the installer outputs your access details:
- Web Dashboard:
http://localhost:3000(orhttp://<your-vps-ip>:3000) - Default Username:
admin - Password: Randomly generated and displayed in terminal summary (saved at
~/.hermit/env)
Hermit supports two frictionless upgrade methods without losing any tunnel configurations or database records:
- 1-Click Web Upgrade (Zero Terminal):
Navigate to Settings (
/settings) on the web dashboard. When a new release is available on GitHub, an update banner will appear. Simply click [Upgrade] — Hermit will pull the latest Docker image and restart the container seamlessly in ~10 seconds. - Terminal 1-Line Upgrade:
Re-run the installer script on your server at any time. It automatically recognizes your existing installation (
~/.hermit/env), preserves all data, and updates to the latest release:curl -fsSL https://raw.githubusercontent.com/quaywin/hermit/main/install.sh | bash # or simply: hermit update
The installer creates a global hermit shortcut command on your server for effortless day-to-day operations:
hermit status # View container status and port mappings
hermit logs # Follow live container logs
hermit restart # Restart Hermit container
hermit update # Pull latest image and upgrade
hermit env # View credentials and configurationIf you prefer to configure Docker Compose manually without the installer script:
# 1. Create config & storage directory
mkdir -p ~/.hermit/storage
# 2. Generate environment secrets
cat <<EOF > ~/.hermit/env
SECRET_KEY_BASE=$(openssl rand -base64 48 | tr -d '\n')
PHX_HOST=localhost
HERMIT_PORT=3000
HERMIT_BASIC_AUTH_USER=admin
HERMIT_BASIC_AUTH_PASS=$(openssl rand -hex 6)
EOF
# 3. Download docker-compose configuration
curl -fsSL https://raw.githubusercontent.com/quaywin/hermit/main/docker-compose.yml -o ~/.hermit/docker-compose.yml
# 4. Start Hermit
docker compose -f ~/.hermit/docker-compose.yml up -dMounts the source code directly with live code reloading and incremental compilation in < 0.5s:
docker compose -f docker-compose.dev.yml up -dHermit can be deployed seamlessly to Fly.io MicroVMs with persistent storage and 512MB Swap safety buffer ($0/month under free credit allowance). See the detailed Fly.io Deployment Guide for full setup instructions.
# Quick Launch on Fly.io
fly launch --no-deploy
fly volumes create hermit_data --size 1 --region sin
fly secrets set PHX_HOST="your-app.fly.dev" SECRET_KEY_BASE=$(openssl rand -base64 48)
fly scale memory 512
fly deployWhen running in standard Production Mode (network_mode: host):
| Port / Protocol | Service | Description |
|---|---|---|
3000/tcp |
Web Dashboard | Phoenix LiveView Web UI (Customizable via HERMIT_PORT in ~/.hermit/env). |
Dynamic UDP |
Tailscale Inbounds | Zero-configuration: Kernel automatically allocates free ephemeral ports for 100% Direct P2P. |
53/udp, tcp |
Standalone DNS | Port 53 DNS resolver (optional if using Hermit as LAN DNS server). |
Tip
Co-existing with Host Tailscale & Services:
In host mode, each VPN tunnel runs in an isolated Linux network namespace (netns). It will never conflict with your host's Tailscale daemon (41641/udp) or drop your SSH connection.
To use a custom web port, set HERMIT_PORT in ~/.hermit/env (e.g. HERMIT_PORT=8080) and restart with hermit restart.
Basic Authentication is enabled automatically by install.sh. You can adjust credentials anytime in ~/.hermit/env:
HERMIT_BASIC_AUTH_USER=admin
HERMIT_BASIC_AUTH_PASS=your_secure_passwordHermit implements high-performance network tuning for Tailscale:
- Namespace UDP GRO Offloading: Hermit automatically runs
ethtoolto enablerx-udp-gro-forwardingand disablerx-gro-liston all virtual interfaces inside the isolated network namespaces.
Host-level Optimization (Manual): Because Hermit runs in an isolated network namespace, it does not modify the host's physical network hardware directly. To get the maximum throughput:
- Ensure your host system runs Linux Kernel 6.2 or later.
- Manually enable UDP GRO on your host's primary physical network interface (this single-line command auto-detects the interface and works on all shells including Bash, Zsh, and Fish):
sudo sh -c 'ethtool -K $(ip -o route get 8.8.8.8 | cut -f 5 -d " ") rx-udp-gro-forwarding on rx-gro-list off'
Running real-world VPN pairs requires operating-system level root privileges to create network namespaces (netns), configure virtual network interfaces, and route traffic via nftables.
- The
privileged: truesetting indocker-compose.ymlgrants the container permissions to perform these system-level operations in an isolated manner. - Running inside Docker prevents impacting your host machine's network configuration, avoids dependency conflicts, and ensures an easy 1-line installation and upgrade experience.
We aim to continuously improve Hermit. Planned future enhancements include:
- Expanded VPN Provider Integration: Add support for more commercial VPN providers (such as Surfshark, ProtonVPN, and ExpressVPN) to fetch keys, server recommendations, and network speed profiles automatically.
- Alternative Inbound Mesh Networks: Integrate additional Tailscale-like overlay networks (e.g., ZeroTier, Netmaker, Headscale, or Nebula) as Inbound Profiles, allowing client devices on those networks to route traffic through your outbound tunnels.
If you are looking for other tools to manage VPNs or WireGuard tunnels, here is how Hermit compares to existing popular open-source alternatives:
| Project | Primary Focus | UI Type | WireGuard Management | Tailscale Integration | Network Namespace Isolation |
|---|---|---|---|---|---|
| Hermit | Multi-tunnel orchestrator | Web Dashboard | Yes | Yes | Yes (isolated netns) |
| wireproxy | Userspace WireGuard proxy | CLI / Config | Yes | No | No (userspace proxy) |
| Gluetun | Docker-focused VPN client | CLI / Config | Yes | No | No (uses Docker network links) |
The development of Hermit was shaped by a few core ideas and existing tools:
- Tailscale Exit Nodes + Mullvad VPN: The initial spark came from wanting a clean way to combine the ease of Tailscale’s mesh networking with the privacy of Mullvad VPN. The goal was to dynamically route traffic from Tailscale devices through isolated Mullvad WireGuard tunnels.
- Self-hosted DNS inside Tailnet: Instead of relying on external DNS services, the author set out to run a dedicated DNS Resolver node directly inside the Tailnet. The early Erlang/Elixir DNS implementation was built with reference to the
dns_erlangspecification and Kip Cole's dns library. - Evolution into a Control D Alternative: Once a basic DNS server was operational inside the Tailnet, we saw the potential of dynamic, multi-tenant DNS routing. Inspired by the architecture of commercial services like Control D, Hermit evolved to support multiple isolated DNS Endpoints (each with dedicated DoH tokens or Tailscale Node IPs) mapped to custom DNS Profiles (blocking, bypassing, or redirecting domains through specific VPN Pairs).
Hermit is built on top of and inspired by several amazing open-source projects:
- WireGuard - For the extremely fast, modern, and secure VPN protocol.
- Tailscale - For making private networking easy and secure.
- AdGuard Home & GoodbyeAds - For providing the blocklists that power our DNS control plane.
- dns - The Elixir DNS library that helped shape our query parser and packet builder.
- Elixir & Phoenix LiveView - For enabling a real-time system dashboard with minimal overhead.
