GHOSTPORT
OPEN SOURCE PRIVACY ROUTER DOCUMENTATION

Everything you need to build, configure, and sail with your own GhostPort privacy router. Your data never leaves your hands.

☠ VERSION 1.0 — MARCH 2026 ☠
INSTALLATION GUIDE
BUILD YOUR OWN GHOSTPORT ROUTER FROM SCRATCH
☠ REQUIRED HARDWARE
COMPONENT SPEC STATUS
Raspberry Pi 54GB or 8GB RAM recommendedREQUIRED
MicroSD Card32GB+ Class 10 / A2 ratedREQUIRED
USB-C Power Supply27W official Pi 5 adapterREQUIRED
USB Ethernet AdapterUSB 3.0 gigabit (second NIC)REQUIRED
PCIe Ethernet HATPi 5 compatible dual NICOPTIONAL
Case with coolingActive cooling recommendedOPTIONAL
☠ STEP BY STEP SETUP
1
FLASH RASPBERRY PI OS
Download Raspberry Pi Imager and flash Raspberry Pi OS Lite (64-bit) to your SD card. Enable SSH and set your hostname to ghostport in the advanced settings before flashing.
2
INITIAL SYSTEM UPDATE
Boot your Pi and run a full system update before installing anything.
TERMINAL
sudo apt update && sudo apt upgrade -y sudo apt install -y git curl wget nftables wireguard
3
INSTALL PI-HOLE
Pi-hole handles DNS filtering and ad blocking for all connected devices.
TERMINAL
curl -sSL https://install.pi-hole.net | bash
💡 During installation: select your WAN interface, enable the web admin, and choose Anonymous logging mode for maximum privacy.
4
CONFIGURE WIREGUARD
Set up WireGuard with your VPN provider or your own VPS. Place your config at /etc/wireguard/wg0.conf then enable it.
TERMINAL
sudo systemctl enable --now wg-quick@wg0 sudo wg show # verify connection
5
INSTALL GHOSTPORT
Install the GhostPort mode switcher and create your nft profiles directory.
TERMINAL
sudo mkdir -p /etc/gpmodes # Download and install gp-mode script sudo curl -sSL https://ghostport.io/install.sh | bash
⚠ Always verify the install script before running it. You can view the source at ghostport.io/install.sh
6
INSTALL NODE.JS & DASHBOARD
The GhostPort web dashboard runs on Node.js and serves on port 4200.
TERMINAL
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs sudo mkdir -p /opt/ghostport/public # Copy server and UI files to /opt/ghostport sudo systemctl enable --now ghostport
7
ACCESS YOUR DASHBOARD
Open any browser on your network and navigate to your Pi's IP on port 4200.
BROWSER
http://YOUR_PI_IP:4200
👻
OPERATING MODES
FOUR LEVELS OF PRIVACY — YOU CHOOSE YOUR PROTECTION
GhostPort gives you four distinct privacy modes you can switch between instantly from the web dashboard or command line. Each mode builds on the last, layering more protection.
ISP MODE
OPEN WATERS
Full passthrough. Traffic flows directly through your ISP with no filtering, no VPN, and no DNS interception. Use when you need maximum speed and compatibility.
PRIVACY LEVEL
👻
ZERO TRUST
GHOST CLOAK
All DNS is forced through Pi-hole. Ads, trackers, and malware domains are blocked network-wide. DNS over HTTPS and DNS over TLS are blocked so no device can bypass it.
PRIVACY LEVEL
💀
DOUBLE HOP
DEAD MAN'S ROUTE
All traffic is routed through WireGuard VPN. Your ISP sees only encrypted traffic. Your real IP is hidden and replaced with your VPN server's IP.
PRIVACY LEVEL
🏴‍☠️
Z-HOP
DAVY JONES
Maximum stealth. WireGuard VPN combined with strict DNS lockdown. No DNS leaks possible. The Pi itself cannot leak DNS outside the tunnel. Full ghost mode.
PRIVACY LEVEL
SWITCHING MODES VIA COMMAND LINE
TERMINAL
sudo gp-mode isp # Open passthrough sudo gp-mode zerotrust # Pi-hole + DNS lockdown sudo gp-mode doublehop # WireGuard VPN sudo gp-mode zhop # WireGuard + DNS lockdown sudo gp-mode status # View current state
💡 Modes can also be switched from the web dashboard at http://YOUR_PI_IP:4200 — no terminal needed.
🔧
TROUBLESHOOTING
COMMON ISSUES AND HOW TO FIX THEM
💡 If you ever get completely locked out, connect a keyboard and monitor directly to the Pi and run sudo gp-mode isp to reset to safe mode.
gp-mode command not found
The script didn't install correctly or lost executable permissions. Fix it:

