Refactor: Migrate from Nginx/ModSec to Caddy Proxy
This commit is contained in:
parent
5a73c9a116
commit
f1445a7609
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
# Global Options
|
||||
email admin@oestepan.com.br
|
||||
# Enable Admin API for the watcher to trigger reloads
|
||||
admin :2019
|
||||
}
|
||||
|
||||
# Import dynamic sites
|
||||
import sites/*
|
||||
|
||||
# Default Site: Traccar GPS
|
||||
gps.oestepan.com.br {
|
||||
# Reverse Proxy to the backend service
|
||||
reverse_proxy host.docker.internal:8083 {
|
||||
# Trust original IPs
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
}
|
||||
|
||||
# Enable logging
|
||||
log {
|
||||
output file /var/log/caddy/gps.access.log
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Relatório de Diagnóstico e Pontos de Dor (Pain Points)
|
||||
|
||||
Este documento sumariza os problemas arquiteturais e técnicos identificados durante a tentativa de estabilizar o stack `nginx-pathfinder-proxy`. O objetivo é fornecer um contexto claro para um futuro Agente de IA simplificar a solução.
|
||||
|
||||
## 1. Arquitetura Excessivamente Complexa (Split Container)
|
||||
Atualmente, temos dois containers NGINX separados:
|
||||
1. **Frontend (`modsecurity`)**: Recebe a internet, faz WAF, termina SSL.
|
||||
2. **Backend (`nginx-proxy`)**: Recebe do WAF, faz roteamento, gerencia certificados (Certbot), roda scripts.
|
||||
|
||||
**Problemas Causados:**
|
||||
- **Inferno de Permissões (Permission Hell):** O Backend (onde roda o Certbot) gera certificados no volume compartilhado como `root`. O Frontend tenta ler esses arquivos e falha com `Permission denied` porque roda com outro UID/GID. Tentar corrigir com `chmod` é frágil e inseguro.
|
||||
- **Configuração Duplicada:** É preciso configurar o Nginx duas vezes. Uma no Frontend (para saber onde estão os certs) e uma no Backend (para saber como tratar a requisição na porta 8080).
|
||||
- **SSL "Ping-Pong":** O Backend gerencia a renovação, mas o Frontend é quem *usa* o certificado. Isso exige reload sincronizado em dois containers diferentes.
|
||||
|
||||
## 2. Problema do "Ovo e a Galinha" (SSL Bootstrap)
|
||||
- O NGINX **não sobe** se o arquivo de certificado não existir.
|
||||
- O Certbot **não gera** o certificado se o NGINX não estiver rodando (para responder o desafio HTTP-01).
|
||||
- **Solução Atual (Gambiarra):** Criamos um script complexo (`pre-flight.sh` + `renew_ssl.sh`) que gera certificados falsos (self-signed) só para o NGINX subir, e depois tenta baixar os reais. Isso adiciona muita lógica propensa a falhas.
|
||||
|
||||
## 3. Fragilidade de Deploy (Portainer / Docker)
|
||||
- **Mount Error:** O Portainer falha ao tentar montar arquivos de configuração (`modsec_conf/...`) que ainda não foram baixados pelo git no host.
|
||||
- **Solução Atual:** Tivemos que "assar" (bake) as configurações dentro da imagem Docker (`COPY conf.d ...`). Isso tira a agilidade de alterar uma config no git e dar deploy rápido; agora exige rebuild da imagem.
|
||||
|
||||
## 4. Scripts de Automação Frágeis
|
||||
- O script `pre-flight.sh` tenta fazer `git clone/pull` dentro do container. Isso gera erros de "Resource busy" quando tenta limpar pastas montadas via volume.
|
||||
- Lógica de `sed/grep` para ler arquivos `.conf` e achar domínios é suscetível a erros de sintaxe no arquivo de config.
|
||||
|
||||
---
|
||||
|
||||
# Recomendação de Simplificação (Para o Próximo Agente)
|
||||
|
||||
### Opção A: Single "Super" Container (Recomendada)
|
||||
Unificar tudo em um único container.
|
||||
- **Base:** Usar a imagem oficial com ModSecurity já compilado (ou compilar num multi-stage build).
|
||||
- **Benefício:** Resolve problemas de permissão (mesmo processo lê e escreve). Resolve problema de setup (um único serviço). Remove complexidade de rede (sem proxy pass interno desnecessário).
|
||||
|
||||
### Opção B: Caddy Server (Radical)
|
||||
Substituir NGINX + Certbot por **Caddy**.
|
||||
- **Benefício:** Caddy tem HTTPS automático (resolve o problema do Ovo/Galinha nativamente).
|
||||
- **WAF:** Existe plugin de WAF para Caddy (Coraza), mas exige validação se atende os requisitos de segurança do Oestepan.
|
||||
|
||||
### Opção C: NGINX Proxy Manager (GUI)
|
||||
Usar uma solução pronta como NGINX Proxy Manager.
|
||||
- Tem interface web.
|
||||
- Gerencia SSL sozinho.
|
||||
- Pode ser difícil integrar ModSecurity customizado.
|
||||
|
||||
### Resumo do Pedido de Refatoração
|
||||
> "Simplificar a infraestrutura eliminando a separação Frontend/Backend. Criar um container único que faça WAF + Proxy + SSL Management, eliminando scripts complexos de bootstrap e problemas de permissão de volume."
|
||||
23
deploy.sh
23
deploy.sh
|
|
@ -1,22 +1,15 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Detecting Public IP..."
|
||||
CURRENT_IP=$(curl -s https://ifconfig.me)
|
||||
echo "Deploying Caddy Proxy..."
|
||||
|
||||
if [ -z "$CURRENT_IP" ]; then
|
||||
echo "Error: Could not detect Public IP."
|
||||
exit 1
|
||||
fi
|
||||
# Pull latest code
|
||||
git pull
|
||||
|
||||
echo "Public IP detected: $CURRENT_IP"
|
||||
echo "HOST_PUBLIC_IP=$CURRENT_IP" > .env
|
||||
|
||||
echo "Building and testing..."
|
||||
docker compose build
|
||||
docker compose run --rm nginx-proxy nginx -t
|
||||
|
||||
echo "Deploying..."
|
||||
# Ensure containers are up
|
||||
docker compose up -d
|
||||
|
||||
echo "Done! Proxy is running."
|
||||
# Force a reload just in case
|
||||
docker compose exec caddy caddy reload
|
||||
|
||||
echo "Deployment Complete."
|
||||
|
|
|
|||
|
|
@ -1,94 +1,21 @@
|
|||
services:
|
||||
# ============================================
|
||||
# ModSecurity WAF (Frente do NGINX)
|
||||
# ============================================
|
||||
modsecurity:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.modsec
|
||||
container_name: modsecurity-waf
|
||||
caddy:
|
||||
image: caddy:latest
|
||||
container_name: proxy_caddy
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
environment:
|
||||
# - BACKEND=http://nginx-proxy:8080 # Replaced by static config mount
|
||||
- PARANOIA=1
|
||||
- ANOMALY_INBOUND=5
|
||||
- ANOMALY_OUTBOUND=4
|
||||
volumes:
|
||||
- ssl_data:/etc/nginx/ssl:ro
|
||||
- modsec_logs:/var/log/modsecurity
|
||||
depends_on:
|
||||
- nginx-proxy
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- ./sites:/etc/caddy/sites
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
- caddy_logs:/var/log/caddy
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
- "srvproxy001.itguys.com.br:172.16.254.1"
|
||||
- "srvproxy001:172.16.254.1"
|
||||
|
||||
- "zammad.itguys.com.br:172.16.254.59"
|
||||
- "zammad:172.16.254.59"
|
||||
- "cloud.grupopralog.com.br:172.16.253.12"
|
||||
- "business.itguys.com.br:172.16.121.13"
|
||||
- "verbocloud.itguys.com.br:172.16.253.13"
|
||||
- "srvoffice001.itguys.com.br:172.16.253.101"
|
||||
- "srvoffice001:172.16.253.101"
|
||||
|
||||
# ============================================
|
||||
# NGINX Proxy (Backend do ModSecurity)
|
||||
# ============================================
|
||||
nginx-proxy:
|
||||
build: .
|
||||
container_name: nginx-proxy
|
||||
restart: always
|
||||
expose:
|
||||
- "8080"
|
||||
environment:
|
||||
- HOST_PUBLIC_IP=${HOST_PUBLIC_IP}
|
||||
volumes:
|
||||
- ssl_data:/etc/nginx/ssl
|
||||
- nginx_cache:/var/cache/nginx
|
||||
- nginx_logs:/var/log/nginx
|
||||
- certbot_data_conf:/etc/letsencrypt
|
||||
- certbot_data_www:/var/www/certbot
|
||||
- repo_data:/opt/repo
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
- "server-254:10.10.253.254"
|
||||
|
||||
- "srvproxy001.itguys.com.br:172.16.254.1"
|
||||
- "srvproxy001:172.16.254.1"
|
||||
|
||||
- "zammad.itguys.com.br:172.16.254.59"
|
||||
- "zammad:172.16.254.59"
|
||||
- "cloud.grupopralog.com.br:172.16.253.12"
|
||||
- "business.itguys.com.br:172.16.121.13"
|
||||
- "verbocloud.itguys.com.br:172.16.253.13"
|
||||
- "srvoffice001.itguys.com.br:172.16.253.101"
|
||||
- "srvoffice001:172.16.253.101"
|
||||
|
||||
# ============================================
|
||||
# Fail2ban (Lê logs e bane IPs)
|
||||
# ============================================
|
||||
fail2ban:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.fail2ban
|
||||
container_name: fail2ban
|
||||
restart: always
|
||||
network_mode: host
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
volumes:
|
||||
- nginx_logs:/var/log/nginx:ro
|
||||
- modsec_logs:/var/log/modsecurity:ro
|
||||
|
||||
volumes:
|
||||
nginx_cache:
|
||||
nginx_logs:
|
||||
modsec_logs:
|
||||
ssl_data:
|
||||
certbot_data_conf:
|
||||
certbot_data_www:
|
||||
repo_data:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
caddy_logs:
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue