Documentation

Pertisk Proxy Docs

Run the Pingora + HTTP/3 reverse proxy or Kubernetes Ingress controller.

Overview

Pertisk Proxy is a shared data plane built on Cloudflare Pingora (HTTP/1.1 + HTTP/2) and Quiche (HTTP/3). Two binaries, one stack:

Binary Mode Purpose
pertisk-proxy proxy Standalone reverse proxy — sites, TLS, and edge rules in SQLite (Admin UI)
pertisk-proxy-ingress ingress Kubernetes Ingress controller — watches Ingress / Gateway API resources

The Admin UI (proxy mode) is what the live demo shows: dashboard, sites, reverse tunnels, GeoIP access lists, WAF, Let’s Encrypt, DNS providers, logs, metrics, backup, and settings.

Live demo: admin.tools.pertisk.comadmin / admin

Screenshots

From the live demo. Recapture (Playwright):

KOS_USER=admin KOS_PASS=admin npm run capture:proxy

Files: public/images/projects/proxy/. Ingress-only pages are skipped when that mode is not in the sidebar.

Sign-in and overview

Proxy Admin sign-in
Login
Proxy Admin dashboard with HTTP/3 and host metrics
Dashboard — HTTP/3, sites, and host health

Routing

Sites list with domain, upstream, and SSL
Sites — domain, upstream, SSL
Add site modal with domain, upstream, and TLS options
Add site
Edit site modal
Edit site
Reverse tunnels from a local machine to this VPS
Tunnels

Security, TLS, and DNS

Access control lists
Access control
WAF policies
WAF
TLS certificates with Let's Encrypt
Certificates
DNS providers for ACME
DNS providers

Observe and system

Proxy request logs
Logs
Live H2/H3 and per-site totals
Metrics
Backup and restore
Backup
Proxy Admin settings
Settings

Admin UI

BrowserRouter app (path routes, not hash). Chrome on every signed-in page: grouped sidebar (collapse), Proxy mode / Ingress mode badge, + Create, theme toggle, user menu (Profile, Change password, Logout).

+ Create opens: Site, DNS provider, Import certificate, Access Control, WAF.

Page Path Shows / actions
Login /login Username, password, Remember password, Sign in, theme toggle
Dashboard / Version, uptime, sites/routes, H2/H3, host CPU/memory, ports, performance tuning, Prometheus
Sites /sites Domain, protocol, upstream, routes, SSL — Cards/List, Add site, Edit, Delete
Add / Edit site /sites?new=1 General: domain, upstream, TLS (None / Existing cert / Generate SSL), routes. Advanced: client IP, access list, WAF policy
Tunnels /tunnels Live pertisk-tunnel-server status; Refresh
Access Control /access-lists GeoIP allow/deny profiles — attach on a site’s Advanced tab
WAF /waf WAF / bot / captcha policies — attach on a site’s Advanced tab
Certificates /certificates Let’s Encrypt + uploaded certs; Import; expiry / next renew / sites
DNS Providers /dns-providers ACME DNS-01 solvers (e.g. Cloudflare)
Logs /logs HTTP vs System, host filter, auto-refresh 3s
Metrics /metrics Live H2/H3, connections, per-site totals, charts
Backup /backup Export JSON (download or S3), restore, merge
Settings /settings Tabs: General, Certificates, Notifications, Storage, Performance
Profile /profile Change password (proxy mode)

Ingress mode swaps Sites / Tunnels / DNS Providers for Ingress (/sites/ingress) and optional Gateway API pages. The demo is proxy mode.

Sites

Add a site from SitesAdd site, or + Create → Site.

