Filtering allowed hosts / IPs - Host header allows firewall bypass

1. Caddy version (caddy version):

v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

2. How I run Caddy:

a. System environment:

Ubuntu 20.04.2

b. Command:

paste command here

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=systemd-networkd-wait-online.service
Wants=network-online.target systemd-networkd-wait-online.service


[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
Environment="GANDI_API_TOKEN=xxxxx"
[Install]
WantedBy=multi-user.target

d. My complete Caddyfile or JSON config:

 *.external.hostname {
        bind external.hostname
        bind internal-site.external.hostname

        tls my@email.address {
                dns gandi {env.GANDI_API_TOKEN}
        }
        log {
                output file /var/log/caddy-test.log
        }

        @external host external.hostname
        handle @external {
                reverse_proxy localhost:8123
        }

        @internal host internal-site.external.hostname
        handle @internal {
                reverse_proxy internal.local:7777
        }
}

3. The problem I’m having:

external.hostname and internal.hostname are two different IPv6 addresses on the same machine. Only one is normally allowed through the firewall.

If I run curl from a machine on the Internet (a VPS that is not connected to my machine in any way)

curl -H "Host: internal-site.external.hostname" https://external.hostname I get the content of the internal site.

I get that there’s no request filtering or anything but this effectively allows a bypass of my firewall rules (only allow 443 on external.hostname)

Are there any plugins that I can use that will let me filter who’s allowed to send what Host header to Caddy?

4. Error messages and/or full log output:

5. What I already tried:

6. Links to relevant resources:

I tried this, with @not_local_ip not remote_ip 127.0.0.1/32, but it seems like there’s an issue there in that I can bypass this with an X-Forwarded-For header!

Confirming this is behaving correctly (can’t bypass a match with X-Forwarded-For) in v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

I’d also note that it wasn’t clear how to use the matcher/respond commands until I found that forum post - the documentation could use some more examples IMO.

Yep, this is a change mentioned in the release notes:

I’m glad you tried updating to the latest version. That’s typically the first step to try.

What’s missing from the examples in Request matchers (Caddyfile) — Caddy Documentation ? Could you be more specific?

1 Like

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