Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/klzgrad/naiveproxy/llms.txt

Use this file to discover all available pages before exploring further.

Caddy with the NaïveProxy fork of the forwardproxy plugin is the recommended way to run a NaïveProxy frontend server. It handles TLS certificates automatically via Let’s Encrypt, routes authenticated proxy traffic through the forward_proxy block, and serves a real website to unauthenticated visitors — making the server indistinguishable from a normal HTTPS site to passive observers and active probers alike.

Get the Caddy Binary

You need a caddy binary that includes the NaïveProxy fork of the forwardproxy plugin. The standard Caddy release does not include it — you must either build from source or download a pre-built release.
Install xcaddy, then build with the naive forwardproxy fork:
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
~/go/bin/xcaddy build --with github.com/caddyserver/forwardproxy=github.com/klzgrad/forwardproxy@naive
This produces a caddy binary in the current directory that bundles the patched plugin.
Download the latest pre-built release from the forwardproxy fork’s releases page:https://github.com/klzgrad/forwardproxy/releases/latestPick the binary matching your platform and architecture, then make it executable.

Write the Caddyfile

Create a Caddyfile with the following content, replacing example.com, me@example.com, user, and pass with your own values:
{
  order forward_proxy before file_server
  log {
    exclude http.log.error # Avoid logging user activity
  }
}
:443, example.com {
  tls me@example.com
  encode
  forward_proxy {
    basic_auth user pass
    hide_ip
    hide_via
    probe_resistance
  }
  file_server {
    root /var/www/html
  }
}
:443 must appear before example.com in the site address line. Swapping the order will cause the Caddyfile to behave incorrectly.

Key forward_proxy Directives

DirectivePurpose
basic_auth user passRequires HTTP Basic authentication before tunneling traffic. Only authenticated clients can use the proxy.
hide_ipStrips the client’s real IP address from forwarded requests so the destination server cannot see it.
hide_viaRemoves the Via header that would otherwise reveal that a proxy is in use.
probe_resistanceEnables active probe resistance. Unauthenticated requests receive the same response as a normal web server, preventing an adversary from confirming a proxy exists at this address.

Other Directives

  • order forward_proxy before file_server — Ensures the proxy handler runs first in the middleware chain so authenticated proxy requests are handled before falling through to the static file server.
  • log { exclude http.log.error } — Suppresses error-level HTTP logs globally to avoid recording user browsing activity on the server.
  • encode — Enables response compression (gzip/zstd) for regular web traffic served by file_server.
  • tls me@example.com — Tells Caddy to obtain and renew a TLS certificate automatically via Let’s Encrypt using the given email address. See the Caddyfile TLS docs for customizing certificate issuance (e.g. DNS challenges, custom CAs, or existing certificate files).
  • file_server { root /var/www/html } — Serves static files from the given directory for any request that is not authenticated proxy traffic, providing the masquerade website.
For more advanced configuration — such as custom TLS settings, structured logging, or programmatic management — consider using Caddy 2’s JSON config format instead of a Caddyfile.

Run Caddy

Grant Caddy permission to bind to privileged port 443 without running as root, then start it:
sudo setcap cap_net_bind_service=+ep ./caddy
./caddy start
caddy start runs the process in the background and detaches from the terminal. Caddy will automatically obtain TLS certificates on first startup and renew them before expiry.
To run Caddy as a persistent systemd service that starts on boot and restarts on failure, see Run as Daemon.

Next Steps

  • To run Caddy as a long-lived background service managed by systemd, follow the Run as Daemon guide.
  • If you prefer a more traditional proxy setup using HAProxy and tinyproxy instead of Caddy, see the HAProxy Setup guide.

Build docs developers (and LLMs) love