Modular way of filtering remote ips for vhosts

Hi, newcomer here. Recently ive started testing caddy as potential replacement of nginx which ive been using for years. So far almost all things ive used in nginx do work in caddy as well, even mTLS (at least cert verification part which i was interested about the most)

1. The problem I’m having:

The only problem i still have is how to filter remote ips in modular manner. In Nginx each IP range i use is under separate name (file which i import) which allows me to reuse it over all vhosts and change it in one place (file) if i need to.

/allow-home

allow 192.168.5.0/24;

/allow-secure

allow 192.168.20.0/24;

vhost part

...
    include includes/allow-home;
    include includes/allow-secure;
    deny all;
...

I tried to replicate this in caddy.

    import imports/allow-home
    import imports/allow-secure

allow-home

@nonhome not remote_ip 192.168.5.0/24
respond @nonhome "Access Denied" 403

But offcorse this does not work because only the first rule is taken into consideration. Im looking for a way to either provide parameter for remote_ip dynamically (like remote_ip @allow-home @allow-secure etc.) or multiple matchers to respond part.

Ive also tried with vars but it seems i dont understand their concept yet

	vars {home_ips} 192.168.5.0/24 # in caddy_vars file
	vars {dmz_ips} 192.168.10.0/24

	@denied not remote_ip {home_ips} {dmz_ips}
	respond @denied "Access Deny" 403

I dont care if those are separate files or variables in some file as long as i can change single ip in one place (not multiple variables or files) for all hosts it occurs.

2. Error messages and/or full log output:

Well i tried many things, hard to provide one specific. Its more a concept problem, not functionality problem.

3. Caddy version:

2.7.6

4. How I installed and ran Caddy:

Docker compose

a. System environment:

Ubuntu 22.04, Docker version 24.0.7, build afdd53b

b. Command:

docker compose up -d

c. Service/unit/compose file:

version: "3.7"

services:
  caddy:
    container_name: caddy
    image: caddy:latest
    restart: "no"
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/imports:/etc/caddy/imports
      - $PWD/logs:/logs

  nginx:
    restart: "no"
    container_name: nginx
    hostname: nginx
    image: nginx:stable-alpine

d. My complete Caddy config:

Caddy proxies requests to nginx default page. Everyone can just copy and recreate this locally

ipmi.domanweb.lan:443 {
	tls internal
	log {
		output file /logs/ipmi.domanweb.lan.log
	}

	vars {home_ips} 192.168.5.0/24 # in caddy_vars file
	vars {dmz_ips} 192.168.10.0/24

	# SECOND attempt
	@denied not remote_ip {home_ips} {dmz_ips}
	respond @denied "Access Deny" 403
	reverse_proxy nginx:80

}

5. Links to relevant resources:

https://nginx.org/en/docs/http/ngx_http_access_module.html

Ive got the answer from u/MaxGhost in reddit

(home_ips) {
    remote_ip 192.168.5.0/24
}

(dmz_ips) {
    remote_ip 192.168.10.0/24
}

example.com {
    @denied not {
        import home_ips
        import dmz_ips
    }
    respond @denied "Access denied" 403

    respond "Welcome"
   reverse_proxy nginx:80
}

Problem solved

1 Like