PikaTunnel: Self-Hosted Reverse Proxy & Tunnel Manager featured image

PikaTunnel: Self-Hosted Reverse Proxy & Tunnel Manager

A playful pika-themed web UI that unifies reverse proxy, VPN tunnels, TLS certificates, and Kubernetes Ingress management, built to replace CCSO's legacy routing system.

Contributors: Aiden Johnson

Overview

PikaTunnel is a self-hosted reverse proxy and tunnel management platform that replaces the CCSO’s legacy routing system—built on a tangle of Helm charts and environment variables—with a clean, pika-themed web dashboard. Developed solo while serving as Tech Director in mid-April 2026, it lets club members and sister organizations at other Penn State campuses create publicly accessible, optionally authenticated routes in seconds rather than hours.

The tool consolidates the entire network edge: it manages HTTP routes, TCP/UDP streams, WireGuard and OpenVPN tunnels, TLS certificates through Let’s Encrypt, and Kubernetes Ingress syncs. Originally deployed to standardize how the CCSO proxies quick dashboards from cloud VMs, PikaTunnel now also powers every external route in my personal homelab—proof that a well‑designed abstraction solves real, recurring problems.

By moving route configuration from fragile env‑var stitching into a central database and GUI, PikaTunnel lowers the barrier for non‑experts, reduces configuration drift, and improves auditability. It has become the default way the club exposes internal services to the internet without opening additional ports on Penn State’s on‑premises network.

Key Features

  • One‑Click Route Creation: Members spawn auth‑optional public routes through the browser. A route can point to an HTTP service, a TCP backend, or a UDP stream—all defined in a single form.
  • Unified VPN Management: Handles WireGuard and OpenVPN peers from the same interface, supporting the club’s transition from Pritunl to defguard while keeping existing tunnel configurations live.
  • Automatic TLS: Integrates with Let’s Encrypt to provision and renew certificates for any domain managed by PikaTunnel, so every route is HTTPS‑enforced without manual intervention.
  • Kubernetes Ingress Sync: Pushes route definitions directly into Kubernetes Ingress resources, ensuring that the cluster’s load balancer always reflects the desired state.
  • Multi‑Tenant & Multi‑Purpose: Designed for CCSO’s multi‑member environment but flexible enough to run in a home lab; the same instance proxies dashboards, game servers, macOS BlueBubbles relays, and agent daemons behind a single nginx frontend.

Technologies & Implementation

The stack balances a snappy developer experience with production‑grade reliability:

Frontend: React 19 with TypeScript. A component library built around the playful pika motif keeps the interface approachable while surfacing complex routing rules. Client‑side state is kept minimal; configuration is always persisted server‑side.

Backend: Python FastAPI + SQLAlchemy, exposed over a REST API. FastAPI was chosen for its native async support (handling proxy health checks, certificate renewal callbacks) and automatic OpenAPI docs, which serve as the project’s living API reference. SQLAlchemy models map directly to a PostgreSQL database, selected to match the CCSO’s existing CloudNativePG operator and because relational integrity matters when mixing routes, certificates, and VPN peers.

Proxy Layer: nginx compiled with the stream_module. PikaTunnel generates and reloads nginx configuration atomically—HTTP, stream, and upstream blocks are written from templates, validated with nginx -t, then hot‑reloaded.

Infrastructure: The application runs in Docker containers orchestrated by Kubernetes (Rancher‑provisioned RKE2) in the CCSO cloud cluster and on a Proxmox‑based homelab. Both environments use the same Helm chart, with environment‑specific overrides for ingress domains and database credentials.

graph TD
  U["User / Club Member"] --> W["PikaTunnel Web UI (React)"]
  W --> A["FastAPI REST Server"]
  A --> D[("PostgreSQL")]
  A --> N["Nginx Config Generator"]
  N --> P["Nginx (HTTP + Stream)"]
  P --> S["Target Services (VMs, Kubernetes Pods, VPN Tunnels)"]
  A --> K["Kubernetes Ingress Controller"]
  K --> P
  A --> C["Certbot / Let's Encrypt"]

Route creation flow: the Web UI sends a request to the API, which validates and stores the rule in PostgreSQL, regenerates the appropriate nginx blocks, reloads nginx, and optionally syncs a Kubernetes Ingress—all in a single atomic transaction.

Challenges & Solutions

Safely replacing a running system. The previous setup relied on environment variables threaded through multiple OpenStack Helm images; any change risked breaking existing routes. I built PikaTunnel to coexist with the old system: I imported all legacy routes into the new database, ran the new proxy on separate ports in parallel, and then cut over DNS gradually. The API’s config‑generation layer includes a dry‑run mode that simulates nginx reloads and reports errors before touching production.

Abstracting VPN tunnels alongside Layer‑7 proxying. WireGuard and OpenVPN have fundamentally different configuration models compared to HTTP routes. Rather than treat them as second‑class citizens, I modeled every endpoint—HTTP, TCP, or VPN—as a polymorphic “Route” entity in the database. The nginx template engine selects the appropriate module (http, stream, or an upstream block for a tunnel gateway) based on the route type, so the GUI never exposes the low‑level wiring.

Results & Impact

  • Immediate club-wide adoption: Within a week of launch, every active CCSO developer was using PikaTunnel to expose internal dashboards, CI runners, and game servers for capture‑the‑flag events.
  • Reduced friction for partner clubs: The multi‑tenant model lets other Penn State cybersecurity clubs create routes on the same instance with their own auth rules, saving each group from maintaining separate infrastructure.
  • Home lab efficiency: The same binary manages all external routes on my personal Proxmox cluster—macOS BlueBubbles relay, Ubuntu Hermes agents, and Kubernetes services—without opening extra ports on my router.
  • Time savings: Creating a new authenticated route dropped from a multi‑hour ritual of editing Helm values, committing, and waiting for a deploy to roughly 60 seconds through the UI.
  • Ongoing roadmap: Planned enhancements include audit logging for route changes, OIDC integration for seamless member sign‑in, and a Terraform provider to manage routes as IaC.

{TODO: Add screenshot of the main pika-themed dashboard with route list}