CLI Reference
CLI Commands
Full reference of commands and flags.
Global
Top-level commands and help.
Endpoints
Forward HTTP/TCP traffic, or expose a directory as a web file manager. On a TCP tunnel, add --proxy-protocol v1|v2 to hand the backend the real client IP.
Traffic policy
Attach edge rules (IP allow/deny, rate limit, header rewrites, force-HTTPS, compression) at connect time — from shorthand flags or a --traffic-policy file. Requires the traffic-policy entitlement. See Traffic Policy Rules → Configure from the agent CLI for the file format.
Endpoint auth
Put an endpoint behind a login at connect time: HTTP Basic auth (--basic-auth user:pass, repeatable, passwords ≥ 8 chars) and/or mutual TLS (--mutual-tls disabled|optional|required with --client-ca <file>; mTLS needs the mtls_attachment entitlement). See Security & Access → Endpoint authentication from the agent CLI.
HTTPS backend
Give the http command an https:// local address and the agent forwards over TLS, verifying the backend certificate — --upstream-ca <file> for a private CA, --upstream-client-cert/--upstream-client-key for mTLS, --upstream-server-name for the SNI, and --upstream-host to rewrite the Host header the backend sees. The local port is optional — it defaults from the scheme (https://→:443, http://→:80). See Connect to an HTTPS backend below.
Inspector
Tail, search, replay, and export the requests captured by a running tunnel, over its local loopback API. replay re-sends a captured request to the tunnel's own local backend.
Config & Diagnostics
Run bare ngris for a quick HTTP tunnel to localhost:80 — it accepts the same http flags and auto-loads config.yaml from the working directory if present; override any setting with the matching NGRIS_AGENT_* environment variable. ngris config check validates the resolved config (file + env) without connecting — a non-zero exit means it's invalid.
ngris --version
ngris --help
ngris auth --token xyz
ngris version
ngris http <addr> [flags]
ngris tcp <addr> [flags]
ngris webfm <path> [--rw] # Web File Manager (read-only by default)
ngris tcp 5432 --proxy-protocol v2 # preserve the real client IP (PROXY protocol; TCP only)
ngris http 3000 --cidr-allow 10.0.0.0/8 --rate-limit 100/1m
ngris http 3000 --force-https --response-header-add X-Frame-Options:DENY
ngris http 3000 --traffic-policy ./policy.yaml # YAML/JSON rule file
ngris http 3000 --basic-auth alice:s3cretpw # HTTP Basic (repeat for more users)
ngris http 3000 --mutual-tls required --client-ca ./client-ca.pem
ngris webfm ./site --rw --basic-auth admin:s3cretpw # protect a writable file server
ngris http https://localhost:8443 # verified TLS to the backend
ngris http https://example.com --upstream-host rewrite # public vhost/CDN (:443 default, sends Host: example.com)
ngris http https://localhost:8443 --upstream-ca ./ca.pem # private / self-signed CA
ngris http https://localhost:8443 \
--upstream-client-cert ./client.pem --upstream-client-key ./client.key # mTLS
ngris inspect --status 4xx,5xx [--search <str>] [--follow] [--json]
ngris replay --id <req_id> --set-header "X-Debug: 1"
ngris export --format json > requests.json
# Bare ngris = HTTP tunnel to localhost:80 (accepts the http flags),
# reading config.yaml from the working directory if present
ngris
ngris --basic-auth admin:s3cretpw --url myapp.ngris.io # bare + http flags
# Validate config (file + env) without connecting — non-zero exit if invalid
ngris config check
ngris config check --config ./config.yaml --json
# Override server address via environment variable
NGRIS_AGENT_SERVER_ADDRESS=eu.ngris.com:443 ngris
Connect to an HTTPS backend
By default the agent forwards to your local service over plain TCP. When that service already speaks TLS — an HTTPS dev server, an internal API, or a backend that demands a client certificate — give the http command an https:// address and the agent connects to it over TLS, verifying the backend certificate. Only the connection between the agent and your backend changes; the public endpoint and its certificate are untouched. Every flag below also works in the config file and via the matching AGENT_LOCAL_SERVICE_* environment variable.
The scheme is the switch
The local address decides the transport. ngris http https://localhost:8443 dials the backend over TLS; an http:// address or a bare host:port stays plaintext and byte-for-byte unchanged. Over TLS the backend certificate is verified against your system trust pool by default, using TLS 1.2 or newer.
Verify a private or self-signed certificate
Point --upstream-ca ./ca.pem at the PEM-encoded CA that signed the backend certificate and the agent trusts that CA instead of the system pool — this is what a self-signed dev backend needs. If nothing verifies the certificate the TLS handshake fails and the request is refused; that is verification working, not a misconfiguration.
local_service_insecure_tls: true in the config file or AGENT_LOCAL_SERVICE_INSECURE_TLS=true in the environment. There is deliberately no command-line flag for it — it turns off all certificate checking for the backend connection and must never be used outside local testing.Present a client certificate (mTLS)
When the backend requires mutual TLS, hand the agent a client certificate with --upstream-client-cert ./client.pem and its key with --upstream-client-key ./client.key. The two are a pair: setting one without the other is a startup error, so the agent stops with a clear message rather than connecting without the certificate it was told to present.
Override the SNI / certificate hostname
--upstream-server-name backend.internal sets both the SNI sent during the handshake and the name the backend certificate is checked against. It defaults to the host portion of the local address, so reach for it only when the certificate names something other than what you dial — for instance when you connect to an IP address but the certificate was issued for an internal hostname.
Rewrite the Host header sent to the backend
By default the agent forwards the incoming request's Host header to the backend unchanged — that is your public Ngris endpoint hostname. A backend that routes on Host, such as a shared virtual host or a public CDN, needs its own name instead. --upstream-host rewrite sends the backend's own host (the host portion of the local address), and --upstream-host backend.example.com sends any literal value you name. Left unset it stays passthrough, so the default forwarding path is byte-for-byte unchanged.
Backends on another host
The backend does not have to be on localhost: the agent reaches any host it can route to, so ngris http https://internal-api.corp:8443 forwards your public endpoint straight to an internal service. Two conveniences make remote and vhost backends easy:
- The port is optional. A schemed address defaults its port from the scheme —
https://dials:443andhttp://dials:80— songris http https://internal-api.corpconnects to:443with nothing more to type. Add an explicit:port(for example:8443) whenever the backend listens elsewhere; an explicit port is always honored. - The forwarded
Hostis yours to set. By default the agent passes the incoming request'sHostheader through unchanged — your public Ngris endpoint hostname — while the TLS SNI follows the upstream host. A plain backend ignoresHost; one that routes on it (a shared virtual host or a public CDN) needs the name it expects. Reach for--upstream-host(above):ngris http https://example.com --upstream-host rewriteforwards to a public vhost and the backend receivesHost: example.com.
ngris to change them. The plaintext http:// and bare host:port paths are unaffected.# Verified against the system trust pool (TLS 1.2+)
ngris http https://localhost:8443
# Verify a private / self-signed backend cert
ngris http https://localhost:8443 --upstream-ca ./ca.pem
# Mutual TLS — present a client cert (both flags required together)
ngris http https://localhost:8443 \
--upstream-client-cert ./client.pem \
--upstream-client-key ./client.key
# Override the SNI / cert hostname (default: host of the address)
ngris http https://10.0.0.5:8443 --upstream-server-name backend.internal
# Rewrite the Host header for a vhost / CDN backend (port defaults to :443)
ngris http https://example.com --upstream-host rewrite
# A backend on another host (port defaults from the scheme; :8443 here is explicit)
ngris http https://internal-api.corp:8443 --upstream-ca ./corp-ca.pem
# Dev only: skip verification (config / env — there is no CLI flag)
AGENT_LOCAL_SERVICE_INSECURE_TLS=true ngris http https://localhost:8443
Troubleshooting
Port already in use
Change the local port or stop the conflicting process.
Firewall/Corporate proxy
Allow outbound QUIC/HTTPS to Ngris regions or switch transport.
Webhook provider rejects IP
Use a Static Egress IP add-on and whitelist it with your provider.
Docker/K8s: Endpoint fails to connect
Ensure the agent can reach your service by name and port.
# macOS/Linux
lsof -i :3000
kill -9 <pid>
# Windows
netstat -ano | findstr :3000
taskkill /PID <pid> /F
# Use HTTP/2 for local connection (gRPC, etc.)
ngris http 3000 --http2
# Use HTTP/3 QUIC (experimental)
ngris http 3000 --http3
# Test connectivity from within container
docker exec -it tunnel-container ping app
kubectl exec -it ngris-pod -- wget -qO- http://web-service:8080/health
FAQ
Is traffic encrypted?
Yes, end-to-end encryption is enforced. The connection between your agent and our edge servers uses mutual TLS. Public endpoints serve HTTPS with auto-renewed certificates via ACME. Data in transit is always protected.
Can I self-host the Ngris server?
Yes, our Unlimited plan and enterprise agreements offer dedicated on-premise or private cloud deployments. This includes full relay infrastructure, database, and management dashboard. Contact sales for architecture details, SLAs, and pricing.
What happens when my endpoint disconnects?
If the agent disconnects, the public endpoint returns a 502 Bad Gateway error. Upon reconnection, the connection resumes automatically if using persistent credentials. For critical services, implement health checks and alerts via the API.
How long are request logs retained?
Free tier retains logs for 3 days. Pro plans retain for 15 days. Unlimited plans offer 30 days with export capabilities. PAYG plans retain for 7 days. See pricing page for full plan details.