Implementazione di un Reverse Proxy Caddy con Supporto GeoIP2 tramite Docker
In questa guida, illustrerò come configurare un reverse proxy Caddy con supporto GeoIP2 per limitare l’accesso a un sito web in base alla provenienza geografica o a specifici indirizzi IP, utilizzando Docker e Docker Compose.
1. Prerequisiti
Prima di procedere, assicurarsi di disporre dei seguenti strumenti installati sul sistema:
- Docker
- Docker Compose
Inoltre è necessario possedere un account MaxMind, al fine di scaricare le banche dati GeoIP2. È possibile utilizzare anche la versione gratuita GeoLite2.
2. Creazione dell’immagine Docker personalizzata
Caddy non include il plugin GeoIP2 nella distribuzione ufficiale e pertanto occorre creare una build personalizzata utilizzando xcaddy.
2.1 Dockerfile
Creare prima di tutto una directory di lavoro, es: /docker/Caddy
mkdir -p /docker/Caddy
e all'interno creare un file denominato Dockerfile con il seguente contenuto:
FROM caddy:builder AS builder
RUN xcaddy build \
--with github.com/zhangjiayin/caddy-geoip2
FROM caddy:2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
Si utilizza l’immagine caddy:builder per compilare Caddy con il plugin GeoIP2. L’eseguibile risultante viene copiato in una immagine finale caddy:2 più leggera.
3. Configurazione di Docker Compose
Creare il file docker-compose.yml nella medesima directory:
`
version: "3.9"
services:
caddy:
build: .
container_name: caddy
restart: unless-stopped
network_mode: host
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
- ./geoip:/geoip
environment:
- TZ=Europe/Rome
`
network_mode: host consente a Caddy di operare direttamente sulla rete del server. La directory ./geoip conterrà le banche dati GeoIP2.
4. Configurazione del Caddyfile
Creare il file Caddyfile con la seguente configurazione:
{
order geoip2_vars first
geoip2 {
accountId **<id_del_vostro_account>**
databaseDirectory /geoip
licenseKey **<la-tua-license-key>**
lockFile "/tmp/geoip2.lock"
editionID GeoLite2-ASN,GeoLite2-City,GeoLite2-Country
updateUrl "https://updates.maxmind.com"
updateFrequency 86400
}
}
**my.virtual.host** {
geoip2_vars strict
header geoip-country "{geoip2.country_code}"
header geoip-subdivision "{geoip2.subdivisions_1_iso_code}"
header geoip-city "{geoip2.city_name}"
@allowed expression ({geoip2.country_code} == "IT")
handle @allowed {
reverse_proxy **http://1.2.3.4:567** {
header_up Host {host}
header_up X-Real-IP {client_ip}
header_up X-Forwarded-For {client_ip}
header_up X-Forwarded-Proto {scheme}
}
}
tls {
curves x25519 secp256r1 secp384r1
protocols tls1.3
}
header Strict-Transport-Security "max-age=63072000"
handle {
respond "Access denied: utenti non autorizzati" 403
}
}
L'accountID e la licenseKey si creano dall'account Maxmind
Quindi abbiamo fatto:
- Aggiornamento automatico delle banche dati GeoIP2 ogni 24 ore.
- Inserimento di header contenenti informazioni geografiche del client.
- Accesso consentito esclusivamente agli utenti italiani.
- Blocco di tutti gli altri con un messaggio di accesso negato.
- Protezione TLS avanzata e HSTS.
5. Avvio dello stack
Per avviare il reverse proxy, eseguire:
docker compose up -d
Per monitorare i log:
docker compose logs -f
6. Aggiornamento manuale delle banche dati GeoIP2
Caddy aggiornerà automaticamente le banche dati secondo la frequenza configurata. È comunque possibile forzare un aggiornamento manuale con il comando:
docker exec -it caddy caddy geoip2 update