Reverse proxy to specific path

1. The problem I’m having:

I’m attempting to use Caddy docker container to access a DNS over HTTPS docker container via reverse_proxy but reverse_proxy does not allow specific path. Therefore I’ve attempted to use rewrite and route both to no avail.

2. Error messages and/or full log output:

Using reverse_proxy (see below Caddyfile), I get the below error:

2023-05-11T22:18:25.903890677Z {"level":"error","ts":1683843505.9037302,"logger":"http.log.error","msg":"dial tcp connect: connection refused","request":{"remote_ip":"","remote_port":"11342","proto":"HTTP/2.0","method":"GET","host":"","uri":"/getnsrecord?","headers":{"Cdn-Loop":["cloudflare"],"X-Forwarded-For":[""],"X-Forwarded-Proto":["https"],"User-Agent":["curl/7.81.0"],"Cf-Connecting-Ip":[""],"Cf-Ipcountry":["US"],"Accept-Encoding":["gzip"],"Cf-Ray":["7c5dcc378a872b63-LAX"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":""}},"duration":0.000406688,"status":502,"err_id":"ecfmh2pa1","err_trace":"reverseproxy.statusError (reverseproxy.go:1299)"}

Using rewrite, I get the below error:

2023-05-11T22:14:00.367304684Z {"level":"error","ts":1683843240.366963,"logger":"http.log.error","msg":"dial tcp connect: connection refused","request":{"remote_ip":"","remote_port":"15852","proto":"HTTP/2.0","method":"GET","host":"","uri":"/getnsrecord?","headers":{"Cf-Connecting-Ip":[""],"Cf-Ipcountry":["US"],"Cdn-Loop":["cloudflare"],"X-Forwarded-For":[""],"Cf-Ray":["7c5dc5bbfcc92b77-LAX"],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"User-Agent":["curl/7.81.0"],"Accept-Encoding":["gzip"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":""}},"duration":0.000367245,"status":502,"err_id":"z24k4gg5g","err_trace":"reverseproxy.statusError (reverseproxy.go:1299)"}

Using route, I get the below error:

2023-05-11T22:15:54.154310804Z {"level":"error","ts":1683843354.1540062,"logger":"http.log.error","msg":"dial unknown network","request":{"remote_ip":"","remote_port":"43808","proto":"HTTP/2.0","method":"GET","host":"","uri":"/getnsrecord?","headers":{"Cf-Ray":["7c5dc8831c1808f2-LAX"],"Cf-Connecting-Ip":[""],"X-Forwarded-For":[""],"X-Forwarded-Proto":["https"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"User-Agent":["curl/7.81.0"],"Accept":["*/*"],"Cf-Ipcountry":["US"],"Cdn-Loop":["cloudflare"],"Accept-Encoding":["gzip"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":""}},"duration":0.000172135,"status":502,"err_id":"74u4cy0xv","err_trace":"reverseproxy.statusError (reverseproxy.go:1299)"}

Using handle_path, I get the below error:

2023-05-11T22:24:57.375965596Z {"level":"error","ts":1683843897.375762,"logger":"http.log.error","msg":"dial unknown network","request":{"remote_ip":"","remote_port":"44032","proto":"HTTP/2.0","method":"GET","host":"","uri":"/getnsrecord?","headers":{"X-Forwarded-Proto":["https"],"User-Agent":["curl/7.81.0"],"Accept":["*/*"],"Cf-Ipcountry":["US"],"Cdn-Loop":["cloudflare"],"Accept-Encoding":["gzip"],"Cf-Connecting-Ip":[""],"X-Forwarded-For":[""],"Cf-Ray":["7c5dd5c63faf520e-LAX"],"Cf-Visitor":["{\"scheme\":\"https\"}"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":""}},"duration":0.000198686,"status":502,"err_id":"wku7aryza","err_trace":"reverseproxy.statusError (reverseproxy.go:1299)"}

3. Caddy version:


4. How I installed and ran Caddy:

Pulled from docker hub

a. System environment:

Ubuntu Linux/Docker

b. Command:

docker-compose -f ~/docker/docker_compose.yml up -d

c. Service/unit/compose file:

version: '3.7'
    external: true
    name: caddy
    driver: bridge

    container_name: caddy
    image: caddy:latest
    restart: unless-stopped
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - $APPDIR/Caddyfile:/etc/caddy/Caddyfile
      - $APPDIR/caddy_data:/data
      - $APPDIR/caddy_config:/config
    image: satishweb/doh-server
    container_name: doh
    restart: always
      DEBUG: "0"
      DOH_HTTP_PREFIX: "/getnsrecord"
      DOH_SERVER_LISTEN: ":8053"
      DOH_SERVER_VERBOSE: "true"

d. My complete Caddy config: {
#  route /getnsrecord {
#    reverse_proxy
#  }
#} {
#     reverse_proxy /getnsrecord
#} {
#  rewrite * /getnsrecord{uri}
#    reverse_proxy
#} {
    handle_path /getnsrecord {

5. Links to relevant resources:

Howdy @Duckwingduck,

Just to clarify the use cases for each of the options you’ve tried:

  • route (or handle) is ideal for limiting the scope of the reverse proxy, i.e. /getnsrecord → reverse proxy to /getnsrecord, other paths → nothing.
  • rewrite is the solution when you want to have the proxy open but the upstream requires a prefix, like: /foo → reverse proxy to /getnsrecord/foo.
  • handle_path is for when you want to accept request to /getnsrecord but the upstream does not expect this prefix, e.g. /getnsrecord/foo → reverse proxy to /foo upstream.

However, in all four of your error message outputs, we don’t see any configuration issues, but rather networking issues:

"logger":"http.log.error","msg":"dial tcp connect: connection refused"
"logger":"http.log.error","msg":"dial tcp connect: connection refused"
"logger":"http.log.error","msg":"dial unknown network"
"logger":"http.log.error","msg":"dial unknown network"

In the first two cases, the upstream server refused the connection (closed port?) and in the latter two cases we have unknown network (was your server moved to a different LAN subnet, and does it have a valid route to


Hmm, I see what you mean regarding the network errors, I don’t see anything glaringly wrong with the way the network is setup (I can ping the various containers from one another). But the networking issues aside, in order to accomplish what I’m looking to do, which is to use the GitHub - satishweb/docker-doh: DNS Over HTTP Container Image to resolve DNS lookups, which is the option to use? Route/rewrite/handle_path? Incidentally, the option to test if the DNS over HTTP container is working or not is to use the following command:

curl -w '\n' ''

Which means the URL would need to be able to handle the ? query. Thanks!

Sorry I missed this – this is because of a syntax error, i.e. the IP address is being parsed as the network portion of the dial address, which is invalid. The network should be something like tcp or udp or unix.

This was because of which is an invalid dial address. You can’t use a path in a dial address, it’s not a URL.

I don’t think I understand your goal with the rewrites/path stripping.

1 Like

I don’t think you need any URI manipulation at the proxy layer? I can’t see why the linked service would need it.

I see, so I should just do {

And in my browser go to which should work once I resolve my network issue?

Hi @francislavoie, as @Whitestrake mentioned below, maybe I’m just overcomplicating the issue and I should just reverse_proxy to the docker and write the complete URL path.

Yeah, the proxy passes through the request as-is, no need to rewrite unless you actually need to change the URL before it’s proxied.

Indeed as both of you correctly surmised, my error was somewhere else, the corrected Caddyfile config below for other who might need it in the future using GitHub - satishweb/docker-doh: DNS Over HTTP Container Image in conjunction with Caddy: {

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.