Reverse-proxy anything on your network
Since v0.14.0, a gateway host with the web server option can act
as an HTTP reverse proxy for its own network, the way nginxproxymanager does on
a home server: pick a hostname, point it at http://192.168.1.10:3000, and get
https://grafana.lab.example.com with a real certificate, an optional DedNets
sign-in, custom headers, a custom error page and request logs.
The service being proxied does not run DedNets at all. The gateway reaches it over the network it already sits in, so anything the gateway can open in a browser, you can publish.
What you need
Section titled “What you need”- A host with the gateway role and the web server option (Publish on your own gateway), online.
- A verified wildcard domain fronted by your web servers (front
global), for example
*.lab.example.com(Bring your own domain). Each proxy host takes a label under it.
Turn the reverse proxy on
Section titled “Turn the reverse proxy on”The reverse proxy is off by default on every host, because it lets the Console point that machine at any address on its own network. Turn it on per host:
- Console: open the host on the Hosts page and click Turn reverse proxy on. The pane shows a Proxy badge and a Proxy hosts table.
- CLI:
dednetsctl gateway proxy on alice/gw1 - MCP:
host_reverse_proxy_enable
Turning it off stops every proxy host on that machine at once. They stay recorded and come back when you turn it on again.
Add a proxy host
Section titled “Add a proxy host”On the host pane, Add proxy host opens the editor:
- Details: a name (it becomes the app name,
alice/gw1/grafana), the upstream (httporhttps, host, port, optional path prefix), one or more hostnames under your wildcard domains, and Require a DedNets sign-in to put it behind the DedNets login (you and the accounts you add as viewers can open it; everyone else is stopped at the gateway). - Headers: headers to set on every request to the upstream (a fixed
X-Real-IP, anAuthorizationfor a backend that needs one) and on every response.Host,X-DedNets-*,Strict-Transport-Security,Server,Viaand the connection-level headers are reserved. - Advanced: verify the upstream’s TLS certificate (off by default: home
devices are usually self-signed), send the upstream’s own host as the
Hostheader (for a backend that only answers its own name), and a custom HTML page shown when the upstream is down (502) or does not answer in time (504).
From the CLI:
dednetsctl export add -daemon alice/gw1 -name grafana \ -upstream http://192.168.1.10:3000 \ -request-header X-Real-IP=203.0.113.9 -response-header X-Frame-Options=DENY \ -error-page ./down.htmldednetsctl domain bind '*.lab.example.com' -label grafana -target alice/gw1/grafanaWith an AI agent: service_reverse_proxy_add, then domain_bind.
The table shows each proxy host’s hostnames, upstream, the certificate state
this host holds for each name (SSL), access, and a status: online when
the gateway can reach the upstream, upstream down when it cannot, not served when the host refuses it (see below), switch off while the reverse
proxy is off. An SSL error carries Let’s Encrypt’s explanation on hover
and is retried automatically, five minutes after the failure and then doubling
(since v0.14.2); see certificates on a gateway.
How it is served
Section titled “How it is served”The hostname is served by the gateway itself: TLS terminates on your machine, the request goes straight to the upstream on your network, and nothing leaves the host. A request that arrives through one of your other web servers, or through the DedNets edge for an edge-front name, reaches the upstream through this gateway over the mesh. It keeps working through a DedNets outage.
The upstream sees the visitor’s hostname as Host (unless you chose the
upstream’s), the usual X-Forwarded-For / X-Forwarded-Proto headers, and,
behind a DedNets sign-in, X-DedNets-User and X-DedNets-Email. Responses
lose Server and Via and gain HSTS, like every hostname your web servers
serve.
Confining what the Console can reach
Section titled “Confining what the Console can reach”An operator can cap the addresses a host will proxy to in the daemon’s config, whatever the account decides in the Console:
[gateway]enabled = trueweb = trueproxy_upstreams = ["192.168.1.0/24", "10.0.0.0/8"] # empty = any address(or DEDMESH_GATEWAY_PROXY_UPSTREAMS="192.168.1.0/24,10.0.0.0/8"). An IP
outside the list is refused when the proxy host is created, and shows as
not served with the reason; a DNS name is resolved on the host at connect
time and must resolve inside the list.
The default site
Section titled “The default site”A hostname that points at your gateway but is not bound to anything gets the
default site, one setting for your whole account (Settings, Default
site; dednetsctl gateway default-site; web_default_site_set):
- Refuse (the default): the TLS handshake fails and plain http redirects to https, as before.
- DedNets page, 404, Redirect to a URL of yours, or Custom HTML.
Anything but Refuse is served on https with a self-signed fallback certificate for the unknown name, so a browser shows a warning before the page. That is expected: no certificate authority issues for a name nobody bound. Plain http serves the default directly.
- A proxy host is an app: uptime monitors, health, viewers and request logs
work on it like on any other.
dednetsctl appsshows where it points and, when the host refuses to serve it, why; an AI agent sees the same inservice_listandservice_status, which also says when a proxy host is waiting for the switch to be turned on. - Change the upstream or the options later from the editor, with
dednetsctl export addagain (it replaces the proxy host), or withPATCH /api/v1/exportssending onlyupstreamorproxy. - Hosts running a version older than this feature ignore proxy hosts (the row stays pending until the host updates).
- A true wildcard proxy (
*.lab.example.com → one upstream) is not available; bind one label per proxy host.