How to correctly reverse proxy to specific backend path

1. The problem I’m having:

Generally speaking i want to reach a service at 192.168.1.0/foo, i want to reverse proxy from host.example.com to 192.168.1.0/foo. is this possible? I can’t really understand what should be the correct way of doing this.
What i get is a blank page, however the request response is 200

2. Error messages and/or full log output:

There are no really error messages, this is the full log output.


Feb 05 13:19:53 caddy caddy[590]: {"level":"info","ts":1707139193.4483407,"logger":"tls.issuance.acme.acme_client","msg":"authorization finalized","identifier":"*.lab.bamje.io","
authz_status":"valid"}
Feb 05 13:19:53 caddy caddy[590]: {"level":"info","ts":1707139193.4483652,"logger":"tls.issuance.acme.acme_client","msg":"validations succeeded; finalizing order","order":"https:
//acme-v02.api.letsencrypt.org/acme/order/1554740627/242068392307"}
Feb 05 13:19:54 caddy caddy[590]: {"level":"info","ts":1707139194.2677555,"logger":"tls.issuance.acme.acme_client","msg":"successfully downloaded available certificate chains","c
ount":2,"first_url":"https://acme-v02.api.letsencrypt.org/acme/cert/03f1e06a4f97dc48eb838c9a70e33b00d8ff"}
Feb 05 13:19:54 caddy caddy[590]: {"level":"info","ts":1707139194.2683775,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"*.lab.bamje.io"}
Feb 05 13:19:54 caddy caddy[590]: {"level":"info","ts":1707139194.2684698,"logger":"tls.obtain","msg":"releasing lock","identifier":"*.lab.bamje.io"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9007921,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","rem
ote_ip":"127.0.0.1","remote_port":"37666","headers":{"Accept-Encoding":["gzip"],"Content-Length":["1080"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"
User-Agent":["Go-http-client/1.1"]}}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9016736,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origi
ns":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.901901,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection po
licies; adding one to enable TLS","server_name":"srv0","https_port":443}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9019227,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9020975,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9021125,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9021337,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2
","h3"]}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9021378,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["*.lab.bamje.io"]}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9021463,"logger":"http","msg":"servers shutting down with eternal grace period"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.902414,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9024215,"logger":"admin.api","msg":"load complete"}
Feb 05 13:22:05 caddy caddy[590]: {"level":"info","ts":1707139325.9036164,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7707922,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","rem
ote_ip":"127.0.0.1","remote_port":"40140","headers":{"Accept-Encoding":["gzip"],"Content-Length":["1087"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"
User-Agent":["Go-http-client/1.1"]}}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7713618,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origi
ns":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7715616,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection p
olicies; adding one to enable TLS","server_name":"srv0","https_port":443}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7715762,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7717326,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7717462,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7717683,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2
","h3"]}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7717726,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["*.lab.bamje.io"]}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.771781,"logger":"http","msg":"servers shutting down with eternal grace period"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7720406,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7720478,"logger":"admin.api","msg":"load complete"}
Feb 05 14:18:03 caddy caddy[590]: {"level":"info","ts":1707142683.7732,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}

3. Caddy version:

caddy version is 2.7.6

4. How I installed and ran Caddy:

installed manually, built with xcaddy and the cloudflare dns plugin.

a. System environment:

systemd service

d. My complete Caddy config:

*.lab.bamje.io {
        tls email
        tls {
                dns cloudflare secret-token
        }

        @zabbix host zabbix.lab.bamje.io

        handle @zabbix {
                reverse_proxy /zabbix 192.168.100.125:80
        }
}

Zabbix is served by apache at specific path, in this case /zabbix.

If i remove /zabbix from reverse_proxy /zabbix 192.168.100.125:80 i can reach the apache landing page correctly.

This is what i get when navigating to zabbix.lab.bamje.io

Thanks to anyone willing to help me.
Bamje

You could try:

    @zabbix host zabbix.lab.bamje.io

    handle @zabbix {
            redir / /zabbix/
            reverse_proxy 192.168.100.125:80
    }

So if you browse to zabbix.lab.bamje.io you will be once redirected to zabbix.lab.bamje.io/zabbix and that request will then be forwarded with that path (/zabbix) to your reverse proxy target. That’s how I would approach it.

Or maybe this, but this will most likely not work for subsequent requests, but I have no experience with zabbix

    @zabbix host zabbix.lab.bamje.io

    handle @zabbix {
            rewrite * /zabbix{path}
            reverse_proxy 192.168.100.125:80
    }

I would suggest the redirect (redir) approach, because manipulating paths sent upstream can cause problems.

Since the upstream app will be building paths for CSS/JS assets in the HTML text, using a rewrite means that those paths will be wrong when it reaches the browser, because it’s missing the path prefix.

Are you sure Zabbix doesn’t let you run it from the root of the domain? A quick google says that you should look go to “Administration” > “General” > “Other” > “Frontend URLs.” and you can probably change it to make / work.

Thank you both guys, unfortunately either the rewrite and the frontend url change did not worked.

I solved my problem switching from apache to nginix, and a simple reverse proxy just worked.

*.lab.bamje.io {
        tls email
        tls {
                dns cloudflare secret-token
        }

        @zabbix host zabbix.lab.bamje.io

        handle @zabbix {
                reverse_proxy 192.168.100.125:80
        }
}

Thanks again