ls -la /usr/local/bin/gp-mode sudo chmod +x /usr/local/bin/gp-mode which gp-mode
If the file is missing entirely, re-run the GhostPort installer.
wg0 is not UP; refusing to switch
WireGuard is not connected. This is a safety guard — GhostPort refuses to route your traffic through a dead tunnel. Check your WireGuard status:

sudo systemctl status wg-quick@wg0 sudo wg show
If there's no handshake, your WireGuard config or VPS may be the issue. Verify your /etc/wireguard/wg0.conf credentials and that your VPS is reachable.
DNS leak test still shows my ISP or Cloudflare
Your device is bypassing Pi-hole using DNS over HTTPS (DoH). Modern phones do this by default. Two fixes:

Option 1 — Turn off Private DNS on Android:
Settings → Network & Internet → Private DNS → Off

Option 2 — Let GhostPort block it automatically:
Make sure you're using Zero Trust, Double Hop, or Z-HOP mode — these modes include nft rules that block DoH/DoT at the router level so no device can bypass it.
Web dashboard shows "Cannot GET /"
The frontend HTML file is missing from the public folder. Fix it:

ls /opt/ghostport/public/ # If index.html is missing, copy it there sudo cp /path/to/index.html /opt/ghostport/public/ sudo systemctl restart ghostport
Switching modes disconnects my VNC/SSH session
This is normal and expected — mode switching flushes and reloads the nft ruleset. Your session should reconnect within a few seconds once the new rules apply. The management table in common.nft permanently protects ports 22 (SSH) and 5900 (VNC) at priority -100 so they always stay open regardless of mode.
Pi-hole web UI not loading
Check Pi-hole FTL is running and lighttpd is serving the web UI:

sudo systemctl status pihole-FTL sudo systemctl status lighttpd # Restart both if needed sudo systemctl restart pihole-FTL lighttpd
Access Pi-hole at http://YOUR_PI_IP/admin
Mobile data leaks my real IP even when connected to GhostPort WiFi
GhostPort can only protect traffic that flows through it. If your phone has mobile data active simultaneously, some apps may use the cellular connection instead of WiFi — bypassing the Pi entirely. Disable mobile data while connected to GhostPort for full protection. The GhostPort mobile app (coming soon) will handle this automatically.
API DOCUMENTATION
CONTROL GHOSTPORT PROGRAMMATICALLY
The GhostPort API runs on port 4200 of your Pi. All endpoints return JSON. No authentication is required on your local network — add your own reverse proxy with auth for remote access.
BASE URL
http://YOUR_PI_IP:4200
GET /api/status Returns live system status
Returns the current active mode, tunnel states, external IP, uptime, and Pi-hole ad block count.
RESPONSE
{ "ok": true, "activeMode": "zerotrust", "tunnels": { "wg0": "down", "tailscale": "down", "pihole": "up" }, "ip": "68.108.166.49", "uptime": "3h 42m", "adsBlocked": 1847 }
EXAMPLE
curl http://YOUR_PI_IP:4200/api/status
POST /api/mode Switch active mode
Switches GhostPort to the specified mode. Valid values: isp, zerotrust, doublehop, zhop
REQUEST BODY
{ "mode": "doublehop" }
RESPONSE
{ "ok": true, "mode": "doublehop", "message": "Mode: DoubleHop (LAN -> wg0)." }
EXAMPLE
curl -X POST http://YOUR_PI_IP:4200/api/mode \ -H "Content-Type: application/json" \ -d '{"mode":"doublehop"}'
POST /api/tailscale Toggle Tailscale on/off
Starts or stops the Tailscale daemon. Valid actions: start, stop
EXAMPLE
curl -X POST http://YOUR_PI_IP:4200/api/tailscale \ -H "Content-Type: application/json" \ -d '{"action":"start"}'
GET /api/wg WireGuard peer stats
Returns WireGuard peer information including last handshake time and bytes transferred.
RESPONSE
{ "ok": true, "peers": [{ "pubkey": "6km9PuJTdT0g...", "endpoint": "18.225.7.204:51820", "allowedIps": "0.0.0.0/0", "lastHandshake": "11:42:05 PM", "rx": "308.95 KiB", "tx": "242.14 KiB" }] }
GET /api/pihole Pi-hole statistics
Returns Pi-hole summary stats including domains blocked, queries today, and block percentage. Proxies the Pi-hole API response.
EXAMPLE
curl http://YOUR_PI_IP:4200/api/pihole