Tab Field Detail
General Domain / upstream Hostname and default backend (http://localhost:8080 or https://… for TLS backends)
General SSL / TLS None (plain HTTP), Existing cert (reuse a Certificates row, including *.tools.pertisk.com), or Generate SSL (ACME HTTP-01 or DNS-01)
General Routes Prefix / Exact / ImplementationSpecific. Default upstream unless a route sets its own (e.g. /api → another port)
Advanced Client IP Forward X-Real-IP / X-Forwarded-For
Advanced Access Control Attach a GeoIP list from /access-lists
Advanced WAF Attach a WAF / bot / captcha policy from /waf
List column Shows
Domain Public hostname
Protocol HTTP or HTTPS
Upstream Default backend
Routes Path match → rewrite / override
SSL Online / Pending / Expired

Tunnels

Reverse tunnels from a laptop or homelab to the VPS. Public HTTPS stays on Sites.

  1. Run pertisk-tunnel-server on the VPS with a strong token. Open firewall UDP 7000 only.
  2. Run pertisk-tunnel-client on the local machine with the same token and matching tunnel names.
  3. Create a Site whose upstream is http://127.0.0.1:<remote_port> (or https://… so TLS bytes pass through).

Admin Tunnels polls http://127.0.0.1:7700/status (override PERTISK_TUNNEL_STATUS_URL). If the server is not running, the page shows that error — as on the demo.

Full guide: docs/tunnel.md.

Access Control and WAF

Create reusable profiles, then attach them per site (Advanced tab). Empty states in the demo: “Create a GeoIP allow/deny profile…” and “Create a WAF / bot / captcha profile…”.

Profile Page What it sets
Access list /access-lists GeoIP allow/deny countries and ASNs
WAF policy /waf Builtin or custom WAF, bot challenge/block scores, captcha

Edge order after route match: GeoIP → captcha endpoints → WAF → bot score. Challenge page: /.pertisk/captcha. Ingress uses the same chain via proxy.pertisk.tech/* annotations.

Certificates and DNS

Page Shows
Certificates Domain (often a wildcard), issuer (Let’s Encrypt or uploaded), challenge (HTTP-01 / DNS-01), expiry, next renew (~30 days before), sites using it
DNS Providers ACME DNS-01 solvers (Cloudflare and others the API advertises). Generate SSL with DNS-01 picks a provider from this list

Import certificate uploads PEM. Credentials are not in backups — re-add providers after restore. Default Let’s Encrypt contact email: Settings → Certificates.

Logs and metrics

Page Shows
Logs HTTP access (method, proto, host, path, upstream, status, duration) or System events. Host filter + auto-refresh 3s
Metrics Totals (requests, connections, bytes, upstream errors, GeoIP blocked), H2 vs H3, process CPU/RSS, protocol bars, per-site H2/H3. Live refresh

Prometheus scrape is linked from the dashboard (:9990/metrics by default).

Backup and settings

Backup exports site config, TLS metadata, and DNS provider names as JSON (proxy) or YAML (ingress). Download, or upload to S3 when Storage is configured. Restore can merge (keep existing hosts, add new ones). DNS provider secrets are omitted.

Settings (proxy mode)

Tab Contents
General Version, auth (default admin / admin in SQLite — change from Profile), env (PERTISK_DB_PATH, PERTISK_MANAGEMENT_ADDR)
Certificates Default ACME contact email
Notifications SMTP
Storage S3 for backups
Performance Effective runtime (Pingora workers, H3, BBR, file limits) — needs restart / Helm redeploy to change

Quick start — deploy

Linux one-liner: latest GitHub proxy package (DEB / RPM / tarball), then enable pertisk-proxy. Needs curl, systemd, and amd64 or arm64.

curl -sfL https://get.proxy.pertisk.com | sh -

Same script from GitHub (use this if the hostname cert is missing — a *.pertisk.com wildcard does not cover get.proxy.pertisk.com):

curl -sfL https://github.com/pertisktech/pertisk-proxy/releases/latest/download/get.sh | sh -
Env Effect
INSTALL_PERTISK_VERSION=0.1.87 Pin a release (with or without v)
INSTALL_PERTISK_TYPE=deb|rpm|tar Skip distro detection
INSTALL_PERTISK_SKIP_START=1 Install only; do not start systemd
INSTALL_PERTISK_SKIP_ENABLE=1 Start now, do not enable on boot

After install:

Admin UI:   http://127.0.0.1:9080   (login admin / admin — change this)
Config:     /etc/pertisk-proxy/pertisk-proxy.conf
Status:     sudo systemctl status pertisk-proxy
Logs:       sudo journalctl -u pertisk-proxy -f

Management listen defaults to 127.0.0.1:9080. Publish it behind this proxy or an SSH tunnel — do not expose :9080 on the public internet. Kubernetes Ingress is a separate Helm chart, not this installer.

Quick start — standalone (from source)

git clone https://github.com/pertisktech/pertisk-proxy.git
cd pertisk-proxy
cargo build --release --bin pertisk-proxy

export ROUTES_CONFIG=./config/examples/routes.yaml
export ENABLE_H3=false
cargo run --bin pertisk-proxy
# or: make run

Default management API listen: [::]:9080 (IPv4 + IPv6).

Quick start — Ingress

cargo build --release --bin pertisk-proxy-ingress --features ingress

export INGRESS_CLASS=pertisk
cargo run --bin pertisk-proxy-ingress --features ingress
# or: make run-ingress

Helm

make deploy-ingress VERSION=0.1.0
# or
make docker-ingress-multi VERSION=0.1.0
make deploy-ingress-helm VERSION=0.1.0

Modes

Standalone reverse proxy

Sites live in SQLite (PERTISK_DB_PATH, default /var/lib/pertisk-proxy/proxy.sqlite on packages). Optional one-time import from a routes file:

routes:
  - host: app.example.com
    path: /api
    path_type: prefix
    upstream: http://backend:8080

Then manage HTTPS, access lists, and WAF in Admin.

Kubernetes Ingress controller

Deploy with Helm. The controller watches Ingress (and optional Gateway API) objects and programs the same Pingora + HTTP/3 data plane. Admin Ingress writes proxy.pertisk.tech/* annotations.

Edge chain

After route match, filtering runs:

  1. GeoIP — access list allow/deny by country or ASN
  2. Captcha endpoints — challenge routes
  3. WAF — request filtering
  4. Bot score — challenge or block by score

Proxy: attach lists/policies on the site Advanced tab. Ingress: same fields as annotations (proxy.pertisk.tech/geoip-*, waf-*, bot-*, captcha-*). Challenge page: /.pertisk/captcha.

GeoIP databases

mkdir -p /var/lib/pertisk-proxy/geoip
# Country MMDB + ASN (MaxMind or ip2asn TSV)

Override with PERTISK_GEOIP_COUNTRY_DB / PERTISK_GEOIP_ASN_DB. Optional: PERTISK_CAPTCHA_SECRET for stable captcha cookies.

Config essentials

Variable Default Notes
ROUTES_CONFIG Optional one-time YAML import; sites live in SQLite
PERTISK_DB_PATH ./data/proxy.sqlite Proxy config DB (packages: /var/lib/pertisk-proxy/proxy.sqlite)
PERTISK_MANAGEMENT_ADDR 127.0.0.1:9080 Admin UI / management API
LISTEN_HTTP / LISTEN_HTTPS :80 / :443 Proxy listeners
ENABLE_H3 true HTTP/3
INGRESS_CLASS Ingress filter
AUTO_HTTPS false HTTP→HTTPS redirect

Health: /healthz, /readyz.

Full documentation

Deep dives live in the repo: