tldr: ready to use script, pay attention to the variables at the beginning.
Caddy can be configured via the API, so it's possible to temporary enable reverse proxy to your local machine (over the lovely Tailscale, of course).
First, you have to define the dumb handler using respond, better to pretent that there is no live upstream at all:
reverse.mydomain.io {
respond "no healthy upstream" 502
}
Restart caddy, check that the handler works, then find your handler in the Admin API:
# curl -SsL localhost:2019/config/apps/http/servers/srv0/routes/4 | jq
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "no healthy upstream",
"handler": "static_response",
"status_code": 502
}
]
}
]
}
],
"match": [
{
"host": [
"reverse.mydomain.io"
]
}
],
"terminal": true
}
Note the "routes/4" in the URL, go check /config/apps/http/servers/
or just bruteforce to find out the actual index of your config.
The /config/apps/http/servers/srv0/routes/4/handle/0
contains the configuration we need to replace.
Now create the JSON file with new configuration:
# cat reverse_proxy.json
{
"handler": "reverse_proxy",
"headers": {
"request": {
"set": {
"X-Real-Ip": [
"{http.request.remote.host}"
]
}
}
},
"upstreams": [
{
"dial": "my-tailscale-machine:8888"
}
]
}
And patch the server configuration with it:
curl -v -XPATCH \
localhost:2019/config/apps/http/servers/srv0/routes/4/handle/0/routes/0/handle/0 \
-d @reverse_proxy.json \
-H 'content-type: application/json'
Check that configuration is applied, check that the request to reverse.mydomain.io
reaches my-tailscale-machine
.
To disable proxying, patch the config again with a static configuration:
# cat disabled.json
{
"body": "no healthy upstream",
"handler": "static_response",
"status_code": 503
}