Reusing IPs in trusted_proxies and remote_ip

1. The problem I’m having:

I have trusted_proxies defined in my Caddyfile:

{
        # Cloudflare
        servers {
                trusted_proxies static 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
        }
}

I would like to re-use this list to restrict by remote_ip, something like:

@blocked_ip not remote_ip LIST_OF_TRUSTED_PROXIES
abort @blocked_ip

I can’t seem to figure out a way to not define the list twice. I understand there is a caddy module to get cloudflare IPs, but I don’t really want to use that. I’m just wondering if there is a generic way to re-use a list of addresses. The only thing I can think of is defining an environment variable with the list.

2. Error messages and/or full log output:

No errors, just general question.

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

Docker

a. System environment:

Linux, docker.

b. Command:

c. Service/unit/compose file:

d. My complete Caddy config:

See above.

5. Links to relevant resources:

Also trying with an environment variable, I’m not sure how to define it. I get a CIDR parsing error if I define it like:

CLOUDFLARE_IPS="173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 1
97.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405
:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32"

In Caddyfile:

        servers {
                trusted_proxies static {$CLOUDFLARE_IPS}
        }

Error:

Error: loading http app module: provision http: loading trusted proxies modules: loading module 'static': provision http.ip_sources.static: parsing CIDR expression: '173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32': netip.ParsePrefix("173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32"): ParseAddr("173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::"): unexpected character (at "/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::")

Maybe needs to be defined differently?

Why not? That’s the best solution here.

There’s also GitHub - lanrat/caddy-dynamic-remoteip: http.matchers.dynamic_remote_ip matches requests by the remote IP address, the ip addresses to match against is provided my a module that implements IPRangeSource which can use the same IP source plugin as a request matcher.

Thanks, makes sense. I’ll go ahead and use those.

1 Like

Following up here because I wanted to double check the env var handling; the problem isn’t with Caddy, the problem is with how the env vars are defined.

I’m not sure what mechanism you used. If you’re using Docker, how are you setting the env vars?

If you use Docker Compose, you can use yaml syntax like this:

    environment:
      CLOUDFLARE_IPS: |-
        173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32

Using | says “preserve newlines” (not that you have any) and - means “drop the trailing newline”.

If you’re using a .env file, it depends on the implementation of the env parser whether it preserves or drops the " (it should drop them for it to work properly as a list of args for Caddy). I think you have to omit the ", I think the .env parsing will keep reading the value until it reaches a non-escaped newline, including spaces. If you use quotes, I think it’s included in the actual value.