1. The problem I’m having:
Reverse proxy shows a blank page when using a geofilter but only from internal networks. Everything was working just peachy but noticed some connections from outside Canada so decided to add the geofilter to a few sites of mine. When I added it I tested it from a VPN outside of Canada and it worked (blank screen). When I connected just through my home network I also got a blank screen. I turned off wifi on my phone and tested and was able to get through to the page without any issue. Removing the geo filter allows me to connect again through the reverse proxy internally.
2. Error messages and/or full log output:
{"level":"info","ts":1749053752.07467,"logger":"http.log.access.log1","msg":"NOP","request":{"remote_ip":"192.168.222.3","remote_port":"45362","client_ip":"192.168.222.3","proto":"HTTP/2.0","method":"GET","host":"request.media.ellisd.ca
","uri":"/sw.js","headers":{"Accept-Language":["en-CA,en-GB;q=0.9,en-US;q=0.8,en;q=0.7"],"Priority":["u=4, i"],"Accept":["*/*"],"Service-Worker":["script"],"Sec-Fetch-Dest":["serviceworker"],"Sec-Fetch-Mode":["same-origin"],"Cookie":["R
EDACTED"],"Cache-Control":["max-age=0"],"Referer":["https://request.media.ellisd.ca/sw.js"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36"],"Accept-Encodin
g":["gzip, deflate, br, zstd"],"Sec-Fetch-Site":["same-origin"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"request.media.ellisd.ca"}},"bytes_read":0,"user_id":"","duration":0.000015728,"size":0
,"status":0,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"]}}
3. Caddy version:
v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=
4. How I installed and ran Caddy:
a. System environment:
docker compose on debian host
b. Command:
docker compose up -d
c. Service/unit/compose file:
---
services:
caddy:
image: serfriz/caddy-cloudflare-ddns-crowdsec-geoip:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
environment:
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CROWDSEC_API_KEY=${CROWDSEC_API_KEY}
- DOMAIN=${DOMAIN}
volumes:
- caddy-data:/data
- caddy-config:/config
- caddy-logs:/var/log/caddy
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy/GeoLite2-Country.mmdb:/etc/caddy/GeoLite2-Country.mmdb
networks:
crowdsec:
security_opt:
- no-new-privileges=true
crowdsec:
image: docker.io/crowdsecurity/crowdsec:latest
container_name: crowdsec
ports:
- "8080:8080"
environment:
- GID=1000
- COLLECTIONS=crowdsecurity/caddy crowdsecurity/http-cve crowdsecurity/whitelist-good-actors
- BOUNCER_KEY_CADDY=${CROWDSEC_API_KEY}
volumes:
- crowdsec-db:/var/lib/crowdsec/data/
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
- caddy-logs:/var/log/caddy:ro
networks:
crowdsec:
restart: unless-stopped
security_opt:
- no-new-privileges=true
volumes:
crowdsec-db:
caddy-logs:
caddy-data:
caddy-config:
networks:
crowdsec:
driver: bridge
d. My complete Caddy config:
{
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
dynamic_dns {
provider cloudflare {env.CLOUDFLARE_API_TOKEN}
domains {
{$DOMAIN}
}
dynamic_domains
versions ipv4
}
order crowdsec first
crowdsec {
api_url http://crowdsec:8080
api_key {env.CROWDSEC_API_KEY}
}
# log {
# output file /var/log/caddy/access.log
# }
}
(logging) {
log {
output file /var/log/caddy/{args[0]}.access.log
format json
}
}
(private_ranges) {
@denied not client_ip private_ranges
respond @denied "Private access only" 403
}
(geofilter) {
@mygeofilter {
maxmind_geolocation {
db_path "/etc/caddy/GeoLite2-Country.mmdb"
allow_countries CA
}
}
}
jelly.media.{$DOMAIN} {
import logging jelly
import geofilter
route {
crowdsec
@jelly host jelly.media.{$DOMAIN}
handle @jelly {
reverse_proxy @mygeofilter 172.16.2.7:8096
}
}
}