Compare commits

..

54 Commits

Author SHA1 Message Date
João Pedro Toledo Goncalves e4a4714ee5 deploy configuraçao do atendimento.grupopralog.com.br no proxy
correçao do fail2ban que nao agia em cima dos logs
2026-02-12 12:45:13 -03:00
João Pedro Toledo Goncalves a5788fc66d feat: sync timezone to America/Sao_Paulo, add diagnostic scripts to producao/scripts, and update PSDE docs 2026-02-08 15:54:09 -03:00
João Pedro Toledo Goncalves be7b271357 fix: restore legacy GEMINI docs, fix modsec loop, encoding issues 2026-02-08 14:24:23 -03:00
João Pedro Toledo Goncalves 982423c3ff feat: re-enable geoip logging and variable mapping 2026-02-08 13:51:49 -03:00
João Pedro Toledo Goncalves 0317b5217a securyti maps 2026-02-08 11:29:10 -03:00
João Pedro Toledo Goncalves dba24f08bc feat: hybrid deployment script with geoip auto-update and improved docs 2026-02-08 11:05:53 -03:00
João Pedro Toledo Goncalves b0b9485b1a Hardening: Integrate CVE 2025-2026 defenses (React2Shell, MadeYouReset, SolarWinds, Fortinet) 2026-02-07 14:21:51 -03:00
João Pedro Toledo Goncalves 7af7fa0ec7 Update README with Pathfinder V2 operational workflow and security features 2026-02-07 13:53:27 -03:00
João Pedro Toledo Goncalves 42a9ea5582 Integrate OWASP CRS v4 and Anti-Brute Force Security Rules 2026-02-07 13:48:47 -03:00
João Pedro Toledo Goncalves 93d0324426 docs(README): finalize 7-vector WAF documentation and combinatorial matrix details 2026-02-07 12:46:56 -03:00
João Pedro Toledo Goncalves ec536dfe9a feat(security): implement 7-vector combinatorial WAF matrix, 2024-2025 CVE protections, GeoIP integration and descriptive JSON logging 2026-02-07 12:45:51 -03:00
João Pedro Toledo Goncalves f81ac3aa73 tudo certo 2026-02-07 02:14:17 -03:00
João Pedro Toledo Goncalves 254ecb09f7 docs: update snippets catalog and ignore .gemini 2026-02-07 02:12:40 -03:00
João Pedro Toledo Goncalves fa29d48ed1 Merge branch 'producao' of https://git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder into producao 2026-02-07 01:57:37 -03:00
João Pedro Toledo Goncalves 58be68baaf updates e estabilizaçao 2026-02-07 01:57:35 -03:00
João Pedro Toledo Goncalves aa219f8510 Merge branch 'producao' of https://git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder into producao 2026-02-07 01:56:37 -03:00
João Pedro Toledo Goncalves 2a1646c726 feat(nginx): Recompilacao com Stream, AIO threads e correcao de logs 2026-02-07 01:55:53 -03:00
João Pedro Toledo Goncalves 78c3c82a69 feat(elite): expansao da stack elite 2026 - modulos, performance, forense e upgrade zero-downtime 2026-02-07 00:20:07 -03:00
João Pedro Toledo Goncalves e932ca8f7d feat(waf): implementado modsecurity 3.0.14, plugins crs v4 e tunings específicos por app 2026-02-06 22:18:42 -03:00
João Pedro Toledo Goncalves 5ada628ac4 docs: refina instruções de emissão SSL e caminhos 2026-02-06 18:21:13 -03:00
João Pedro Toledo Goncalves d64f3c527f fix(ssl): atualiza caminhos do certificado LetsEncrypt com sufixo -0001 2026-02-06 18:20:16 -03:00
João Pedro Toledo Goncalves 9c9c747a4b docs: detalha workflow de ativação de sites e SSL 2026-02-06 18:07:29 -03:00
João Pedro Toledo Goncalves 326a3711f0 docs: atualiza README.md com guias de instalação nativa e padrões ouro 2026-02-06 18:05:39 -03:00
João Pedro Toledo Goncalves 0d395f42c5 docs: consolidate READMEs and update for configuration-only model 2026-02-06 16:44:41 -03:00
João Pedro Toledo Goncalves af977eb2cb chore: pivot repository to configuration-only (removed docker artifacts and sensitive data) 2026-02-06 16:41:59 -03:00
João Pedro Toledo Goncalves 454cd564a1 fix: restore missing ssl certificates from history 2026-02-06 16:28:35 -03:00
João Pedro Toledo Goncalves 7e5ce88adb fix: add ssl certificates to ferreirareal config and confirm test-backend removal 2026-02-06 16:24:40 -03:00
João Pedro Toledo Goncalves 7aea780cb1 . 2026-02-06 15:52:35 -03:00
João Pedro Toledo Goncalves 58b5fbd3e2 . 2026-02-06 15:48:47 -03:00
João Pedro Toledo Goncalves 56a9c5e91a fix: isolate dynamic config (blacklist) to separate volume and bake static configs to prevent mount errors 2026-02-06 14:45:03 -03:00
João Pedro Toledo Goncalves 21a9c393c5 fix: bake nginx config into image and remove bind mount to prevent portainer directory error 2026-02-06 14:13:14 -03:00
João Pedro Toledo Goncalves 368cda2b76 feat: split logs into human-readable (stdout) and json (file) for better observability 2026-02-06 13:17:20 -03:00
João Pedro Toledo Goncalves 9e7decd6de refactor: restructure sites-ativos into nginx and logs folders for cleaner docker volume mapping 2026-02-06 13:14:05 -03:00
João Pedro Toledo Goncalves 354759743f feat: consolidate sites-ativos into production branch for single-source deployment 2026-02-06 13:08:51 -03:00
João Pedro Toledo Goncalves 0048b1a70b fix: resolve nginx infinite loop, crlf issues and missing modules 2026-02-05 15:53:26 -03:00
João Pedro Toledo Goncalves 34bb52d60d . 2026-02-05 15:41:27 -03:00
João Pedro Toledo Goncalves 3eafb5891b chore: ignore default fail2ban jails 2026-02-05 14:43:00 -03:00
João Pedro Toledo Goncalves 61a4fce622 feat(fail2ban): cleanup unused jails and add nginx-unified config 2026-02-05 14:37:47 -03:00
João Pedro Toledo Goncalves 74b1f3892d fix(docker): migrate to alpine 3.18, fix modsecurity and brotli build 2026-02-05 14:29:58 -03:00
João Pedro Toledo Goncalves f0abf2932f fix: Ajusta failregex para padrão numérico do Nginx JSON 2026-02-04 19:52:13 -03:00
João Pedro Toledo Goncalves 441b69658c docs: Adiciona análise de sizing e segurança de cache 2026-02-04 19:42:47 -03:00
João Pedro Toledo Goncalves 44c0220cba docs: Atualiza README com detalhes da nova infraestrutura 2026-02-04 19:20:34 -03:00
João Pedro Toledo Goncalves 609c92f484 feat: Implementa Nginx High-End com HTTP/3 e ModSecurity 2026-02-04 19:18:22 -03:00
João Pedro Toledo Goncalves d8c6607b3a fix: adiciona certbot-nginx para suportar comando --nginx 2026-01-30 11:43:31 -03:00
João Pedro Toledo Goncalves 9f18a4598a fix: escape password special characters in Dockerfile 2026-01-29 14:51:22 -03:00
João Pedro Toledo Goncalves 216630a219 feat: adiciona usuario itguys com acesso root e sudo no .bashrc 2026-01-29 09:25:36 -03:00
João Pedro Toledo Goncalves 6ee169464c fix: mount volume to directory instead of file to avoid OCI error 2026-01-29 09:22:52 -03:00
João Pedro Toledo Goncalves 368855f2b0 fix: troca bind mounts por volumes e ajuste busca git sites-ativos 2026-01-29 09:18:36 -03:00
João Pedro Toledo Goncalves 54f8a4283b feat: custom shell, SSH porta 122 e network_mode host 2026-01-29 09:13:14 -03:00
João Pedro Toledo Goncalves c3b9316fd2 remoçao do .gemini 2026-01-29 09:03:08 -03:00
João Pedro Toledo Goncalves 7e20ba5c87 Cleanup: Remove configs (conf.d, snippets) from production branch (moved to sites-ativos) 2026-01-27 14:35:44 -03:00
João Pedro Toledo Goncalves 4cb6b85f29 Fix: Remove snippets bind-mount to prevent empty directory shadowing 2026-01-27 14:17:52 -03:00
João Pedro Toledo Goncalves fd770b61a2 Fix: Add nano and remove nginx.conf host-mount for Portainer compatibility 2026-01-27 14:14:33 -03:00
João Pedro Toledo Goncalves 975d6ab90b Refactor: Simplify infrastructure to single Nginx container (Legacy Removed) 2026-01-27 14:03:04 -03:00
321 changed files with 33041 additions and 1469 deletions

View File

@ -1,54 +0,0 @@
# Documentation and config folders
.gemini/
.git/
.github/
.vscode/
.idea/
# Legacy files (not needed in container)
legacy/
_backup/
# Logs and debug files
*.log
debug_logs*.txt
nginx_test*.log
# Environment files
.env
.env.local
# Git files
.gitignore
.gitattributes
# Documentation
README.md
*.md
!nginx.conf
# Docker files (avoid recursive includes)
docker-compose*.yml
Dockerfile*
# Temporary and backup files
*.tmp
*.bak
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db
# SSL private keys (should be mounted as volume, not baked in)
ssl/*.key
# Caddy Data
caddy_data/
caddy_config/
caddy_logs/
# Disabled configs
*.disabled

View File

@ -1,135 +1,129 @@
# NGINX Pathfinder Proxy - Documentação Técnica # 🤖 Instruções para Agentes Gemini
## Visão Geral **Especialista NGINX/Linux Brasileiro. Gerencia Pathfinder Proxy. Escrita: direta e técnica.**
Projeto de infraestrutura para Proxy Reverso de Alta Disponibilidade, utilizando Containers Docker para modularidade e fácil manutenção. ## 🌍 Ambiente
## Arquitetura de Containers - **OS**: Ubuntu 24.04 (Nativo). **IP**: 172.17.0.253.
- **Login**: itguys | **Senha**: vR7Ag$Pk
- **Git**: https://git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder.git.
- **Stack**: Nginx Mainline (1.29.5) + ModSec (3.0.14) + Fail2Ban (1.0.2).
O projeto roda sobre 3 serviços orquestrados via `docker-compose.yml`: ## 🧩 Snippets (`producao/nginx/snippets/`)
| Serviço | Imagem | Porta Exposta | Função | - **acme_challenge**: Desafios Certbot (HTTP-01).
|---------|--------|---------------|--------| - **ads_disallow**: Bloqueia acesso a ads.txt.
| **modsecurity** | `owasp/modsecurity-crs:nginx-alpine` | `80`, `443` | **Frontend (WAF)**. Recebe todo o tráfego da internet, filtra ataques (SQLi, XSS) e encaminha requisições limpas para o Proxy. | - **bandwidth_limit**: Controle de banda e downloads (10MB+ limited to 1MB/s).
| **nginx-proxy** | `alpine` (Custom Build) | `8080` (Interna) | **Backend Proxy**. Gerencia vhosts, terminação SSL, cache, compressão Brotli e roteamento para as aplicações finais. | - **blacklist**: Lista dinâmica de IPs banidos pelo Fail2Ban.
| **fail2ban** | `crazymax/fail2ban` | - | **Watchdog**. Lê logs compartilhados dos dois containers acima e bane IPs maliciosos diretamente no host (via iptables). | - **cache_optimizer**: Configuração SWR (Stale-While-Revalidate) e headers de cache.
- **cache_proxy_params**: Parâmetros padrão para proxy cache (Lock, Stale).
- **cache_zones**: Definição de zonas de cache e chaves dinâmicas.
- **compression**: Stack moderna de compressão (Gzip + Brotli).
- **fingerprinting**: Cache imutável para assets versionados (Immutable).
- **humans.txt**: Créditos técnicos e ferramentas.
- **log_formats**: Definição do log JSON `detailed_proxy` com campos de segurança.
- **modsecurity**: Ativação do motor WAF e inclusão da Blacklist.
- **proxy_params**: Headers de proxy, timeouts e ofuscação de backend.
- **rate_limit**: Zonas de limitação (Global vs Punição).
- **robots_allow**: Permite indexação total em robots.txt.
- **robots_disallow**: Bloqueia indexação total em robots.txt.
- **security.txt**: Standard de reporte de vulnerabilidades (RFC 9116).
- **security_actions**: Ações de bloqueio baseadas no score (Retorna 444).
- **security_headers**: Headers de borda 2026 (COOP, COEP, CORP, Permissions).
- **security_maps**: Motor PSDE (Detecção de Bots, URIs, Métodos e Scoring).
- **ssl_params**: Stack TLS 1.3, HSTS e HTTP/3 (QUIC).
- **stub_status**: Métricas de estado do Nginx para monitoramento.
- **well_known**: Agregador de arquivos padrão (.well-known, robots, humans).
> **Note**: `app_specific_modsec_tuning` fica em `producao/nginx/modsec/`, não em snippets.
## 🔄 Workflow: Novo Site ou Atualização
**Sempre pergunte e pesquise antes de configurar:**
### Perguntas Obrigatórias
- **Novo Site?** Perguntar: Tipo de site, IP e URL destino.
- **Atualização?** Perguntar: Atualizar IP? Alterar URL destino?
### Regras
- **Pesquisa Web**: Obrigatório pesquisar ajustes finos específicos para o sistema/engine alvo.
- **Git**: Alt em `producao/` -> commit e push para branch `producao`.
- **Proibição**: NUNCA sincronize `.gemini/` ou `antes-do-docker/`.
- **Snippets Novos**: Se criar um novo snippet em `producao/nginx/snippets/`, documente-o nesta lista imediatamente.
--- ---
## Automação SSL ## 🚀 Workflow de Deploy Técnico (Automação)
O sistema possui um mecanismo de **auto-cura** para certificados SSL. **NUNCA faça commit direto na branch `producao` sem antes validar a configuração.**
### Componentes O repositório conta com um script de automação híbrido (`producao/scripts/deploy_pathfinder.py`) que deve ser usado para **todo e qualquer deploy**.
1. **Certbot**: Instalado dentro do container `nginx-proxy`.
2. **Volumes**:
- `ssl/`: Onde ficam os arquivos `.crt` e `.key` usados pelo NGINX.
- `certbot/`: Onde o Certbot guarda os arquivos originais do Let's Encrypt.
3. **Scripts**:
- `scripts/inject_acme.sh`: Varre todos os arquivos em `conf.d/` e injeta o snippet de validação ACME (`.well-known`) se não existir.
- `scripts/renew_ssl.sh`:
1. Verifica a data de expiração de cada certificado ativo.
2. Se faltar **3 dias ou menos**, dispara `certbot renew`.
3. Copia os novos arquivos gerados para a pasta `ssl/`.
4. Recarrega o NGINX.
### Agendamento ### Passo a Passo para Agentes:
- **Cron**: Configurado no `pre-flight.sh` para rodar todos os dias às **01:00 AM**.
- **Startup**: A verificação também roda a cada reinício do container.
---
## Estrutura de Arquivos
1. **Faça suas alterações** nos arquivos de configuração (`nginx/`).
2. **Valide e Deploye** rodando o script abaixo no terminal do Windows:
```powershell
python producao/scripts/deploy_pathfinder.py sync --all
``` ```
. 3. **Verifique a Saída**:
├── conf.d/ # Configurações de sites (VHosts) - O script fará o upload, testará a configuração (`nginx -t`) no servidor e fará o reload.
├── snippets/ # Trechos reutilizáveis - Se houver erro, **corrija antes de prosseguir**. O script fará rollback automático no servidor, mas seu código local estará "quebrado".
│ ├── acme_challenge.conf # Snippet para validação Let's Encrypt 4. **Confirmar**: Somente após o sucesso do comando acima ("Deploy Remoto Concluído com Sucesso!"), faça o commit das alterações.
│ ├── internal_networks.conf # IPs permitidos (VPN/Local)
│ └── ... ## 🛠️ Comandos Úteis
├── scripts/ # Scripts de automação
│ ├── pre-flight.sh # Entrypoint (DNS Check + Cron Setup) - **Sincronizar Tudo (Nginx + Fail2Ban + GeoIP)**:
│ ├── inject_acme.sh # Injetor de config ACME `python producao/scripts/deploy_pathfinder.py sync --all`
│ └── renew_ssl.sh # Lógica de renovação - **Deploy de Novo Site**:
├── ssl/ # Certificados em uso `python producao/scripts/deploy_pathfinder.py site --deploy dominio.com`
├── fail2ban/ # Configs do Fail2ban - **Atualizar GeoIP Manualmente**:
│ ├── jail.d/ # Definição das prisões `python producao/scripts/deploy_pathfinder.py geoip --update`
│ └── filter.d/ # Regex de detecção
├── .gemini/ # Documentação do projeto ## ⚠️ Pontos de Atenção
└── docker-compose.yml # Orquestração
- **GeoIP**: O script baixa automaticamente os bancos GeoIP se faltarem. Não precisa baixar manualmente.
- **Paramiko**: O script usa `paramiko` para SSH. Se não estiver instalado, instale com `pip install paramiko`.
- **Credenciais**: As credenciais de acesso ao servidor estão embutidas no cabeçalho do script. Não as exponha em logs públicos.
## 🐛 Solução de Problemas e Lições Aprendidas (2026-02-08)
### 1. Conflitos de ModSecurity (Loop em `nginx -t`)
- **Sintoma**: O deploy reporta sucesso, mas as alterações não aparecem no servidor. O log remoto mostra `nginx: [emerg] "modsecurity_rules_file" directive is duplicate`.
- **Causa**: O arquivo `snippets/modsecurity.conf` já define `modsecurity_rules_file`. Se você incluir esse snippet E também definir a diretiva `modsecurity_rules_file` no bloco `server` (ex: `ferreirareal.com.br.conf`), o Nginx falhará.
- **Solução**: Use apenas `include snippets/modsecurity.conf;` no bloco server. A diretiva `modsecurity_rules_file /etc/nginx/modsec/main.conf;` deve ficar comentada ou removida do vhost.
### 2. Scripts de Diagnóstico e Recuperação (2026-02-08)
Foram criados scripts auxiliares em `producao/scripts/` para situações de emergência ou validação profunda. Use-os com cautela:
- **`restore_nginx.py`**:
- **Função**: Força o upload do `nginx.conf` local para o servidor e reinicia o serviço.
- **Uso**: `python producao/scripts/restore_nginx.py`
- **Quando usar**: Se o `deploy_pathfinder.py` falhar ou se o Nginx não subir por erro de configuração crítica (ex: variáveis faltando).
- **`fetch_logs.py`**:
- **Função**: Baixa logs específicos do servidor para análise local.
- **Uso**: `python producao/scripts/fetch_logs.py`
- **Quando usar**: Para investigar ataques ou erros sem precisar logar via SSH.
- **`verify_time_and_logs.py`**:
- **Função**: Verifica a data do servidor e os últimos logs de acesso.
- **Uso**: `python producao/scripts/verify_time_and_logs.py`
- **Quando usar**: Para confirmar se o timezone está correto (-0300) e se o Nginx está gerando logs novos.
### 3. Falhas Silenciosas de Rollback
- **Cuidado**: O script `deploy_pathfinder.py` executa um rollback automático se `nginx -t` falhar.
- **O que acontece**: O script restaura o backup anterior e reinicia o Nginx. Isso faz o deploy parecer bem-sucedido (exit code 0), mas seus arquivos novos foram descartados.
- **Verificação**: **SEMPRE** verifique o timestamp dos arquivos remotos após um deploy crítico para garantir que foram atualizados:
```python
# Exemplo de verificação rápida
client.exec_command("ls -l /etc/nginx/snippets/log_formats.conf")
``` ```
--- ### 3. Encoding Windows vs Linux
- **Problema**: `UnicodeEncodeError: 'charmap' codec can't encode character...` ao rodar scripts Python no Windows.
- **Causa**: O console do Windows padrão (cp1252) não suporta emojis como 🚀 ou ✅.
- **Regra**: Evite usar emojis ou caracteres especiais em scripts que rodam no lado do cliente (Windows). Use `[OK]`, `[ERROR]`, `[+]` em vez de ícones.
## Módulos Especiais ### 4. Organização e Limpeza
- **Área de Diagnóstico**: Use a pasta `logs/` na raiz do projeto (`ngnix-pathfinder-proxy/logs`) para armazenar logs temporários, downloads de debug e "bagunça" necessária durante investigações.
### 1. Brotli & Headers More - **Limpeza**: Após resolver o problema, **limpe** esta pasta para não commitar lixo no repositório. O `.gitignore` deve ignorar essa pasta, mas mantenha o hábito de limpeza.
O container `nginx-proxy` é construído manualmente (`Dockerfile`) para incluir módulos que não vêm por padrão no Alpine:
- `nginx-mod-http-brotli`
- `nginx-mod-http-headers-more`
### 2. ModSecurity (WAF)
Rodar o WAF em container separado (`modsecurity`) evita a necessidade de compilar o ModSecurity no NGINX principal.
**Arquitetura Customizada:**
- **Injeção de Template**: Um arquivo `modsec.conf.template` local é montado durante o boot para contornar limitações de permissão do container oficial. Ele instrui o NGINX a carregar regras customizadas.
- **Regras Modulares**: Localizadas em `modsec_rules/`, divididas por aplicação (`gitea-rule-exceptions.conf`, `nextcloud...`).
- **Global**: `global-exceptions.conf` define apenas a whitelist de rede.
- **Bypass de Emergência**: Se o WAF falhar, altere as portas no `docker-compose.yml` para expor o `nginx-proxy` diretamente.
---
## Fluxo de Deploy Atualizado
```mermaid
graph TD
Start[Deploy] --> DetectIP[Detectar IP Público]
DetectIP --> Build[Docker Build (NGINX + Certbot)]
Build --> Up[Docker Compose Up]
Up --> PreFlight[Pre-Flight Script]
PreFlight --> DNSCheck[Validar DNS dos Domínios]
DNSCheck --> CronSetup[Configurar Cron Job]
CronSetup --> SSLCheck[Verificar Validade SSL]
SSLCheck -- Vence > 3 dias --> StartNginx[Iniciar NGINX]
SSLCheck -- Vence <= 3 dias --> Renew[Rodar renew_ssl.sh]
Renew --> StartNginx
```
---
## Comandos Operacionais
**Verificar status dos serviços:**
```bash
docker compose ps
```
**Verificar validade dos SSL (Log):**
```bash
docker compose logs nginx-proxy | grep "SSL"
```
**Forçar renovação SSL manualmente:**
```bash
docker compose exec nginx-proxy /scripts/renew_ssl.sh
```
**Reload Zero-Downtime (Blue-Green Logic):**
Este comando valida a configuração e executa um reload gracioso (`nginx -s reload`), onde novos workers assumem as novas configurações enquanto os antigos terminam as requisições correntes.
```bash
./scripts/reload.sh # Linux
./scripts/reload.ps1 # Windows PowerShell
```
**Banir um IP manualmente:**
```bash
docker compose exec fail2ban fail2ban-client set nginx-badbots banip 1.2.3.4
```
**Adicionar novo site:**
1. Criar `conf.d/novo-site.conf`
2. `docker compose restart nginx-proxy`
3. O script de startup irá validar o DNS e injetar o suporte ACME automaticamente.

View File

@ -1,40 +0,0 @@
# Tarefas Pendentes e Melhorias Futuras
## 1. Gestão Dinâmica de DNS
**Origem:** Migração de `legacy/hosts`
- **Problema:** O método atual usa `extra_hosts` no `docker-compose.yml`, que é estático e exige recriação do container para alterações.
- **Objetivo:** Mudar o modo de registro e atualização de DNS para ser mais dinâmico ou simples.
- **Ideias:** DNS containerizado (Bind/CoreDNS) ou Service Discovery.
## 2. Revisão de Regras ModSecurity
**Origem:** Migração de `legacy/nginx/modsecurity/*.conf` (Regras Antigas)
- **Status:** ✅ Concluído.
- **Resolução:** Regras refatoradas para estrutura modular (`modsec_rules/`). WAF ativo e configurado via template injection para Gitea, Nextcloud, Exchange, Zabbix e outros.
- **Ação:** Monitorar logs (`modsec_audit.log`) para ajustes finos futuros.
## 3. Atualizações Zero-Downtime (Sem Queda)
**Objetivo:** Criar um método para atualizar configurações de sites sem que clientes externos percam a conexão.
- **Status:** ✅ Concluído.
- **Solução Implementada:** Script `./scripts/reload.sh` que executa `nginx -t` e `nginx -s reload` (Reload Suave/Process-Level Blue-Green).
- **Como usar:** Execute `./scripts/reload.sh` após alterar qualquer `.conf`.
## 4. Conexão Direta na Interface do Host
**Objetivo:** Configurar o proxy para rotear tráfego tanto internamente (entre containers Docker) quanto externamente (para serviços fora do Docker).
- **Status:** 🧪 Implementado - Aguardando Teste no Host
- **Solução Implementada:**
- Adicionado `host.docker.internal:host-gateway` no `docker-compose.yml` para ambos containers
- Criado `snippets/docker_resolver.conf` para resolução DNS dinâmica de containers
- Criado `conf.d/test-connectivity.conf` (temporário) com endpoints de teste
- Atualizado diagrama de arquitetura no `README.md`
- **Testes Necessários (no host de deploy):**
```bash
# Rebuild e restart
docker compose build --no-cache nginx-proxy
docker compose down && docker compose up -d
# Testar conectividade
docker compose exec nginx-proxy ping -c 2 10.10.253.254
docker compose exec nginx-proxy ping -c 2 10.10.253.128
```
- **Após Validação:** Deletar `conf.d/test-connectivity.conf` e marcar como ✅ Concluído.

View File

@ -0,0 +1,51 @@
---
description: Guia detalhado para garantir a segurança máxima (Hardening) em sites e no sistema Pathfinder Proxy.
---
# Workflow: Hardening de Segurança Pathfinder
Este workflow orienta o agente na aplicação das proteções mais rígidas para o ecossistema Nginx + ModSecurity + Fail2Ban.
### 1. Uso de Snippets de Segurança Existentes
Sempre utilize os snippets em `producao/nginx/snippets/` como base:
- **`ssl_params.conf`**: Configuração base de TLS e HTTP/3.
- **`security_headers.conf`**: Headers de borda modernos (Referrer, COOP, COEP).
- **`modsecurity.conf`**: Ativação do WAF e integração com a `blacklist.conf`.
- **`security_maps.conf`**: Inteligência de Scoring (PSDE).
- **`security_actions.conf`**: Decisão final de bloqueio (444).
- **`well_known.conf`**: Agregador de arquivos de raiz (robots, security, humans).
- **`rate_limit.conf`**: Limites de tráfego e zonas de punição.
### 2. Criação de Novos Snippets
Se as proteções atuais não forem suficientes para um sistema específico:
- **Crie um novo snippet** em `producao/nginx/snippets/` com nome descritivo.
- **Siga o padrão**: Use comentários claros e mantenha a modularidade.
- **Documentação Obrigatória**: Se criar um snippet novo, você **DEVE** adicionar sua descrição na seção `🛠️ Snippets` do arquivo `GEMINI.md` imediatamente.
### 3. Reforço da Camada SSL/TLS (Snippet `ssl_params`)
- **Protocolos**: Garanta o uso exclusivo de TLS 1.2 e TLS 1.3. Desative versões legadas.
- **HSTS**: Verifique se o header `Strict-Transport-Security` está ativo com pelo menos 1 ano (`31536000s`) e inclui subdomínios.
- **OCSP Stapling**: Certifique-se de que a validação de certificado é feita no servidor para reduzir latência e aumentar a privacidade.
- **HTTP/3**: Sempre anuncie os headers de QUIC (`Alt-Svc`) para navegadores compatíveis.
### 4. Implementação de Headers de Proteção de Borda
- **Anti-Clickjacking**: Use `X-Frame-Options: SAMEORIGIN` em todos os VHosts, a menos que o site precise ser emoldurado por domínios específicos.
- **Anti-Sniffing**: O header `X-Content-Type-Options: nosniff` deve ser obrigatório para evitar que o navegador execute arquivos com tipos MIME incorretos.
- **Segurança de Conteúdo (CSP)**: Analise os recursos (Scripts, Imagens, Estilos) e crie uma política que restrinja fontes externas não confiáveis.
- **Permissions-Policy**: Desative acessos desnecessários a hardware (Câmera, Microfone, Geolocalização) diretamente no nível de header.
### 5. Orquestração ModSecurity + PSDE
- **Motor Ativo**: O ModSecurity deve estar em modo de bloqueio (`SecRuleEngine On`) para todas as rotas sensíveis.
- **Sincronização com PSDE**: A lógica descrita no `security_maps.conf` deve atuar como a primeira linha de defesa (Fast-fail) para bots e URIs suspeitas.
- **Tratamento de Falsos Positivos**: Em caso de bloqueio indevido, a correção deve ser feita via remoção seletiva de regras por ID nos respectivos VHosts.
### 6. Blindagem contra Robôs e Scrapers (Snippet `well_known`)
- **Arquivos de Raiz (Well-Known)**: Utilize o snippet `well_known.conf` que já consolida as melhores práticas de identificação e bloqueio.
- **`robots_disallow.conf`**: Já configurado para retornar `Disallow: /`, instruindo robôs legítimos a não indexarem o site.
- **`security.txt.conf`**: Define o contato padrão de segurança (`mailto:suporte@itguys.com.br`).
- **`ads_disallow.conf`**: Bloqueia vendedores de anúncios não autorizados.
- **Bloqueio de IA e Má-Fé**: O sistema já possui no `security_maps.conf` uma lista extensa de assinaturas de IAs (GPTBot, ClaudeBot, Gemini-Ai, etc.) e Scrapers que ignoram o `robots.txt`. O agente deve apenas garantir que este mapeamento esteja ativo via `security_actions.conf`.
### 7. Gestão de Blacklist e Fail2Ban
- **Ação do Firewall**: O Nginx deve incluir o snippet `blacklist.conf` dentro do bloco do ModSecurity.
- **Isolamento de Erros**: Configurações de VHost que geram excesso de erros 403/404 devem ser monitoradas agressivamente pelo Fail2Ban.

View File

@ -0,0 +1,78 @@
---
description: Guia passo a passo para otimizar buffers, timeouts e cache no Nginx baseado no tipo de carga de trabalho.
---
# 🚀 Workflow: Performance Tuning (Pathfinder Proxy)
Este workflow guia o ajuste fino do Nginx para extrair a máxima performance, garantindo que o tempo de resposta (`request_time`) e a carga da CPU sejam minimizados.
### 1. Base Tecnológica (Obrigatório)
Todo site no Pathfinder deve começar com a fundação de compressão e parâmetros base:
```nginx
# No bloco 'http' ou 'server'
include snippets/compression.conf; # Gzip + Brotli (Google)
include snippets/proxy_params.conf; # Real-IP + Headers + Buffers Base
```
### 2. Aplicação de Presets por Carga de Trabalho
#### ⚡ Preset: APIs e Node.js
O `proxy_params.conf` já traz timeouts de 60s. Para APIs de tempo real, você deve **sobrescrever** para timeouts mais agressivos:
```nginx
location /api/ {
include snippets/proxy_params.conf;
# Sobrescrita para baixa latência
proxy_read_timeout 30s;
proxy_buffering off;
# Suporte a WebSockets (Necessário para Traccar/Socket.io)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
#### 📂 Preset: Downloads e Assets Estáticos
Otimize usando o motor SWR (Stale-While-Revalidate):
```nginx
location /static/ {
include snippets/cache_optimizer.conf; # Ativa SWR + X-Cache-Status
# Performance de Sistema
sendfile on;
tcp_nopush on;
# Cache no Browser (1 ano para assets com hash)
expires 365d;
add_header Cache-Control "public, no-transform";
}
```
#### 🎬 Preset: Streaming (Vídeo/Áudio)
Para streaming, precisamos de buffers maiores que o padrão do `proxy_params.conf`:
```nginx
location /stream/ {
include snippets/proxy_params.conf;
# Suporte a Range Requests (Seek no vídeo)
proxy_cache_key "$host$request_uri$http_range";
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
# Tuning de Buffer Exclusivo
proxy_buffers 32 16k;
proxy_buffer_size 64k;
proxy_read_timeout 600s;
}
```
### 3. Caching Inteligente (Pseudo-CDN)
Use o snippet `cache_zones.conf` para definir onde o cache reside e o `cache_proxy_params.conf` para comportamento padrão de cache.
### 4. Verificação de Performance
Utilize o formato de log **detailed_proxy** (definido em `snippets/log_formats.conf`) para depurar gargalos:
```bash
# Monitorar tempo de resposta do backend em tempo real
tail -f /var/log/nginx/access_json.log | jq '. | {url: .uri, status: .status, upstream_time: .upstream_response_time, cache: .upstream_cache_status}'
```

50
.gitignore vendored
View File

@ -1,42 +1,12 @@
# Logs and debug files # Runtime Data
*.log logs/
debug_logs*.txt ssl/
nginx_test*.log certbot/
# Environment files
.env
.env.local
# Docker # Docker
docker-compose.override.yml docker-compose.yml
Dockerfile
# SSL certificates (sensitive - should be managed separately) *.sh
ssl/*.key .env
ssl/*.crt .gemini/
ssl/*.pem logs/
# Editor files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db
# Temporary files
*.tmp
*.bak
# Disabled configs
*.disabled
# Backups
_backup/
# Caddy Data
caddy_data/
caddy_config/
caddy_logs/

383
README.md
View File

@ -1,238 +1,189 @@
# NGINX Pathfinder Proxy # 🛡️ Nginx Pathfinder Proxy
Solução moderna de Proxy Reverso containerizado, construída com NGINX, ModSecurity WAF e automação de SSL. Este repositório é o núcleo de inteligência e configuração do **Pathfinder Proxy**, instalado nativamente em **Ubuntu 24.04**. Ele combina performance extrema (HTTP/3, Brotli) com um motor de segurança multicamadas (PSDE + WAF + Fail2Ban).
## 🚀 Funcionalidades
### 🛡️ Segurança em Primeiro Lugar
- **ModSecurity WAF**: Conjunto de Regras OWASP (CRS) integrado rodando como proxy sidecar/frontend.
- **Fail2ban**: Serviço "cão de guarda" que bane IPs com comportamento suspeito (bots ruins, excesso de erros 4xx/5xx).
- **Mapas de Segurança**: Bloqueio automatizado de User-Agents maliciosos e restrições de rede interna.
### ⚡ Performance
- **HTTP/3 (QUIC)**: Habilitado para conexões modernas de baixa latência.
- **Compressão Brotli**: Melhores taxas de compressão que o Gzip padrão.
- **Headers More**: Manipulação avançada de cabeçalhos para respostas limpas.
### 🔒 SSL Automatizado
- **Renovação Zero-Touch**: O Certbot integrado verifica a validade diariamente.
- **Auto-Renovação**: Renova automaticamente certificados próximos do vencimento (<= 3 dias).
- **Injeção Inteligente**: Injeta automaticamente os snippets de desafio ACME nas configurações dos sites.
--- ---
## 🛠️ Como Trabalhar neste Repositório ## 🏗️ Estrutura de Pastas e Componentes
A configuração é modular para permitir manutenção rápida e alta disponibilidade.
- `nginx.conf`: O "cérebro" global. Configura workers, logs JSON e carrega os módulos dinâmicos.
- `conf.d/`: Contém as definições de cada site (**VHosts**).
- `snippets/`: Componentes reutilizáveis (SSL, Proxy, Cache, WAF, Headers).
- `modsec/`: Configuração do ModSecurity, regras **OWASP CRS v4** e tunings específicos.
- `dynamic/`: Arquivos modificados em tempo real (ex: `blacklist.conf` pelo Fail2Ban).
- `scripts/`: Scripts de automação e diagnóstico (`deploy_pathfinder.py`, `restore_nginx.py`, `fetch_logs.py`).
---
## 🧩 Guia de Snippets (Uso Obrigatório)
Para garantir o **Padrão Ouro**, todo site deve incluir os snippets básicos:
1. `include snippets/ssl_params.conf;`: Ativa TLS 1.3, HSTS e anuncia **HTTP/3 (QUIC)**.
2. `include snippets/proxy_params.conf;`: Headers padrão e ofuscação de tecnologia de backend (`Server`, `X-Powered-By`).
3. `include snippets/security_headers.conf;`: **Headers de 2026** (COOP, COEP, CORP) para proteção de isolamento do navegador.
4. `include snippets/modsecurity.conf;`: Ativa o WAF e a Blacklist dinâmica.
5. `include snippets/security_actions.conf;`: Toma a decisão final de bloquear (`444`) se o motor PSDE detectar risco alto.
6. `include snippets/cache_optimizer.conf;`: Otimiza a entrega de estáticos com cache inteligente (SWR).
### 📚 Catálogo Completo de Snippets
Abaixo, a lista completa de componentes modulares disponíveis em `nginx/snippets/`:
#### 🔒 Segurança & WAF
- **`modsecurity.conf`**: Ativa o WAF (OWASP CRS v4) e carrega a blacklist.
- **`security_headers.conf`**: Headers de borda 2026 (COOP, COEP, CORP, Permissions-Policy).
- **`security_actions.conf`**: Executa o bloqueio (Return 444) baseado no score do PSDE.
- **`security_maps.conf`**: Motor de decisão (PSDE), detecção de bots, scorings e variáveis de risco.
- **`blacklist.conf`**: Lista dinâmica de IPs banidos (gerenciado pelo Fail2Ban).
- **`ads_disallow.conf`**: Bloqueia acesso a `ads.txt`.
- **`robots_disallow.conf`**: Bloqueia indexação total (para ambientes de homologação/privados).
- **`robots_allow.conf`**: Permite indexação total.
#### 🚀 Performance & Cache
- **`cache_optimizer.conf`**: Otimização fina de SWR (Stale-While-Revalidate) e headers de cache.
- **`cache_proxy_params.conf`**: Configurações padrão de lock e validade de cache para upstream.
- **`cache_zones.conf`**: Definição das zonas de memória compartilhada e chaves de cache.
- **`compression.conf`**: Stack de compressão moderna (Brotli + Gzip) com níveis otimizados.
- **`fingerprinting.conf`**: Cache imutável (1 ano) para assets versionados com hash no nome.
#### 🚦 Controle de Tráfego
- **`rate_limit.conf`**: Zonas de limitação de requisições (Global vs Punição por Score).
- **`bandwidth_limit.conf`**: Limita a velocidade de download após X MB transferidos.
- **`proxy_params.conf`**: Headers de encaminhamento (Real-IP, Forwarded) e ofuscação de backend.
- **`ssl_params.conf`**: Configuração TLS 1.3, HSTS e HTTP/3 (QUIC).
- **`acme_challenge.conf`**: Endpoint para renovação de certificados SSL (Certbot).
#### 📊 Monitoramento & Identidade
- **`log_formats.conf`**: Define o formato JSON `detailed_proxy` rico em metadados de segurança.
- **`stub_status.conf`**: Endpoint de métricas internas do Nginx (para Zabbix/Prometheus).
- **`humans.txt.conf`**: Rota para arquivos de créditos técnicos.
- **`security.txt.conf`**: Rota padrão (RFC 9116) para reporte de segurança.
- **`well_known.conf`**: Agregador que inclui robots, humans e security.txt de uma vez.
---
## 🛡️ Camada de WAF (ModSecurity 3.0.14)
O Pathfinder Proxy utiliza o **ModSecurity v3** compilado sob medida para o Nginx Mainline.
- **Versão Nginx**: 1.29.5 Mainline (Oficial).
- **Versão ModSec**: 3.0.14.
- **Regras**: OWASP Core Rule Set (CRS) v4 (Instalação Minimalista).
- **Anti-Brute Force**: Proteção integrada contra força bruta em páginas de login via ModSecurity Collections (Phase 1).
- **API Support**: Métodos **PUT, PATCH e DELETE** liberados por padrão para suporte a sistemas modernos.
- **Tuning**: Arquivo `modsec/app_specific_modsec_tuning.conf` centraliza exceções granulares (Zabbix, Gitea, UniFi, Veeam).
---
## 🧠 Motor de Segurança PSDE "Elite" (8-Vector Matrix)
Diferente de firewalls comuns, o Pathfinder utiliza uma **Matriz de Pontuação Combinatória** no `security_maps.conf` que analisa 8 vetores simultâneos:
1. **🛡️ Bot:** Bloqueio de 600+ user-agents maliciosos.
2. **🌐 URI:** Acesso a arquivos sensíveis e assinaturas de CVEs recentes.
3. **⚙️ Method:** Métodos HTTP perigosos (TRACE, DEBUG) em rotas críticas.
4. **🔥 Payload:** Inspeção profunda de `$args` (SQLi, XSS, RCE, Log4j).
5. **🌍 Geo:** Risco por país (CN, RU, KP, IR) via **GeoIP2**.
6. **🚦 Protocol:** Violações como User-Agents vazios ou falsificados.
7. **🔗 Referer:** 400+ domínios de spam e phishing bloqueados instantaneamente.
8. **🤯 Header:** Detecção de anomalias em cabeçalhos customizados (ex: React2Shell CVE-2025-55182).
### 📈 Lógica de Decisão
- **Nivel 3 (ATAQUE_CRITICO)**: Payloads maliciosos, Referer Spam, Headers Corrompidos ou combinação de 3+ vetores.
- **Nivel 2 (RISCO_ALTO)**: Combinação de 2 vetores de risco (ex: Bot + Geo-Risco).
- **Nivel 1 (SUSPEITO)**: Detecção de sinais individuais.
---
## 🛠️ Workflow Operacional: Ativando um Novo Site
Siga este procedimento para colocar um novo sistema no ar com segurança máxima:
### 1. Preparação no Repositório (Local)
1. Crie o arquivo `nginx/conf.d/nome-do-site.conf` seguindo o **Padrão Ouro**.
2. **Atenção:** Aponte os caminhos de certificado para `/etc/letsencrypt/live/nome-do-site/`.
3. Faça o commit e push para a branch `producao`.
### 2. Sincronização no Servidor (SSH)
1. Entre no servidor e vá para o diretório de scripts: `cd /etc/nginx/scripts/`.
2. Execute o deploy seguro: `sudo python3 deploy_pathfinder.py`.
- **Nota:** Este script faz backup automático e rollback se a configuração estiver errada.
---
## 🛠️ Automação de Deploy (Pathfinder Automator V2 - Hybrid)
O Pathfinder conta com o orquestrador `scripts/deploy_pathfinder.py`, que agora funciona em modo **Híbrido (Windows Client -> Linux Server)**. Você roda o script na sua máquina local e ele faz todo o trabalho sujo.
### Pré-requisitos ### Pré-requisitos
- Docker & Docker Compose instalados - Python 3 instalado no Windows.
- Acesso à internet (para baixar imagens e validar SSL) - Biblioteca Paramiko: `pip install paramiko`
### 1. Implantar o Servidor (Deploy) ### Comandos Principais
Para iniciar toda a infraestrutura: - **`python producao/scripts/deploy_pathfinder.py sync --all`**:
```bash - Empacota suas configs locais.
./deploy.sh - Conecta no servidor via SSH.
``` - Atualiza bancos GeoIP automaticamente.
*Este script detecta seu IP público, configura o ambiente e sobe os containers.* - Sincroniza configurações e recarrega o Nginx.
- **Faz Rollback Automático** se o `nginx -t` falhar.
### 2. Adicionar um Novo Site - **`python producao/scripts/deploy_pathfinder.py site --deploy <domínio>`**:
Todas as configurações de sites ficam na pasta `conf.d/`. - Sobe um novo VHost + Certificado SSL + Teste de DNS.
1. **Crie o arquivo de configuração**: - **`python producao/scripts/deploy_pathfinder.py geoip --update`**:
Crie um arquivo `.conf` em `conf.d/` (ex: `meusite.com.br.conf`). Use um dos arquivos existentes como modelo. - Força a atualização dos bancos de dados GeoIP2 (Mirror GitHub).
**Modelo Básico (com SSL):** ### 🛡️ Segurança de Operação
```nginx - **Backup & Rollback Atômico**: Cada alteração gera um `.bak`. Se `nginx -t` falhar, o script desfaz a alteração imediatamente.
# Backend (para onde vai o tráfego) - **Auditoria Syslog**: Todas as ações são registradas no syslog do servidor.
upstream meu_backend { - **Validação Local**: O script retorna `Exit Code 1` no Windows se falhar no Linux, ideal para CI/CD.
server 192.168.1.10:8080; - **DNS Safeguard**: O deploy de SSL só ocorre se o DNS já estiver apontando para o IP do servidor, evitando bloqueios no Let's Encrypt.
}
# Redirecionamento HTTP -> HTTPS
server {
listen 80;
server_name meusite.com.br;
include /etc/nginx/snippets/acme_challenge.conf; # Importante para SSL
return 301 https://$host$request_uri;
}
# Bloco HTTPS
server {
listen 443 ssl;
http2 on;
server_name meusite.com.br;
ssl_certificate /etc/nginx/ssl/meusite.com.br.crt;
ssl_certificate_key /etc/nginx/ssl/meusite.com.br.key;
include /etc/nginx/snippets/ssl_params.conf;
location / {
proxy_pass http://meu_backend;
include /etc/nginx/includes/proxy_backend.conf;
}
}
```
2. **Aplique as alterações**:
```bash
docker compose restart nginx-proxy
```
*No reinício, o script de pre-flight validará o DNS e injetará configurações de SSL necessárias.*
### 3. Modificar Configurações Globais
As configurações globais são modularizadas na pasta `snippets/`.
- **Rate Limiting**: Edite `snippets/rate_limit.conf` para ajustar os limites de requisições por segundo.
- **Bloqueio de Bots**: Edite `snippets/security_maps.conf` para adicionar novos User-Agents à lista negra.
- **Cache**: Edite `snippets/cache_zones.conf` para definir novas zonas ou tempos de cache.
### 3.1. Modificar Regras do WAF (ModSecurity)
O WAF agora utiliza uma estrutura modular de regras localizada na pasta `modsec_rules/`.
- **Arquivos Específicos**: Regras para Gitea, Nextcloud, Exchange, Zabbix, etc. ficam em seus respectivos arquivos `.conf`.
- **Global**: `global-exceptions.conf` contém apenas whitelists de rede interna.
- **Aplicação**: Após editar qualquer regra, reinicie o container do WAF para aplicar:
```bash
docker compose restart modsecurity
```
> **Nota Técnica**: O arquivo `modsec.conf.template` na raiz é injetado no container durante o boot para contornar problemas de permissão e garantir o carregamento das regras customizadas.
### 4. Gerenciar Certificados SSL
O sistema gerencia isso automaticamente, mas você pode intervir manualmente se necessário.
- **Verificar Validade**:
Verifique os logs do startup para ver o status de todos os domínios:
```bash
docker compose logs nginx-proxy | grep "SSL"
```
- **Forçar Renovação**:
Se precisar renovar um certificado imediatamente:
```bash
docker compose exec nginx-proxy /scripts/renew_ssl.sh
```
- **Reload sem Downtime (Recomendado)**:
Para aplicar alterações de configuração (vhosts, SSL) sem derrubar conexões ativas:
```bash
./scripts/reload.sh
```
### 5. Monitorar e Debugar
- **Verificar Status dos Containers**:
```bash
docker compose ps
```
- **Ver Logs em Tempo Real**:
```bash
docker compose logs -f
```
- **Verificar se o WAF (ModSecurity) bloqueou algo**:
```bash
docker compose logs modsecurity | grep "Access denied"
```
- **Verificar Banimentos do Fail2ban**:
```bash
docker compose exec fail2ban fail2ban-client status nginx-badbots
```
--- ---
## 🏗️ Visão Geral da Stack ## 🔐 Gestão de SSL (Let's Encrypt)
```mermaid O Pathfinder Proxy usa o desafio **HTTP-01** via snippet `acme_challenge.conf`. Isso permite emitir certificados sem parar o Nginx.
graph TD
subgraph Internet
Client[Cliente Externo]
end
subgraph Host["Host Docker (Portainer)"] ### Emissão do Primeiro Certificado
subgraph PathfinderStack["Stack: Pathfinder-Proxy<br/>Rede: 172.112.0.0/16"] Rode os comandos abaixo (substitua o domínio):
WAF["ModSecurity WAF<br/>172.112.0.3<br/>:80, :443"]
NGINX["nginx-proxy<br/>172.112.0.2<br/>:8080 interno"]
F2B["fail2ban<br/>network: host"]
end
subgraph HostNetwork["Rede Física do Host"] 1. **Criar pasta de desafios (se não existir):**
HostIP["host.docker.internal<br/>(gateway)"] ```bash
end sudo mkdir -p /var/lib/letsencrypt && sudo chown www-data:www-data /var/lib/letsencrypt
subgraph OtherStacks["Outras Stacks Docker"]
Container1["Container A<br/>172.111.0.x"]
Container2["Container B<br/>172.113.0.x"]
end
end
subgraph ExternalServers["Servidores Externos"]
Server254["10.10.253.254"]
Server128["10.10.253.128<br/>Gitea"]
end
Client -->|":80/:443"| WAF
WAF -->|"proxy_pass :8080"| NGINX
F2B -.->|"lê logs"| WAF
F2B -.->|"lê logs"| NGINX
NGINX -->|"extra_hosts<br/>host-gateway"| HostIP
NGINX -.->|"bridge network"| Container1
NGINX -.->|"bridge network"| Container2
HostIP -->|"roteamento"| Server254
HostIP -->|"roteamento"| Server128
style WAF fill:#e74c3c,stroke:#c0392b,color:#fff
style NGINX fill:#3498db,stroke:#2980b9,color:#fff
style F2B fill:#27ae60,stroke:#1e8449,color:#fff
style Server128 fill:#9b59b6,stroke:#8e44ad,color:#fff
style Server254 fill:#9b59b6,stroke:#8e44ad,color:#fff
style HostIP fill:#f39c12,stroke:#d68910,color:#fff
style Container1 fill:#1abc9c,stroke:#16a085,color:#fff
style Container2 fill:#1abc9c,stroke:#16a085,color:#fff
``` ```
--- 2. **Gerar o certificado:**
```bash
sudo certbot certonly --webroot -w /var/lib/letsencrypt/ -d meusite.com.br -d www.meusite.com.br
```
## 📋 Sistemas e Servidores Configurados > [!TIP]
> **Atenção aos Caminhos:** Se o Certbot gerar uma pasta com final `-0001`, certifique-se de que o arquivo `.conf` do seu site em `/etc/nginx/conf.d/` aponta para o caminho exato gerado por ele. Você pode conferir os caminhos ativos com `sudo certbot certificates`.
Lista de todos os sistemas roteados pelo proxy, organizados por tipo de infraestrutura.
| Domínio | IP/Backend | Docker | VM | LXC | Descrição |
|---------|------------|:------:|:--:|:---:|-----------|
| `git.itguys.com.br` | 10.10.253.128 | ❌ | ❌ | ✅ | Gitea - Servidor Git |
| `zammad.itguys.com.br` | 172.16.254.59 | ❌ | ❌ | ✅ | Zammad - Helpdesk |
| `monitoramento.itguys.com.br` | 172.16.254.x | ❌ | ❌ | ✅ | Zabbix/Grafana |
| `mimir.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | Mimir - Métricas |
| `windmill.grupopralog.com.br` | 172.16.253.103:8000 | ❌ | ❌ | ✅ | Windmill - Automação |
| `katalog.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | Katalog |
| `verbocloud.itguys.com.br` | 172.16.253.13:11580 | ❌ | ❌ | ✅ | Nextcloud AIO |
| `cloud.grupopralog.com.br` | 172.16.253.12 | ❌ | ❌ | ✅ | Nextcloud Pralog |
| `srvoffice001.itguys.com.br` | 172.16.253.101 | ❌ | ✅ | ❌ | Exchange Server |
| `business.itguys.com.br` | 172.16.121.13 | ❌ | ✅ | ❌ | Exchange OWA |
| `vcenter.itguys.com.br` | 172.16.254.110:443 | ❌ | ✅ | ❌ | VMware vCenter |
| `unifi.itguys.com.br` | 172.16.254.123:8443 | ❌ | ✅ | ❌ | UniFi Controller |
| `workspace.itguys.com.br` | 172.16.121.2 | ❌ | ✅ | ❌ | Workspace Windows |
| `vscode.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | VS Code Server |
| `telefonia.itguys.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Central Telefônica |
| `proxy.itguys.com.br` | localhost | ✅ | ❌ | ❌ | Este proxy |
| `itguys.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Site Principal |
| `pralog.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Site Pralog |
| `anatram.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Site Anatram |
| `ferreirareal.com.br` | 172.16.x.x | ✅ | ❌ | ❌ | Site Ferreira Real |
| `petytransportes.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Site Pety Transportes |
| `solucionei.itguys.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Solucionei |
| `rhema.itguys.com.br` | 172.16.x.x | ❌ | ✅ | ❌ | Rhema |
| `integra.grupopralog.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | Integração Pralog |
| `ns1.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | DNS Primário |
| `ns2.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | DNS Secundário |
| `dns-primario.itguys.com.br` | 172.16.x.x | ❌ | ❌ | ✅ | DNS Admin |
> [!NOTE]
> **Legenda:** Docker = Container Docker | VM = Máquina Virtual (VMware/Hyper-V) | LXC = Linux Container (Proxmox)
>
> IPs marcados como `172.16.x.x` precisam ser verificados nos arquivos de configuração individuais.
--- ---
*Mantido por IT Guys* ## 🚀 Manutenção e Logs
### Recompilar WAF e Performance (Se necessário)
Se o Nginx for atualizado ou se precisar habilitar o Brotli, o módulo precisará ser recompilado usando o script:
`sudo ./scripts/setup_pathfinder.sh`
### Validação
Sempre teste a configuração antes do reload:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
### Auditoria e Diagnósticos
O Pathfinder agora reporta a **razão exata** do bloqueio nos logs JSON:
`tail -f /var/log/nginx/access_json.log | jq -r '"[\(.risk_category)] -> \(.risk_reason) | \(.request)"'`
- **`risk_category`**: TAG curta para máquinas (LIMPO, SUSPEITO, RISCO_ALTO, ATAQUE_CRITICO).
- **`risk_reason`**: Motivo humano detalhado (ex: "COMBINACAO: Bot conhecido em local sensivel").
---

49
TODO.md
View File

@ -1,49 +0,0 @@
# 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."

View File

@ -1,88 +0,0 @@
# ==============================================================================
# ARQUIVO: /etc/nginx/sites-available/gps.oestepan.com.br.conf
# AUTOR: Gemini (Especialista NGINX)
# DATA: 27/01/2026
#
# CONTEXTO:
# Proxy Reverso para Traccar GPS (OESTEPAN).
# ModSecurity (WAF) termina o SSL e envia tráfego descriptografado para a porta 8080.
# ==============================================================================
upstream traccar_backend {
server host.docker.internal:8083;
keepalive 32;
}
# ------------------------------------------------------------------------------
# BLOCO PRINCIPAL: Porta 8080 (Tráfego vindo do ModSecurity)
# ------------------------------------------------------------------------------
server {
listen 8080;
listen [::]:8080;
server_name gps.oestepan.com.br;
include /etc/nginx/snippets/acme_challenge.conf;
limit_req zone=global_limit burst=20 nodelay;
# ============================================================================
# LOGS
# ============================================================================
client_max_body_size 50M;
access_log /var/log/nginx/gps.oestepan.com.br.access.log detailed_proxy;
error_log /var/log/nginx/gps.oestepan.com.br.error.log warn;
# ============================================================================
# ROTAS (Sem SSL pois o WAF já terminou a encriptação)
# ============================================================================
# 1. WebSocket
location /api/socket {
proxy_pass http://traccar_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https; # Informa ao backend que é HTTPS
}
# 2. Rota Principal
location / {
proxy_pass http://traccar_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https; # Informa ao backend que é HTTPS
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 90s;
}
}
# ------------------------------------------------------------------------------
# BLOCO DUMMY: Apenas para que o script renew_ssl.sh encontre os caminhos do SSL
# ------------------------------------------------------------------------------
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name gps.oestepan.com.br;
# Important: These paths MUST be in /etc/nginx/ssl/ (shared volume)
# so ModSecurity can access them. renew_ssl.sh will copy the certs here.
ssl_certificate /etc/nginx/ssl/gps.oestepan.com.br.fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/gps.oestepan.com.br.privkey.pem;
# Retorna 444 (No Response) se alguém tentar conectar direto (bypass WAF)
location / {
return 444;
}
}

View File

@ -1,12 +0,0 @@
# Internal Networks Configuration
# Define internal network ranges for access control
# Allow access from internal networks
allow 10.10.0.0/16;
allow 10.11.0.0/16;
allow 10.12.0.0/16;
allow 172.16.0.0/16;
allow 127.0.0.1;
# Deny all others (uncomment if needed)
# deny all;

View File

@ -1,75 +0,0 @@
# Original of the latest recommended version:
# https://github.com/owasp-modsecurity/ModSecurity/blob/v3/master/modsecurity.conf-recommended
# Directives configured upstream (in the same order)
SecRuleEngine ${MODSEC_RULE_ENGINE}
SecRequestBodyAccess ${MODSEC_REQ_BODY_ACCESS}
SecRequestBodyLimit ${MODSEC_REQ_BODY_LIMIT}
SecRequestBodyNoFilesLimit ${MODSEC_REQ_BODY_NOFILES_LIMIT}
SecRequestBodyLimitAction ${MODSEC_REQ_BODY_LIMIT_ACTION}
SecRequestBodyJsonDepthLimit ${MODSEC_REQ_BODY_JSON_DEPTH_LIMIT}
SecArgumentsLimit ${MODSEC_ARGUMENTS_LIMIT}
SecPcreMatchLimit ${MODSEC_PCRE_MATCH_LIMIT}
SecPcreMatchLimitRecursion ${MODSEC_PCRE_MATCH_LIMIT_RECURSION}
SecResponseBodyAccess ${MODSEC_RESP_BODY_ACCESS}
SecResponseBodyMimeType ${MODSEC_RESP_BODY_MIMETYPE}
SecResponseBodyLimit ${MODSEC_RESP_BODY_LIMIT}
SecResponseBodyLimitAction ${MODSEC_RESP_BODY_LIMIT_ACTION}
SecTmpDir ${MODSEC_TMP_DIR}
SecDataDir ${MODSEC_DATA_DIR}
SecAuditEngine ${MODSEC_AUDIT_ENGINE}
SecAuditLogRelevantStatus "${MODSEC_AUDIT_LOG_RELEVANT_STATUS}"
SecAuditLogParts ${MODSEC_AUDIT_LOG_PARTS}
SecAuditLogType ${MODSEC_AUDIT_LOG_TYPE}
SecAuditLog ${MODSEC_AUDIT_LOG}
SecArgumentSeparator ${MODSEC_ARGUMENT_SEPARATOR}
SecCookieFormat ${MODSEC_COOKIE_FORMAT}
# SecUnicodeMapFile unicode.mapping ${MODSEC_UNICODE_MAPPING}
SecStatusEngine ${MODSEC_STATUS_ENGINE}
# Additional directives
SecAuditLogFormat ${MODSEC_AUDIT_LOG_FORMAT}
SecAuditLogStorageDir ${MODSEC_AUDIT_STORAGE_DIR}
SecDebugLog ${MODSEC_DEBUG_LOG}
SecDebugLogLevel ${MODSEC_DEBUG_LOGLEVEL}
SecDisableBackendCompression ${MODSEC_DISABLE_BACKEND_COMPRESSION}
SecTmpSaveUploadedFiles ${MODSEC_TMP_SAVE_UPLOADED_FILES}
SecUploadDir ${MODSEC_UPLOAD_DIR}
SecUploadFileMode ${MODSEC_UPLOAD_FILE_MODE}
SecUploadKeepFiles ${MODSEC_UPLOAD_KEEP_FILES}
# Rules configured upstream (in the same order)
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRule &ARGS "@ge ${MODSEC_ARGUMENTS_LIMIT}" \
"id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2"
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,log,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
# Additional rules
SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \
"id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
# Gemini: Include Custom Rules
include /etc/nginx/custom_rules/*.conf

View File

@ -1,2 +0,0 @@
# Include all custom rules form legacy migration
include /etc/nginx/custom_rules/*.conf

View File

@ -1,15 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Microsoft Exchange (ATUALIZADO)
# --------------------------------------------------------------------------
# Exchange Protocols Whitelist
# --------------------------------------------------------------------------
# Whitelists standard Exchange 2016/2019 paths to prevent WAF blocking
# essential email and admin functionality.
SecRule REQUEST_URI "@rx ^/(owa|ecp|Microsoft-Server-ActiveSync|EWS|OAB|Autodiscover|rpc|mapi)/" \
"id:10006, \
phase:1, \
pass, \
nolog, \
ctl:ruleEngine=Off, \
msg:'WHITELIST: Microsoft Exchange Services'"

View File

@ -1,45 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Gitea (ATUALIZADO)
# --------------------------------------------------------------------------
# Git Operations & Web Interface
# --------------------------------------------------------------------------
# ID 10008: Permitir operacoes de edição na UI
SecRule REQUEST_URI "@rx ^/.*/(src/branch|_edit|_new|commits/branch)/" \
"id:10008,phase:1,nolog,allow,ctl:ruleEngine=Off"
# ID 10011: Permitir acesso a assets e raw files
SecRule REQUEST_URI "@rx ^/.*/.*(raw|assets)/" \
"id:10011,phase:1,nolog,pass,ctl:ruleEngine=Off"
# ID 10013: Permitir acesso a arquivos .conf (git repos)
SecRule REQUEST_FILENAME "@rx \.conf$" \
"id:10013,phase:1,nolog,pass,chain,msg:'[CUSTOM] Whitelist .conf files for Git server'"
SecRule SERVER_NAME "@streq git.itguys.com.br" "ctl:ruleRemoveById=930120"
# ID 10025: Upload de Arquivos na UI
SecRule REQUEST_URI "@rx ^/[^/]+/[^/]+/upload-file$" \
"id:10025,phase:1,pass,nolog,ctl:ruleEngine=Off"
# ID 10026: Wiki
SecRule REQUEST_URI "@rx ^/[^/]+/[^/]+/wiki$" \
"id:10026,phase:1,pass,nolog,ctl:ruleEngine=Off"
# --------------------------------------------------------------------------
# Git Hooks & Uploads
# --------------------------------------------------------------------------
# ID 10040: Git Smart Protocol (Push/Pull)
# Disables rule engine and INCREASES request body limit for git-receive-pack (Push)
# to allow large uploads.
SecRule REQUEST_URI "@rx /git-(upload|receive)-pack$" \
"id:10040, \
phase:1, \
pass, \
nolog, \
ctl:ruleEngine=Off, \
ctl:requestBodyAccess=Off"
# ID 10041: Permitir LFS (Large File Storage) e Uploads via HTTP
SecRule REQUEST_URI "@rx /(info/lfs|objects/batch)" \
"id:10041,phase:1,pass,nolog,ctl:ruleEngine=Off"

View File

@ -1,14 +0,0 @@
# ==========================================================================
# Arquivo Global de Exceções do ModSecurity
# ==========================================================================
# Este arquivo contém apenas regras genéricas ou de infraestrutura.
# Regras específicas de aplicações estão em arquivos separados.
# WHITELIST: Acesso permitido da rede interna, ModSecurity desativado
SecRule REMOTE_ADDR "@ipMatch 172.16.0.0/16,10.10.0.0/16,10.11.0.0/16,10.12.0.0/16" \
"id:10000, \
phase:1, \
pass, \
nolog, \
ctl:ruleEngine=Off, \
msg:'WHITELIST: Acesso permitido da rede interna, ModSecurity desativado'"

View File

@ -1,5 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Grafana
# ID 10009: Whitelist Grafana Dashboard API
SecRule REQUEST_URI "@beginsWith /api/dashboards/" \
"id:10009,phase:1,pass,nolog,allow,ctl:ruleRemoveById=9XXXXX"

View File

@ -1,30 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Nextcloud (ATUALIZADO)
# --------------------------------------------------------------------------
# Broad API & Extension Whitelist (User Request: "Liberate all APIs")
# --------------------------------------------------------------------------
# Allows /apps/, /ocs/ (Open Cloud Standard), and /remote.php (WebDAV)
# to ensure plugins and sync clients work without restriction.
SecRule REQUEST_URI "@rx ^/(index\.php/apps|apps|ocs|remote\.php)/" \
"id:10050,phase:1,pass,nolog,ctl:ruleEngine=Off"
# --------------------------------------------------------------------------
# Office Online (WOPI & Hosting)
# --------------------------------------------------------------------------
# Whitelist for Office Online server communication
SecRule REQUEST_URI "@rx ^/(hosting|op|we|wv|p|x|lo|m|o|browser)/" \
"id:10014,phase:1,pass,nolog,ctl:ruleEngine=Off"
# Proxy Whitelist for Office Online (Internal)
SecRule REMOTE_ADDR "@ipMatch 172.16.254.1" \
"id:10034,phase:1,pass,nolog,chain,msg:'WHITELIST: [Proxy 172.16.254.1] Office Online WOPI'"
SecRule REQUEST_URI "@beginsWith /index.php/apps/officeonline/wopi/files/" "ctl:ruleEngine=Off"
# --------------------------------------------------------------------------
# Specific Sync & Discovery (Legacy/Specific IDs reserved)
# --------------------------------------------------------------------------
SecRule REQUEST_URI "@streq /.well-known/caldav" "id:10002,phase:1,pass,nolog,ctl:ruleEngine=Off"
SecRule REQUEST_URI "@streq /.well-known/carddav" "id:10003,phase:1,pass,nolog,ctl:ruleEngine=Off"
# Preview Generator
SecRule REQUEST_URI "@beginsWith /index.php/core/preview" "id:10010,phase:1,pass,nolog,ctl:ruleRemoveById=9XXXXX"

View File

@ -1,22 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Zabbix (ATUALIZADO)
# --------------------------------------------------------------------------
# Zabbix Web Interface Protection
# --------------------------------------------------------------------------
# REMOVED: zabbix.php whitelist. The UI should be protected by WAF.
# REMOVED: api_jsonrpc.php whitelist. This should only be accessed via VPN
# (covered by Global Internal Network rule 10000).
# --------------------------------------------------------------------------
# Dashboard Noise Reduction
# --------------------------------------------------------------------------
# Allows jsrpc.php which handles some background AJAX for the dashboard.
# If this causes security concerns, it can be removed, but usually generates false positives.
SecRule REQUEST_URI "@streq /jsrpc.php" \
"id:10004,phase:1,pass,nolog,ctl:ruleEngine=Off"
# --------------------------------------------------------------------------
# Host Discovery
# --------------------------------------------------------------------------
SecRule REQUEST_URI "@beginsWith /zabbix/host_discovery.php" \
"id:10005,phase:1,pass,nolog,ctl:ruleRemoveById=9XXXXX,ctl:ruleRemoveById=9YYYYY"

View File

@ -1,5 +0,0 @@
# Ficheiro de Exceções do ModSecurity para o Zammad
# ID 10007: Whitelist Zammad API
SecRule REQUEST_URI "@beginsWith /api/v1/" \
"id:10007,phase:1,pass,nolog,allow,ctl:ruleRemoveById=9XXXXX"

View File

@ -1,46 +0,0 @@
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
load_module modules/ngx_http_headers_more_filter_module.so;
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 16384;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
server_tokens off;
proxy_headers_hash_bucket_size 512;
keepalive_timeout 65;
# SSL Session Cache
ssl_session_cache shared:SSL:60m;
# Include Snippets
# Include Snippets (Global HTTP context)
# Excludes acme_challenge.conf which is server-context only
include /etc/nginx/snippets/cache_zones.conf;
include /etc/nginx/snippets/log_formats.conf;
include /etc/nginx/snippets/rate_limit.conf;
include /etc/nginx/snippets/security_maps.conf;
# include /etc/nginx/snippets/custom_errors.conf; # Optional globally
# Global Fallback Logs
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log;
# Include Site Configurations
include /etc/nginx/conf.d/*.conf;
}

View File

@ -1,55 +0,0 @@
#!/bin/sh
# ==============================================================================
# SCRIPT: git_sync.sh
# AUTHOR: Gemini (Automated)
# PURPOSE: Pull latest changes from git and reload Nginx if successful
# CRON: Scheduled in pre-flight.sh
# ==============================================================================
REPO_DIR="/opt/repo"
# URL Encoded Password for 'o3!VV3H6qBg^rucv2UvF6mdK$NWyNj@3'
# ! = %21, ^ = %5E, $ = %24, @ = %40
GIT_USER="gitea-deploy"
GIT_PASS="o3%21VV3H6qBg%5Erucv2UvF6mdK%24NWyNj%403"
GIT_REPO="git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder.git"
BRANCH="producao"
GIT_URL="https://${GIT_USER}:${GIT_PASS}@${GIT_REPO}"
echo "[Git-Sync] $(date): Starting sync process..."
if [ ! -d "$REPO_DIR" ]; then
echo "[Git-Sync] ERROR: Repository directory $REPO_DIR does not exist."
exit 1
fi
# Trust the directory (fix for 'dubious ownership' in container)
git config --global --add safe.directory "$REPO_DIR"
cd "$REPO_DIR"
# Fetch and Pull
OUTPUT=$(git pull "$GIT_URL" "$BRANCH" 2>&1)
EXIT_CODE=$?
echo "[Git-Sync] Output: $OUTPUT"
if [ $EXIT_CODE -ne 0 ]; then
echo "[Git-Sync] ERROR: Git pull failed."
exit $EXIT_CODE
fi
if echo "$OUTPUT" | grep -q "Already up to date"; then
echo "[Git-Sync] No changes detected."
exit 0
else
echo "[Git-Sync] Changes detected. Validating Nginx config..."
if nginx -t; then
echo "[Git-Sync] Configuration valid. Reloading Nginx..."
nginx -s reload
echo "[Git-Sync] Reload successful."
else
echo "[Git-Sync] CRITICAL: Nginx configuration test failed! Not reloading."
exit 1
fi
fi

View File

@ -1,28 +0,0 @@
#!/bin/sh
# Inject ACME challenge snippet into all site configs
# Target: Server blocks listening on port 80
CONF_DIR="/etc/nginx/conf.d"
SNIPPET="include /etc/nginx/snippets/acme_challenge.conf;"
echo "[Inject-ACME] Starting injection..."
for conf in $CONF_DIR/*.conf; do
[ -e "$conf" ] || continue
# Check if already injected
if grep -q "acme_challenge.conf" "$conf"; then
echo "[Inject-ACME] Skipping $conf (already has ACME snippet)"
continue
fi
echo "[Inject-ACME] Injecting into $conf..."
# Logic: Insert snippet before 'return 301' or inside 'listen 80' block
# Simplest reliable way with sed: match "listen 80;" and append snippet after it
# Note: Some configs might use "listen 80;" or "listen [::]:80;" or "listen 80 default_server;"
sed -i '/listen 80.*;/a \ '"$SNIPPET" "$conf"
done
echo "[Inject-ACME] Injection complete."

View File

@ -1,111 +0,0 @@
#!/bin/sh
set -e
echo "[Pre-Flight] Starting checks..."
# Check environment
if [ -z "$HOST_PUBLIC_IP" ]; then
echo "[Pre-Flight] WARNING: HOST_PUBLIC_IP not set. DNS checks might be inaccurate."
fi
# Iterate site configs for DNS checks
for conf in /etc/nginx/conf.d/*.conf; do
[ -e "$conf" ] || continue
echo "[Pre-Flight] Checking config: $conf"
# Simple extraction of server_name (naive, but works for standard configs)
DOMAINS=$(grep -E "^\s*server_name\s+" "$conf" | sed -r 's/.*server_name\s+(.*);/\1/')
for domain in $DOMAINS; do
if [ "$domain" = "_" ] || [ "$domain" = "localhost" ]; then continue; fi
echo "[Pre-Flight] Validating DNS for $domain..."
RESOLVED_IP=$(dig +short "$domain" @1.1.1.1 | tail -n 1)
if [ "$RESOLVED_IP" != "$HOST_PUBLIC_IP" ]; then
echo "[Pre-Flight] WARNING: Domain $domain resolves to $RESOLVED_IP, expected $HOST_PUBLIC_IP"
else
echo "[Pre-Flight] DNS OK: $domain -> $RESOLVED_IP"
fi
done
done
# Run SSL Renewal Check (handles its own iteration)
echo "[Pre-Flight] Running SSL renewal check..."
/scripts/renew_ssl.sh
# Setup Daily Cron for Renewal (run at 01:00)
# ==============================================================================
# GIT SYNC & DYNAMIC CONFIG SETUP
# ==============================================================================
REPO_DIR="/opt/repo"
GIT_USER="gitea-deploy"
GIT_PASS="o3%21VV3H6qBg%5Erucv2UvF6mdK%24NWyNj%403"
GIT_REPO="git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder.git"
GIT_URL="https://${GIT_USER}:${GIT_PASS}@${GIT_REPO}"
echo "[Pre-Flight] Checking repository at $REPO_DIR..."
if [ ! -d "$REPO_DIR/.git" ]; then
echo "[Pre-Flight] Repository not found. Cloning..."
# Ensure dir exists
mkdir -p "$REPO_DIR"
# Clone
git clone "$GIT_URL" "$REPO_DIR"
else
echo "[Pre-Flight] Repository exists. Pulling latest..."
cd "$REPO_DIR"
git config --global --add safe.directory "$REPO_DIR"
# Attempt pull, if fails (lock file or corruption), wipe and re-clone
if ! git pull; then
echo "[Pre-Flight] ERROR: Git pull failed (likely corrupt ref/lock). Re-cloning..."
# If REPO_DIR is a mountpoint, we cannot remove it. We must empty it.
# find is safer than globbing for hidden files
find "$REPO_DIR" -mindepth 1 -delete
git clone "$GIT_URL" "$REPO_DIR"
fi
fi
# SYMLINK SETUP
# We want Nginx to use the configs from the repo (dynamic) instead of the baked-in ones (static).
echo "[Pre-Flight] Setting up symlinks..."
# 1. conf.d (Sites)
if [ -d "$REPO_DIR/conf.d" ]; then
echo "[Pre-Flight] Linking conf.d..."
rm -rf /etc/nginx/conf.d
ln -s "$REPO_DIR/conf.d" /etc/nginx/conf.d
fi
# 2. snippets (Optional, but good for consistency)
if [ -d "$REPO_DIR/snippets" ]; then
echo "[Pre-Flight] Linking snippets..."
rm -rf /etc/nginx/snippets
ln -s "$REPO_DIR/snippets" /etc/nginx/snippets
fi
# 3. ModSecurity Rules (Optional)
if [ -d "$REPO_DIR/modsec_rules" ]; then
echo "[Pre-Flight] Linking modsec_rules..."
rm -rf /etc/nginx/custom_rules
ln -s "$REPO_DIR/modsec_rules" /etc/nginx/custom_rules
fi
# Setup Daily Cron for Renewal (run at 01:00)
echo "0 1 * * * /scripts/renew_ssl.sh >> /var/log/nginx/ssl_renew.log 2>&1" >> /etc/crontabs/root
# Setup Git Sync Cron (Run every 5 minutes)
echo "*/5 * * * * /scripts/git_sync.sh >> /var/log/nginx/git_sync.log 2>&1" >> /etc/crontabs/root
# Start Crond in background
crond -b -l 8
echo "[Pre-Flight] Checks complete. Starting NGINX..."
# Background: Trigger SSL renewal again in 60s
# This catches the fresh snakeoil certs (1 day expire) and renews them using the NOW RUNNING Nginx.
(sleep 60 && /scripts/renew_ssl.sh >> /var/log/nginx/ssl_bootstrap.log 2>&1) &
exec "$@"

View File

@ -1,24 +0,0 @@
$ContainerName = "nginx-proxy"
Write-Host "[Reload] Checking configuration in $ContainerName..." -ForegroundColor Cyan
# 1. Validate Configuration
docker exec $ContainerName nginx -t
if ($LASTEXITCODE -eq 0) {
Write-Host "[Reload] Configuration is VALID." -ForegroundColor Green
# 2. Graceful Reload
Write-Host "[Reload] Triggering graceful reload..." -ForegroundColor Cyan
docker exec $ContainerName nginx -s reload
if ($LASTEXITCODE -eq 0) {
Write-Host "[Reload] ✅ Reload signal sent successfully." -ForegroundColor Green
Write-Host "[Reload] Zero-downtime update in progress." -ForegroundColor Green
} else {
Write-Host "[Reload] ❌ Failed to send reload signal." -ForegroundColor Red
exit 1
}
} else {
Write-Host "[Reload] ❌ Configuration is INVALID. Aborting reload." -ForegroundColor Red
exit 1
}

View File

@ -1,26 +0,0 @@
#!/bin/bash
# Zero-Downtime Reload Script
# Validates config first, then reloads NGINX gracefully.
CONTAINER_NAME="nginx-proxy"
echo "[Reload] Checking configuration in $CONTAINER_NAME..."
# 1. Validate Configuration (nginx -t)
if docker exec "$CONTAINER_NAME" nginx -t; then
echo "[Reload] Configuration is VALID."
else
echo "[Reload] ❌ Configuration is INVALID. Aborting reload."
exit 1
fi
# 2. Graceful Reload (nginx -s reload)
# This starts new workers with new config, while old workers finish requests.
echo "[Reload] Triggering graceful reload..."
if docker exec "$CONTAINER_NAME" nginx -s reload; then
echo "[Reload] ✅ Reload signal sent successfully."
echo "[Reload] Zero-downtime update in progress."
else
echo "[Reload] ❌ Failed to send reload signal."
exit 1
fi

View File

@ -1,105 +0,0 @@
#!/bin/sh
# SSL Renewal Script
# Checks expiry and attempts renewal if < 3 days
echo "[SSL-Renew] Starting check at $(date)..."
# Ensure ACME snippet is present (idempotent)
/scripts/inject_acme.sh
# Iterate configs to find certs
for conf in /etc/nginx/conf.d/*.conf; do
[ -e "$conf" ] || continue
# Extract Cert File
CRT_FILE=$(grep -E "\s*ssl_certificate\s+" "$conf" | sed -r 's/.*ssl_certificate\s+(.*);/\1/' | head -n 1)
# Extract Server Name for Certbot
DOMAIN=$(grep -E "\s*server_name\s+" "$conf" | sed -r 's/.*server_name\s+(.*);/\1/' | head -n 1)
# Validation: Skip configs without SSL or Domain
if [ -z "$CRT_FILE" ] || [ -z "$DOMAIN" ]; then
# echo "[SSL-Renew] Skipping $conf (No SSL/Domain found)"
continue
fi
if [ -f "$CRT_FILE" ]; then
# Check if cert expires in the next 3 days (259200 seconds)
# openssl -checkend returns 0 if valid for the duration, 1 if expires
if openssl x509 -checkend 259200 -noout -in "$CRT_FILE" > /dev/null; then
echo "[SSL-Renew] Cert for $DOMAIN is valid."
else
echo "[SSL-Renew] WARNING: Cert for $DOMAIN expires soon (or is invalid)!"
echo "[SSL-Renew] Attempting renewal via Certbot..."
# Attempt non-interactive renewal
certbot certonly --webroot -w /var/www/certbot \
-d "$DOMAIN" \
--email suporte@itguys.com.br \
--agree-tos \
--no-eff-email \
--non-interactive \
--keep-until-expiring
if [ $? -eq 0 ]; then
echo "[SSL-Renew] Certbot success. Updating symlinks/files..."
LE_CERT="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
LE_KEY="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
if [ -f "$LE_CERT" ]; then
cp "$LE_CERT" "$CRT_FILE"
chmod 644 "$CRT_FILE"
# Key file assumption: usually same name but .key/privkey.pem
KEY_FILE=$(grep -E "\s*ssl_certificate_key\s+" "$conf" | sed -r 's/.*ssl_certificate_key\s+(.*);/\1/' | head -n 1)
if [ -f "$KEY_FILE" ]; then
# If key path is found, copy it
cp "$LE_KEY" "$KEY_FILE"
chmod 644 "$KEY_FILE"
else
# Fallback: try to derive key path from cert path if variable is empty
# (This handles edge cases where parsing failed but cert existed)
echo "[SSL-Renew] Warning: Could not parse ssl_certificate_key from config."
fi
echo "[SSL-Renew] Files updated. Queuing NGINX reload."
RELOAD_NEEDED=1
fi
else
echo "[SSL-Renew] Certbot failed for $DOMAIN."
fi
fi
else
echo "[SSL-Renew] CRT Not Found for $DOMAIN. Generating Self-Signed Bootstrap Cert..."
# Ensure dir exists
mkdir -p "$(dirname "$CRT_FILE")"
KEY_FILE=$(grep -E "\s*ssl_certificate_key\s+" "$conf" | sed -r 's/.*ssl_certificate_key\s+(.*);/\1/' | head -n 1)
if [ -z "$KEY_FILE" ]; then
echo "[SSL-Renew] Error: Cannot determine key file path for bootstrap. Skipping."
continue
fi
mkdir -p "$(dirname "$KEY_FILE")"
# Generate minimal self-signed cert valid for 1 day (forces renewal next run)
openssl req -x509 -nodes -days 1 -newkey rsa:2048 \
-keyout "$KEY_FILE" \
-out "$CRT_FILE" \
-subj "/C=BR/ST=SP/L=Bootstrap/O=ITGuys/CN=$DOMAIN"
chmod 644 "$KEY_FILE" "$CRT_FILE"
echo "[SSL-Renew] Bootstrap Cert created. Nginx should be able to start."
fi
done
if [ "$RELOAD_NEEDED" = "1" ]; then
echo "[SSL-Renew] Reloading NGINX..."
nginx -s reload
fi
echo "[SSL-Renew] Check complete."

View File

@ -1,9 +0,0 @@
# ACME Challenge Snippet
# Include this in port 80 server blocks to allow Certbot validation
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
try_files $uri =404;
allow all;
auth_basic off;
}

View File

@ -1,33 +0,0 @@
# Cache Zone Definitions
# Include this file in nginx.conf http block
# General caches
proxy_cache_path /var/cache/nginx/static_cache levels=1:2 keys_zone=static_cache:10m max_size=2g inactive=90d use_temp_path=off;
proxy_cache_path /var/cache/nginx/api_cache levels=1:2 keys_zone=api_cache:10m max_size=100m inactive=5m use_temp_path=off;
# Site-specific caches
proxy_cache_path /var/cache/nginx/itguys_cache levels=1:2 keys_zone=itguys_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/business_cache levels=1:2 keys_zone=business_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/gitea_cache levels=1:2 keys_zone=gitea_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/zammad_cache levels=1:2 keys_zone=zammad_cache:10m max_size=500m inactive=60m use_temp_path=off;
proxy_cache_path /var/cache/nginx/grafana_cache levels=1:2 keys_zone=grafana_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/unifi_cache levels=1:2 keys_zone=unifi_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/workspace_cache levels=1:2 keys_zone=workspace_cache:10m max_size=1g inactive=60m use_temp_path=off;
proxy_cache_path /var/cache/nginx/solucionei_cache levels=1:2 keys_zone=solucionei_cache:20m max_size=2g inactive=90d use_temp_path=off;
proxy_cache_path /var/cache/nginx/rhema_cache levels=1:2 keys_zone=rhema_cache:20m max_size=2g inactive=90d use_temp_path=off;
proxy_cache_path /var/cache/nginx/vcenter_cache levels=1:2 keys_zone=vcenter_cache:10m max_size=1g inactive=60m use_temp_path=off;
proxy_cache_path /var/cache/nginx/ferreirareal_cache levels=1:2 keys_zone=ferreirareal_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/snipeit_cache levels=1:2 keys_zone=snipeit_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/technitium_cache levels=1:2 keys_zone=technitium_cache:10m inactive=60m max_size=1g;
proxy_cache_path /var/cache/nginx/magnusbilling_cache levels=1:2 keys_zone=magnusbilling_cache:10m max_size=1g inactive=7d use_temp_path=off;
# Nextcloud caches
proxy_cache_path /var/cache/nginx/nextcloud_private_cache levels=1:2 keys_zone=nextcloud_private_cache:20m max_size=1g inactive=15m use_temp_path=off;
proxy_cache_path /var/cache/nginx/nextcloud_previews_cache levels=1:2 keys_zone=nextcloud_previews:20m max_size=2g inactive=7d use_temp_path=off;
proxy_cache_path /var/cache/nginx/nextcloud_cache_grupopralog levels=1:2 keys_zone=nextcloud_cache:120m max_size=10g inactive=6h use_temp_path=off;
proxy_cache_path /var/cache/nginx/nextcloud_session_cache levels=1:2 keys_zone=nextcloud_session_cache:50m max_size=500m inactive=30m use_temp_path=off;
proxy_cache_path /var/cache/nginx/foldertree_cache keys_zone=foldertree_cache:10m levels=1:2 inactive=1m max_size=100m;
# Exchange/Zabbix caches
proxy_cache_path /var/cache/nginx/zabbix_cache levels=1:2 keys_zone=zabbix_cache:10m max_size=1g inactive=60m use_temp_path=off;
proxy_cache_path /var/cache/nginx/exchange_private_cache levels=1:2 keys_zone=exchange_private_cache:20m max_size=500m inactive=10m use_temp_path=off;

View File

@ -1,11 +0,0 @@
# Custom Error Pages Snippet
# Include this file INSIDE a server block
# Custom error pages
error_page 502 @error_502;
error_page 503 @error_503;
error_page 504 @error_504;
# Named locations for error handling
# These should be defined in the server block, not here
# The including site config should define its own error handling locations

View File

@ -1,11 +0,0 @@
# Docker DNS Resolver
# Use dentro de location blocks quando precisar resolver
# nomes de containers dinamicamente (ex: com variáveis)
#
# Uso:
# set $backend "container-name:port";
# include /etc/nginx/snippets/docker_resolver.conf;
# proxy_pass http://$backend;
resolver 127.0.0.11 valid=30s ipv6=off;
resolver_timeout 5s;

View File

@ -1,77 +0,0 @@
# Log Format Definitions
# Include this file in nginx.conf http block
log_format detailed_proxy escape=json
'{'
# Timestamps e Identificadores
'"@timestamp":"$time_iso8601",'
'"time_local":"$time_local",'
'"msec":"$msec",'
'"request_id":"$request_id",'
'"hostname":"$hostname",'
'"worker_pid":$pid,'
# Informações de Conexão e Cliente
'"remote_addr":"$remote_addr",'
'"remote_port":$remote_port,'
'"server_addr":"$server_addr",'
'"server_port":"$server_port",'
'"real_ip":"$http_x_forwarded_for",'
'"http_x_real_ip":"$http_x_real_ip",'
'"remote_user":"$remote_user",'
# Detalhes da Requisição HTTP
'"request":"$request",'
'"request_method":"$request_method",'
'"scheme":"$scheme",'
'"server_protocol":"$server_protocol",'
'"host_header":"$host",'
'"request_uri":"$request_uri",'
'"uri":"$uri",'
'"document_uri":"$document_uri",'
'"args":"$args",'
'"query_string":"$query_string",'
'"request_length":$request_length,'
# Headers da Requisição
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_accept_encoding":"$http_accept_encoding",'
'"http_accept_language":"$http_accept_language",'
# Detalhes da Resposta
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$bytes_sent,'
'"sent_http_content_type":"$sent_http_content_type",'
'"sent_http_cache_control":"$sent_http_cache_control",'
# Performance e Conexão
'"request_time":$request_time,'
'"connection":"$connection",'
'"connection_requests":$connection_requests,'
# SSL/TLS
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher",'
'"ssl_session_reused":"$ssl_session_reused",'
# Upstream
'"upstream_addr":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_connect_time":"$upstream_connect_time",'
'"upstream_header_time":"$upstream_header_time",'
'"upstream_response_time":"$upstream_response_time",'
'"upstream_cache_status":"$upstream_cache_status",'
# Compressão
'"compression_ratio":"$gzip_ratio",'
# Variáveis Customizadas
'"is_bad_bot":"$is_bad_bot",'
'"is_suspicious_uri":"$is_suspicious_uri",'
'"block_request":"$block_request",'
'"is_internal_ip":"$is_internal"'
'}';
log_format suspicious_bot 'SUSPICIOUS_BOT: $remote_addr - "$http_user_agent" - "$request"';

View File

@ -1,6 +0,0 @@
# Rate Limit Zones
# Include this file in nginx.conf http block
# Smart rate limiting - excludes internal IPs
limit_req_zone $limit_key zone=global_limit:20m rate=10r/s;
limit_req_zone $bad_bot_key zone=bad_bot_limit:10m rate=5r/m;

View File

@ -1,49 +0,0 @@
# Security Maps and Variables
# Include this file in nginx.conf http block
# Bad Bot Detection
map $http_user_agent $is_bad_bot {
default 0;
~*(nikto|sqlmap|wpscan|gobuster|dirbuster|feroxbuster|nessus|nmap|curl) 1;
}
# Suspicious URI Detection
map $request_uri $is_suspicious_uri {
default 0;
~*(\.env|\.git|/vendor/|/setup\.php|/\.well-known/|/phpmyadmin|/config\.php|composer\.json) 1;
}
# Combined Block Request
map $is_bad_bot$is_suspicious_uri $block_request {
default 0;
~1 1;
}
# Internal IP Detection
geo $is_internal {
default 0;
10.10.0.0/16 1; 10.11.0.0/16 1; 10.12.0.0/16 1; 172.16.0.0/16 1;
45.169.73.155 1; 201.73.213.130 1; 177.74.160.17 1; 177.74.160.18 1;
177.74.160.19 1; 177.74.160.20 1; 177.74.160.21 1; 177.74.160.22 1;
177.74.160.23 1; 45.169.87.168 1; 45.169.87.169 1; 45.169.87.170 1;
45.169.87.171 1; 45.169.87.172 1; 45.169.87.173 1; 45.169.87.174 1;
45.169.87.175 1; 45.169.73.154 1; 201.73.213.129 1;
}
# Rate Limit Key (excludes internal IPs)
map $is_internal $limit_key {
0 $binary_remote_addr;
1 "";
}
# Bad Bot Rate Limit Key
map $is_bad_bot $bad_bot_key {
1 $binary_remote_addr;
default "";
}
# Cache Asset TTL
map $request_uri $cache_asset {
~*\.(css|js|mjs|svg|gif|png|jpg|jpeg|ico|wasm|woff|woff2|ttf|otf)$ 1y;
default off;
}

View File

@ -1,25 +0,0 @@
{
# 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
}
}

View File

@ -1,15 +0,0 @@
#!/bin/bash
set -e
echo "Deploying Caddy Proxy..."
# Pull latest code
git pull
# Ensure containers are up
docker compose up -d
# Force a reload just in case
docker compose exec caddy caddy reload
echo "Deployment Complete."

View File

@ -1,21 +0,0 @@
services:
caddy:
image: caddy:latest
container_name: proxy_caddy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy_core/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"
volumes:
caddy_data:
caddy_config:
caddy_logs:

View File

@ -0,0 +1,305 @@
# Configuration README
!! NOTICE !!
When using [linuxserver/fail2ban](https://github.com/linuxserver/docker-fail2ban), the `*.conf` files in this directory and its subdirectories will be replaced every time the container restarts. The files are meant to be easily viewed so that you can reference them.
If you would like to customize anything, create a `*.local` file with the same name as the `*.conf` file and apply your customizations. You do not need to copy the entire `*.conf` file to `*.local`, you only need to include things you want to change.
For example, to adjust `jail.conf`, create `jail.local` and apply your customizations there.
## File Parsing Order
Fail2ban will combine action configurations in the following order:
```text
action.d/*.conf (in alphabetical order)
action.d/*.local (in alphabetical order)
```
Fail2ban will combine filter configurations in the following order:
```text
filter.d/*.conf (in alphabetical order)
filter.d/*.local (in alphabetical order)
```
Fail2ban will combine jail configurations in the following order:
```text
jail.conf
jail.d/*.conf (in alphabetical order)
jail.local
jail.d/*.local (in alphabetical order)
```
## Chains
Chains affect how access is restricted. There are two primary ways to restrict access.
### `DOCKER-USER`
The `DOCKER-USER` chain is used to restrict access to applications running in Docker containers. This will restrict access to all containers, not just the one that the jail is configured for.
### `INPUT`
The `INPUT` chain is used to restrict access to applications running on the host. This will restrict access to the host network stack. The host network stack may not be inclusive of all Docker network stacks, thus the `DOCKER-USER` chain is used separately for applications running in Docker containers.
### `FORWARD` (for legacy versions of Docker)
The `FORWARD` chain may be used on systems running older versions of Docker where the `DOCKER-USER` chain is not available.
## `jail.local` Examples
These are examples of what you can do in your `jail.local`. There is no universally correct way to setup `jail.local` as it depends on your needs.
You can enable any of the pre-made jails by reviewing the files in `jail.d/` and adding a few lines to your `jail.local` to enable the jail.
### Basic Example
This example shows how to enable jails for sshd on the host, and SWAG (nginx) running in a container. It also includes some general recommendations and optional lines commented out.
In order for bans to work correctly, the `INPUT` chain should be used for applications running on the host, and the `DOCKER-USER` chain should be used for applications running in containers.
In this basic example:
- `sshd` expects ssh to be running on the host (not in a container), so the `INPUT` chain is used
- `nginx-http-auth` expects nginx to be running in a container (ex: SWAG), so the `DOCKER-USER` chain is used
```ini
[DEFAULT]
# Prevents banning LAN subnets
ignoreip = 127.0.0.1/8 ::1
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
# The ban action "iptables-multiport" (default) should work for most
# The ban action "iptables-allports" can be used if multiport causes issues
#banaction = %(banaction_allports)s
[sshd]
# configuration inherits from jail.conf
enabled = true
chain = INPUT
action = %(known/action)s
[nginx-http-auth]
# configuration inherits from jail.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
[nginx-badbots]
# configuration inherits from jail.d/nginx-badbots.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
[nginx-botsearch]
# configuration inherits from jail.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
[nginx-deny]
# configuration inherits from jail.d/nginx-deny.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
[nginx-unauthorized]
# configuration inherits from jail.d/nginx-unauthorized.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
```
### Incremental Banning
This example only includes the configurations for incremental banning. You can add these lines to the `[DEFAULT]` section of your existing config.
With these configurations, after an IP is unbanned, if it gets banned again the ban time will increase exponentially.
```ini
[DEFAULT]
# "bantime.increment" allows to use database for searching of previously banned ip's to increase a
# default ban time
bantime.increment = true
# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
bantime.maxtime = 5w
# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier
bantime.factor = 24
# "bantime" is the number of seconds that a host is banned.
bantime = 1h
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 24h
# "maxretry" is the number of failures before a host get banned.
maxretry = 5
```
### unRAID
Add these lines to your `jail.local` to enable jails for unRAID's sshd and Web GUI.
The `port` line for the Web GUI is optional, but if you use unRAID's My Servers plugin to enable public access you should add the port you use (replace `YOUR-UNRAID-MY-SERVERS-WAN-PORT`)
Both of these jails protect unRAID at the host level using the `INPUT` chain.
```ini
[unraid-sshd]
# configuration inherits from jail.d/unraid-sshd.conf
enabled = true
chain = INPUT
action = %(known/action)s
[unraid-webgui]
# configuration inherits from jail.d/unraid-webgui.conf
enabled = true
chain = INPUT
port = http,https,YOUR-UNRAID-MY-SERVERS-WAN-PORT
action = %(known/action)s
```
### Unifi-Controller
Add these lines to enable the jail for Unifi-Controller.
```ini
[unifi-controller-auth]
# configuration inherits from jail.d/unifi-controller-auth.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
```
### Additional Actions
The default `action` will use `iptables` to perform bans. You may also apply bans using other services such as CloudFlare, report bans to services such as AbuseIPDB, or setup notifications for with services such as Apprise or Discord Webhooks.
```ini
[DEFAULT]
# Apply additional actions to all bans with all jails
action = %(action_)s
apprise-api[host="127.0.0.1", tag="fail2ban"]
cloudflare[cfuser="YOUR-EMAIL", cftoken="YOUR-TOKEN"]
discord-webhook[webhook="https://discord.com/api/webhooks/######/######"]
abuseipdb_apikey = YOUR-API-KEY
[sshd]
# Apply additional actions only to bans for the sshd jail
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,22"]
[unifi-controller-auth]
# Apply additional actions only to bans for the unifi-controller-auth jail
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,21"]
```
### Full Example
```ini
[DEFAULT]
# "bantime.increment" allows to use database for searching of previously banned ip's to increase a
# default ban time
bantime.increment = true
# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
bantime.maxtime = 5w
# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier
bantime.factor = 24
# "bantime" is the number of seconds that a host is banned.
bantime = 1h
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 24h
# "maxretry" is the number of failures before a host get banned.
maxretry = 5
# Prevents banning LAN subnets
ignoreip = 127.0.0.1/8 ::1
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
# The ban action "iptables-multiport" (default) should work for most
# The ban action "iptables-allports" can be used if multiport causes issues
#banaction = %(banaction_allports)s
# Read https://github.com/sebres/PoC/blob/master/FW.IDS-DROP-vs-REJECT/README.md before changing block type
# The block type "REJECT --reject-with icmp-port-unreachable" (default behavior) should respond to, but then instantly reject connection attempts
# The block type "DROP" should not respond to connection attempts, resulting in a timeout
#banaction = iptables-multiport[blocktype=DROP]
# Add additional actions
action = %(action_)s
apprise-api[host="127.0.0.1", tag="fail2ban"]
cloudflare[cfuser="YOUR-EMAIL", cftoken="YOUR-TOKEN"]
abuseipdb_apikey = YOUR-API-KEY
[unraid-sshd]
# configuration inherits from jail.d/unraid-sshd.conf
enabled = true
chain = INPUT
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,22"]
[unraid-webgui]
# configuration inherits from jail.d/unraid-webgui.conf
enabled = true
chain = INPUT
port = http,https,YOUR-UNRAID-MY-SERVERS-WAN-PORT
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,21"]
[unifi-controller-auth]
# configuration inherits from jail.d/unifi-controller-auth.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,21"]
[vaultwarden-auth]
# configuration inherits from jail.d/vaultwarden-auth.conf
enabled = true
chain = DOCKER-USER
action = %(known/action)s
abuseipdb[abuseipdb_apikey="%(abuseipdb_apikey)s", abuseipdb_category="18,21"]
```
## Customizing jails
You can customize additional aspects about a jail by modifying your `jail.local` file.
```ini
[unifi-controller-auth]
# configuration inherits from jail.d/unifi-controller-auth.conf
enabled = true
# If you are using non-standard ports for your unifi-controller, you can specify the ports you use
port = 8081,8442
# If your log file is mounted to a non-standard location inside the container, you can specify the path that the container will see your log file
logpath = /path/to/unificontroller/server.log
# If you are running the unifi-controller on your host (not in a docker container) you can change the chain to INPUT
#chain = INPUT
# If you are running the unifi-controller in a docker container you can change the chain to DOCKER-USER
#chain = DOCKER-USER
```

View File

@ -0,0 +1,105 @@
## Version 2024/05/20
# Fail2ban configuration file
#
# Action to report IP address to abuseipdb.com
# You must sign up to obtain an API key from abuseipdb.com.
#
# NOTE: These reports may include sensitive Info.
# If you want cleaner reports that ensure no user data see the helper script at the below website.
#
# IMPORTANT:
#
# Reporting an IP of abuse is a serious complaint. Make sure that it is
# serious. Fail2ban developers and network owners recommend you only use this
# action for:
# * The recidive where the IP has been banned multiple times
# * Where maxretry has been set quite high, beyond the normal user typing
# password incorrectly.
# * For filters that have a low likelihood of receiving human errors
#
# This action relies on a api_key being added to the above action conf,
# and the appropriate categories set.
#
# Example, for ssh bruteforce (in section [sshd] of `jail.local`):
# action = %(known/action)s
# abuseipdb[abuseipdb_apikey="my-api-key", abuseipdb_category="18,22"]
#
# See below for categories.
#
# Added to fail2ban by Andrew James Collett (ajcollett)
## abuseIPDB Categories, `the abuseipdb_category` MUST be set in the jail.conf action call.
# Example, for ssh bruteforce: action = %(action_abuseipdb)s[abuseipdb_category="18,22"]
# ID Title Description
# 3 Fraud Orders
# 4 DDoS Attack
# 9 Open Proxy
# 10 Web Spam
# 11 Email Spam
# 14 Port Scan
# 18 Brute-Force
# 19 Bad Web Bot
# 20 Exploited Host
# 21 Web App Attack
# 22 SSH Secure Shell (SSH) abuse. Use this category in combination with more specific categories.
# 23 IoT Targeted
# See https://abuseipdb.com/categories for more descriptions
[Definition]
# bypass action for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
#
# ** IMPORTANT! **
#
# By default, this posts directly to AbuseIPDB's API, unfortunately
# this results in a lot of backslashes/escapes appearing in the
# reports. This also may include info like your hostname.
# If you have your own web server with PHP available, you can
# use my (Shaun's) helper PHP script by commenting out the first #actionban
# line below, uncommenting the second one, and pointing the URL at
# wherever you install the helper script. For the PHP helper script, see
# <https://github.com/parseword/fail2ban-abuseipdb/>
#
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = lgm=$(printf '%%.1000s\n...' "<matches>"); curl -sSf "https://api.abuseipdb.com/api/v2/report" -H "Accept: application/json" -H "Key: <abuseipdb_apikey>" --data-urlencode "comment=$lgm" --data-urlencode "ip=<ip>" --data "categories=<abuseipdb_category>"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Option: abuseipdb_apikey
# Notes Your API key from abuseipdb.com
# Values: STRING Default: None
# Register for abuseipdb [https://www.abuseipdb.com], get api key and set below.
# You will need to set the category in the action call.
abuseipdb_apikey =

View File

@ -0,0 +1,26 @@
## Version 2022/08/06
# Fail2Ban configuration file
# https://www.rfxn.com/projects/advanced-policy-firewall/
#
# Note: APF doesn't play nicely with other actions. It has been observed to
# remove bans created by other iptables based actions. If you are going to use
# this action, use it for all of your jails.
#
# DON'T MIX APF and other IPTABLES based actions
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = apf --deny <ip> "banned by Fail2Ban <name>"
actionunban = apf --remove <ip>
[Init]
# Name used in APF configuration
#
name = default
# DEV NOTES:
#
# Author: Mark McKinstry

View File

@ -0,0 +1,60 @@
## Version 2022/08/06
# Fail2Ban action configuration for apprise-api
# Author: Roxedus https://github.com/Roxedus
# Modified by: nemchik https://github.com/nemchik
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = curl -X POST -d '{"tag": "<tag>", "type": "info", "body": "The jail <name> as been started successfully."}' \
-H "Content-Type: application/json" \
<url>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = curl -X POST -d '{"tag": "<tag>", "type": "info", "body": "The jail <name> has been stopped."}' \
-H "Content-Type: application/json" \
<url>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl -X POST -d '{"tag": "<tag>", "type": "warning", "body": "The IP <ip> has just been banned from <name> after <failures> attempts."}' \
-H "Content-Type: application/json" \
<url>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = curl -X POST -d '{"tag": "<tag>", "type": "success", "body": "The IP <ip> has just been unbanned from <name>."}' \
-H "Content-Type: application/json" \
<url>
[Init]
proto = http
host = apprise
port = 8000
key = apprise
url = <proto>://<host>:<port>/notify/<key>
#tag = fail2ban
tag = all

View File

@ -0,0 +1,50 @@
## Version 2024/09/02
# Fail2Ban configuration file
#
# Author: Chris Caron <lead2gold@gmail.com>
#
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = printf %%b "The jail <name> has been started successfully." | <apprise> -t "[Fail2Ban] <name>: started on `uname -n`"
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = printf %%b "The jail <name> has been stopped." | <apprise> -t "[Fail2Ban] <name>: stopped on `uname -n`"
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>" | <apprise> -n "warning" -t "[Fail2Ban] <name>: banned <ip> from `uname -n`"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Define location of the default apprise configuration file to use
#
config = /etc/fail2ban/apprise.conf
#
apprise = apprise -c "<config>"

View File

@ -0,0 +1,88 @@
## Version 2019/06/29
# Fail2Ban configuration file
#
# Author: Steven Hiscocks
#
#
# Action to report IP address to blocklist.de
# Blocklist.de must be signed up to at www.blocklist.de
# Once registered, one or more servers can be added.
# This action requires the server 'email address' and the associated apikey.
#
# From blocklist.de:
# www.blocklist.de is a free and voluntary service provided by a
# Fraud/Abuse-specialist, whose servers are often attacked on SSH-,
# Mail-Login-, FTP-, Webserver- and other services.
# The mission is to report all attacks to the abuse departments of the
# infected PCs/servers to ensure that the responsible provider can inform
# the customer about the infection and disable them
#
# IMPORTANT:
#
# Reporting an IP of abuse is a serious complaint. Make sure that it is
# serious. Fail2ban developers and network owners recommend you only use this
# action for:
# * The recidive where the IP has been banned multiple times
# * Where maxretry has been set quite high, beyond the normal user typing
# password incorrectly.
# * For filters that have a low likelihood of receiving human errors
#
[Definition]
# bypass reporting of restored (already reported) tickets:
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl --fail --data-urlencode "server=<email>" --data "apikey=<apikey>" --data "service=<service>" --data "ip=<ip>" --data-urlencode "logs=<matches><br>" --data 'format=text' --user-agent "<agent>" "https://www.blocklist.de/en/httpreports.html"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
# Option: email
# Notes server email address, as per blocklist.de account
# Values: STRING Default: None
#
#email =
# Option: apikey
# Notes your user blocklist.de user account apikey
# Values: STRING Default: None
#
#apikey =
# Option: service
# Notes service name you are reporting on, typically aligns with filter name
# see http://www.blocklist.de/en/httpreports.html for full list
# Values: STRING Default: None
#
#service =

View File

@ -0,0 +1,95 @@
## Version 2023/11/18
# Fail2Ban configuration file
#
# Author: Nick Munger
# Modified by: Ken Menzel
# Daniel Black (start/stop)
# Fabian Wenk (many ideas as per fail2ban users list)
#
# Ensure firewall_enable="YES" in the top of /etc/rc.conf
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = ipfw show | fgrep -c -m 1 -s 'table(<table>)' > /dev/null 2>&1 || (
num=$(ipfw show | awk 'BEGIN { b = <lowest_rule_num> } { if ($1 == b) { b = $1 + 1 } } END { print b }');
ipfw -q add "$num" <blocktype> <block> from table\(<table>\) to me <port>; echo "$num" > "<startstatefile>"
)
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = [ ! -f <startstatefile> ] || ( read num < "<startstatefile>" <br> ipfw -q delete $num <br> rm "<startstatefile>" )
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
# requires an ipfw rule like "deny ip from table(1) to me"
actionban = e=`ipfw table <table> add <ip> 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XADD): File exists' ] || echo "$e" | grep -q "record already exists" || { echo "$e" 1>&2; exit $x; }
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = e=`ipfw table <table> delete <ip> 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XDEL): No such process' ] || echo "$e" | grep -q "record not found" || { echo "$e" 1>&2; exit $x; }
[Init]
# Option: table
# Notes: The ipfw table to use. If a ipfw rule using this table already exists,
# this action will not create a ipfw rule to block it and the following
# options will have no effect.
# Values: NUM
table = 1
# Option: port
# Notes.: Specifies port to monitor. Blank indicate block all ports.
# Values: [ NUM | STRING ]
#
port =
# Option: startstatefile
# Notes: A file to indicate that the table rule that was added. Ensure it is unique per table.
# Values: STRING
startstatefile = /var/run/fail2ban/ipfw-started-table_<table>
# Option: block
# Notes: This is how much to block.
# Can be "ip", "tcp", "udp" or various other options.
# Values: STRING
block = ip
# Option: blocktype
# Notes.: How to block the traffic. Use a action from man 5 ipfw
# Common values: deny, unreach port, reset
# ACTION definition at the top of man ipfw for allowed values.
# Values: STRING
#
blocktype = unreach port
# Option: lowest_rule_num
# Notes: When fail2ban starts with action and there is no rule for the given table yet
# then fail2ban will start looking for an empty slot starting with this rule number.
# Values: NUM
lowest_rule_num = 111

View File

@ -0,0 +1,94 @@
## Version 2025/03/01
#
# Author: Logic-32
#
# IMPORTANT
#
# Please set jail.local's permission to 640 because it contains your CF API token.
#
# This action depends on curl.
#
# To get your Cloudflare API token: https://developers.cloudflare.com/api/tokens/create/
#
# Cloudflare Firewall API: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/endpoints/
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
actionban = curl -s -X POST "<_cf_api_url>" \
<_cf_api_prms> \
--data '{"mode":"<cfmode>","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"<notes>"}'
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = id=$(curl -s -G -X GET "<_cf_api_url>" \
--data-urlencode "mode=<cfmode>" --data-urlencode "notes=<notes>" --data-urlencode "configuration.target=<cftarget>" --data-urlencode "configuration.value=<ip>" \
<_cf_api_prms> \
| awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' \
| tr -d ' "' \
| head -n 1)
if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found using target <cftarget>"; exit 0; fi; \
curl -s -X DELETE "<_cf_api_url>/$id" \
<_cf_api_prms> \
--data '{"cascade": "none"}'
_cf_api_url = https://api.cloudflare.com/client/v4/zones/<cfzone>/firewall/access_rules/rules
_cf_api_prms = -H "Authorization: Bearer <cftoken>" -H "Content-Type: application/json"
[Init]
# Declare your Cloudflare Authorization Bearer Token in the [DEFAULT] section of your jail.local file.
# The Cloudflare <ZONE_ID> of the domain you want to manage.
#
# cfzone =
# Your personal Cloudflare token. Ideally restricted to just have "Zone.Firewall Services" permissions.
#
# cftoken =
# Target of the firewall rule. Default is "ip" (v4).
#
cftarget = ip
# The firewall mode Cloudflare should use. Default is "block" (deny access).
# Consider also "js_challenge" or other "allowed_modes" if you want.
#
cfmode = block
# The message to include in the firewall IP banning rule.
#
notes = Fail2Ban <name>
[Init?family=inet6]
cftarget = ip6

View File

@ -0,0 +1,89 @@
## Version 2022/08/06
#
# Author: Mike Rushton
#
# IMPORTANT
#
# Please set jail.local's permission to 640 because it contains your CF API key.
#
# This action depends on curl (and optionally jq).
# Referenced from http://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE
#
# To get your CloudFlare API Key: https://www.cloudflare.com/a/account/my-account
#
# CloudFlare API error codes: https://www.cloudflare.com/docs/host-api.html#s4.2
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
# API v1
#actionban = curl -s -o /dev/null https://www.cloudflare.com/api_json.html -d 'a=ban' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>'
# API v4
actionban = curl -s -o /dev/null -X POST <_cf_api_prms> \
-d '{"mode":"block","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"Fail2Ban <name>"}' \
<_cf_api_url>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
# API v1
#actionunban = curl -s -o /dev/null https://www.cloudflare.com/api_json.html -d 'a=nul' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>'
# API v4
actionunban = id=$(curl -s -X GET <_cf_api_prms> \
"<_cf_api_url>?mode=block&configuration_target=<cftarget>&configuration_value=<ip>&page=1&per_page=1&notes=Fail2Ban%%20<name>" \
| { jq -r '.result[0].id' 2>/dev/null || tr -d '\n' | sed -nE 's/^.*"result"\s*:\s*\[\s*\{\s*"id"\s*:\s*"([^"]+)".*$/\1/p'; })
if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found"; exit 0; fi;
curl -s -o /dev/null -X DELETE <_cf_api_prms> "<_cf_api_url>/$id"
_cf_api_url = https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
_cf_api_prms = -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' -H 'Content-Type: application/json'
[Init]
# If you like to use this action with mailing whois lines, you could use the composite action
# action_cf_mwl predefined in jail.conf, just define in your jail:
#
# action = %(action_cf_mwl)s
# # Your CF account e-mail
# cfemail =
# # Your CF API Key
# cfapikey =
cftoken =
cfuser =
cftarget = ip
[Init?family=inet6]
cftarget = ip6

View File

@ -0,0 +1,122 @@
## Version 2023/11/22
# Fail2Ban configuration file
#
# Author: Russell Odom <russ@gloomytrousers.co.uk>, Daniel Black
# Sends a complaint e-mail to addresses listed in the whois record for an
# offending IP address.
# This uses the https://abusix.com/contactdb.html to lookup abuse contacts.
#
# DEPENDENCIES:
# This requires the dig command from bind-utils
#
# You should provide the <logpath> in the jail config - lines from the log
# matching the given IP address will be provided in the complaint as evidence.
#
# WARNING
# -------
#
# Please do not use this action unless you are certain that fail2ban
# does not result in "false positives" for your deployment. False
# positive reports could serve a misfavor to the original cause by
# flooding corresponding contact addresses, and complicating the work
# of administration personnel responsible for handling (verified) legit
# complains.
#
# Please consider using e.g. sendmail-whois-lines.conf action which
# would send the reports with relevant information to you, so the
# report could be first reviewed and then forwarded to a corresponding
# contact if legit.
#
[INCLUDES]
before = helpers-common.conf
[Definition]
# Used in test cases for coverage internal transformations
debug = 0
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = oifs=${IFS};
RESOLVER_ADDR="%(addr_resolver)s"
if [ "<debug>" -gt 0 ]; then echo "try to resolve $RESOLVER_ADDR"; fi
ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | tr -d '"')
IFS=,; ADDRESSES=$(echo $ADDRESSES)
IFS=${oifs}
IP=<ip>
if [ ! -z "$ADDRESSES" ]; then
( printf %%b "<message>\n"; date '+Note: Local timezone is %%z (%%Z)';
printf %%b "\nLines containing failures of <ip> (max <grepmax>)\n";
%(_grep_logs)s;
) | <mailcmd> "Abuse from <ip>" <mailargs> $ADDRESSES
fi
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
# Server as resolver used in dig command
#
addr_resolver = <ip-rev>abuse-contacts.abusix.org
# Default message used for abuse content
#
message = Dear Sir/Madam,\n\nWe have detected abuse from the IP address $IP, which according to a abusix.com is on your network. We would appreciate if you would investigate and take action as appropriate.\n\nLog lines are given below, but please ask if you require any further information.\n\n(If you are not the correct person to contact about this please accept our apologies - your e-mail address was extracted from the whois record by an automated process.)\n\n This mail was generated by Fail2Ban.\nThe recipient address of this report was provided by the Abuse Contact DB by abusix.com. abusix.com does not maintain the content of the database. All information which we pass out, derives from the RIR databases and is processed for ease of use. If you want to change or report non working abuse contacts please contact the appropriate RIR. If you have any further question, contact abusix.com directly via email (info@abusix.com). Information about the Abuse Contact Database can be found here: https://abusix.com/global-reporting/abuse-contact-db\nabusix.com is neither responsible nor liable for the content or accuracy of this message.\n
# Path to the log files which contain relevant lines for the abuser IP
#
logpath = /dev/null
# Option: mailcmd
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
# Values: CMD
#
mailcmd = mail -E 'set escape' -s
# Option: mailargs
# Notes.: Additional arguments to mail command. e.g. for standard Unix mail:
# CC reports to another address:
# -c me@example.com
# Appear to come from a different address - the '--' indicates
# arguments to be passed to Sendmail:
# -- -f me@example.com
# Values: [ STRING ]
#
mailargs =
# Number of log lines to include in the email
#
#grepmax = 1000
#grepopts = -m <grepmax>

View File

@ -0,0 +1,44 @@
## Version 2022/08/06
# Author: Gilbn from https://technicalramblings.com
# Adapted Source: https://gist.github.com/sander1/075736a42db2c66bc6ce0fab159ca683
# Create the Discord Webhook in: Server settings -> Webhooks -> Create Webhooks
[Definition]
# Notify on Startup
actionstart = curl -X POST "<webhook>" \
-H "Content-Type: application/json" \
-d '{"username":"<botname>", "content":":white_check_mark: The **[<name>]** jail has started"}'
# Notify on Shutdown
actionstop = curl -X POST "<webhook>" \
-H "Content-Type: application/json" \
-d '{"username":"<botname>", "content":":no_entry: The **[<name>]** jail has been stopped"}'
#
actioncheck =
# Notify on Banned
actionban = curl -X POST "<webhook>" \
-H "Content-Type: application/json" \
-d '{"username":"<botname>", "content":"<discord_userid> :bell: **[<name>]** :hammer:**BANNED**:hammer: IP: [<ip>](<url_check_ip><ip>) for **<bantime>** seconds after **<failures>** failure(s). If you want to unban the IP run: `fail2ban-client unban <ip>`"}'
# Notify on Unbanned
actionunban = curl -X POST "<webhook>" \
-H "Content-Type: application/json" \
-d '{"username":"<botname>", "content":":bell: **[<name>]** **UNBANNED** IP: [<ip>](<url_check_ip><ip>)"}'
[Init]
# Discord Webhook URL
webhook = https://discordapp.com/api/webhooks/XXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Discord Bot Username
botname = Fail2Ban
# User ID to ping
# ex: discord_userid = "<@!1234567890>"
discord_userid =
# URL prefix for an IP checking website
# abuseipdb is used by default since there is also an action to report an IP to their API
url_check_ip = https://www.abuseipdb.com/check/

View File

@ -0,0 +1,208 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Russell Odom <russ@gloomytrousers.co.uk>
# Submits attack reports to DShield (http://www.dshield.org/)
#
# You MUST configure at least:
# <port> (the port that's being attacked - use number not name).
#
# You SHOULD also provide:
# <myip> (your public IP address, if it's not the address of eth0)
# <userid> (your DShield userID, if you have one - recommended, but reports will
# be used anonymously if not)
# <protocol> (the protocol in use - defaults to tcp)
#
# Best practice is to provide <port> and <protocol> in jail.conf like this:
# action = dshield[port=1234,protocol=tcp]
#
# ...and create "dshield.local" with contents something like this:
# [Init]
# myip = 10.0.0.1
# userid = 12345
#
# Other useful configuration values are <mailargs> (you can use for specifying
# a different sender address for the report e-mails, which should match what is
# configured at DShield), and <lines>/<minreportinterval>/<maxbufferage> (to
# configure how often the buffer is flushed).
#
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = if [ -f <tmpfile>.buffer ]; then
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <mailargs> <dest>
date +%%s > <tmpfile>.lastsent
fi
rm -f <tmpfile>.buffer <tmpfile>.first
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
# See http://www.dshield.org/specs.html for more on report format/notes
#
# Note: We are currently using <time> for the timestamp because no tag is
# available to indicate the timestamp of the log message(s) which triggered the
# ban. Therefore the timestamps we are using in the report, whilst often only a
# few seconds out, are incorrect. See
# http://sourceforge.net/tracker/index.php?func=detail&aid=2017795&group_id=121032&atid=689047
#
actionban = TZONE=`date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'`
DATETIME="`perl -e '@t=localtime(<time>);printf "%%4d-%%02d-%%02d %%02d:%%02d:%%02d",1900+$t[5],$t[4]+1,$t[3],$t[2],$t[1],$t[0]'` $TZONE"
PROTOCOL=`awk '{IGNORECASE=1;if($1=="<protocol>"){print $2;exit}}' /etc/protocols`
if [ -z "$PROTOCOL" ]; then PROTOCOL=<protocol>; fi
printf %%b "$DATETIME\t<userid>\t<failures>\t<ip>\t<srcport>\t<myip>\t<port>\t$PROTOCOL\t<tcpflags>\n" >> <tmpfile>.buffer
NOW=`date +%%s`
if [ ! -f <tmpfile>.first ]; then
echo <time> | cut -d. -f1 > <tmpfile>.first
fi
if [ ! -f <tmpfile>.lastsent ]; then
echo 0 > <tmpfile>.lastsent
fi
LOGAGE=$(($NOW - `cat <tmpfile>.first`))
LASTREPORT=$(($NOW - `cat <tmpfile>.lastsent`))
LINES=$( wc -l <tmpfile>.buffer | awk '{ print $1 }' )
if [ $LINES -ge <lines> && $LASTREPORT -gt <minreportinterval> ] || [ $LOGAGE -gt <maxbufferage> ]; then
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ $TZONE Fail2Ban" <mailargs> <dest>
rm -f <tmpfile>.buffer <tmpfile>.first
echo $NOW > <tmpfile>.lastsent
fi
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = if [ -f <tmpfile>.first ]; then
NOW=`date +%%s`
LOGAGE=$(($NOW - `cat <tmpfile>.first`))
if [ $LOGAGE -gt <maxbufferage> ]; then
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <mailargs> <dest>
rm -f <tmpfile>.buffer <tmpfile>.first
echo $NOW > <tmpfile>.lastsent
fi
fi
[Init]
# Option: port
# Notes.: The target port for the attack (numerical). MUST be provided in the
# jail config, as it cannot be detected here.
# Values: [ NUM ]
#
port = ???
# Option: userid
# Notes.: Your DShield user ID. Should be provided either in the jail config or
# in a .local file.
# Register at https://secure.dshield.org/register.html
# Values: [ NUM ]
#
userid = 0
# Option: myip
# Notes.: The target IP for the attack (your public IP). Should be provided
# either in the jail config or in a .local file unless your PUBLIC IP
# is the first IP assigned to eth0
# Values: [ an IP address ] Default: Tries to find the IP address of eth0,
# which in most cases will be a private IP, and therefore incorrect
#
myip = `ip -4 addr show dev eth0 | grep inet | head -n 1 | sed -r 's/.*inet ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/'`
# Option: protocol
# Notes.: The protocol over which the attack is happening
# Values: [ tcp | udp | icmp | (any other protocol name from /etc/protocols) | NUM ] Default: tcp
#
protocol = tcp
# Option: lines
# Notes.: How many lines to buffer before making a report. Regardless of this,
# reports are sent a minimum of <minreportinterval> apart, or if the
# buffer contains an event over <maxbufferage> old, or on shutdown
# Values: [ NUM ]
#
lines = 50
# Option: minreportinterval
# Notes.: Minimum period (in seconds) that must elapse before we submit another
# batch of reports. DShield request a minimum of 1 hour (3600 secs)
# between reports.
# Values: [ NUM ]
#
minreportinterval = 3600
# Option: maxbufferage
# Notes.: Maximum age (in seconds) of the oldest report in the buffer before we
# submit the batch, even if we haven't reached <lines> yet. Note that
# this is only checked on each ban/unban, and that we always send
# anything in the buffer on shutdown. Must be greater than
# Values: [ NUM ]
#
maxbufferage = 21600
# Option: srcport
# Notes.: The source port of the attack. You're unlikely to have this info, so
# you can leave the default
# Values: [ NUM ]
#
srcport = ???
# Option: tcpflags
# Notes.: TCP flags on attack. You're unlikely to have this info, so you can
# leave empty
# Values: [ STRING ]
#
tcpflags =
# Option: mailcmd
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
# Values: CMD
#
mailcmd = mail -E 'set escape' -s
# Option: mailargs
# Notes.: Additional arguments to mail command. e.g. for standard Unix mail:
# CC reports to another address:
# -c me@example.com
# Appear to come from a different address (the From address must match
# the one configured at DShield - the '--' indicates arguments to be
# passed to Sendmail):
# -- -f me@example.com
# Values: [ STRING ]
#
mailargs =
# Option: dest
# Notes.: Destination e-mail address for reports
# Values: [ STRING ]
#
dest = reports@dshield.org
# Option: tmpfile
# Notes.: Base name of temporary files used for buffering
# Values: [ STRING ]
#
tmpfile = /var/run/fail2ban/tmp-dshield

View File

@ -0,0 +1,64 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = if [ ! -z '<target>' ]; then touch <target>; fi;
printf %%b "<init>\n" <to_target>
echo "%(debug)s started"
# Option: actionflush
# Notes.: command executed once to flush (clear) all IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = printf %%b "-*\n" <to_target>
echo "%(debug)s clear all"
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = if [ ! -z '<target>' ]; then rm -f <target>; fi;
echo "%(debug)s stopped"
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "+<ip>\n" <to_target>
echo "%(debug)s banned <ip> (family: <family>)"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = printf %%b "-<ip>\n" <to_target>
echo "%(debug)s unbanned <ip> (family: <family>)"
debug = [<name>] <actname> <target> --
[Init]
init = 123
target = /var/run/fail2ban/fail2ban.dummy
to_target = >> <target>

View File

@ -0,0 +1,46 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Donald Yandt
# Because of the --remove-rules in stop this action requires firewalld-0.3.8+
[INCLUDES]
before = firewallcmd-common.conf
[Definition]
actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
firewall-cmd --direct --add-rule <family> filter <chain> 0 -j f2b-<name>
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -j f2b-<name>
firewall-cmd --direct --remove-rules <family> filter f2b-<name>
firewall-cmd --direct --remove-chain <family> filter f2b-<name>
# Example actioncheck: firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-recidive$'
actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
# DEV NOTES:
#
# Author: Donald Yandt
# Uses "FirewallD" instead of the "iptables daemon".
#
#
# Output:
# actionstart:
# $ firewall-cmd --direct --add-chain ipv4 filter f2b-recidive
# success
# $ firewall-cmd --direct --add-rule ipv4 filter f2b-recidive 1000 -j RETURN
# success
# $ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -j f2b-recidive
# success

View File

@ -0,0 +1,77 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Donald Yandt
#
[Init]
# Option: name
# Notes Default name of the chain
# Values: STRING
name = default
# Option port
# Notes Can also use port numbers separated by a comma and in rich-rules comma and/or space.
# Value STRING Default: 1:65535
port = 1:65535
# Option: protocol
# Notes [ tcp | udp | icmp | all ]
# Values: STRING Default: tcp
protocol = tcp
# Option: family(ipv4)
# Notes specifies the socket address family type
# Values: STRING
family = ipv4
# Option: chain
# Notes specifies the firewalld chain to which the Fail2Ban rules should be
# added
# Values: STRING Default: INPUT_direct
chain = INPUT_direct
# Option: zone
# Notes use command firewall-cmd --get-active-zones to see a list of all active zones. See firewalld man pages for more information on zones
# Values: STRING Default: public
zone = public
# Option: service
# Notes use command firewall-cmd --get-services to see a list of services available
# Examples services: amanda-client amanda-k5-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps
# freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kadmin kerberos
# kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s
# postgresql privoxy proxy-dhcp puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp squid ssh synergy
# telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server
# Values: STRING Default: ssh
service = ssh
# Option: rejecttype (ipv4)
# Notes See iptables/firewalld man pages for ipv4 reject types.
# Values: STRING
rejecttype = icmp-port-unreachable
# Option: blocktype (ipv4/ipv6)
# Notes See iptables/firewalld man pages for jump targets. Common values are REJECT,
# REJECT --reject-with icmp-port-unreachable, DROP
# Values: STRING
blocktype = REJECT --reject-with <rejecttype>
# Option: rich-blocktype (ipv4/ipv6)
# Notes See firewalld man pages for jump targets. Common values are reject,
# reject type="icmp-port-unreachable", drop
# Values: STRING
rich-blocktype = reject type='<rejecttype>'
[Init?family=inet6]
# Option: family(ipv6)
# Notes specifies the socket address family type
# Values: STRING
family = ipv6
# Option: rejecttype (ipv6)
# Note: See iptables/firewalld man pages for ipv6 reject types.
# Values: STRING
rejecttype = icmp6-port-unreachable

View File

@ -0,0 +1,133 @@
## Version 2024/11/07
# Fail2Ban action file for firewall-cmd/ipset
#
# This requires:
# ipset (package: ipset)
# firewall-cmd (package: firewalld)
#
# This is for ipset protocol 6 (and hopefully later) (ipset v6.14).
# Use ipset -V to see the protocol and version.
#
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
#
# If you are running on an older kernel you make need to patch in external
# modules.
[INCLUDES]
before = firewallcmd-common.conf
[Definition]
actionstart = <ipsbackend_<ipsetbackend>/actionstart>
firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
actionflush = <ipsbackend_<ipsetbackend>/actionflush>
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
<actionflush>
<ipsbackend_<ipsetbackend>/actionstop>
actionban = <ipsbackend_<ipsetbackend>/actionban>
# actionprolong = %(actionban)s
actionunban = <ipsbackend_<ipsetbackend>/actionunban>
[ipsbackend_ipset]
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
actionflush = ipset flush <ipmset>
actionstop = ipset destroy <ipmset> 2>/dev/null || { sleep 1; ipset destroy <ipmset>; }
actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime>
actionunban = ipset -exist del <ipmset> <ip>
[ipsbackend_firewalld]
actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=<ipsettype> --option=timeout=<default-ipsettime> --option=maxelem=<maxelem> <firewalld_familyopt>
# TODO: there doesn't seem to be an explicit way to invoke the ipset flush function using firewall-cmd
actionflush =
actionstop = firewall-cmd --direct --delete-ipset=<ipmset>
actionban = firewall-cmd --ipset=<ipmset> --add-entry=<ip>
actionunban = firewall-cmd --ipset=<ipmset> --remove-entry=<ip>
[Init]
# Option: ipsettype
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
# Values: hash:ip, hash:net, etc... Default: hash:ip
ipsettype = hash:ip
# Option: chain
# Notes specifies the iptables chain to which the fail2ban rules should be
# added
# Values: [ STRING ]
#
chain = INPUT_direct
# Option: default-ipsettime
# Notes: specifies default timeout in seconds (handled default ipset timeout only)
# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban)
default-ipsettime = 0
# Option: ipsettime
# Notes: specifies ticket timeout (handled ipset timeout only)
# Values: [ NUM ] Default: 0 (managed by fail2ban by unban)
ipsettime = 0
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536
# expression to calculate timeout from bantime, example:
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
# Option: ipsetbackend
# Notes.: defines the backend of ipset used for match-set (firewalld or ipset)
# Values: firewalld or ipset
# Default: ipset
ipsetbackend = ipset
# Option: actiontype
# Notes.: defines additions to the blocking rule
# Values: leave empty to block all attempts from the host
# Default: Value of the multiport
actiontype = <multiport>
# Option: allports
# Notes.: default addition to block all ports
# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=<allports>]
# for all protocols: banaction = firewallcmd-ipset[actiontype=""]
allports = -p <protocol>
# Option: multiport
# Notes.: addition to block access only to specific ports
# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=<multiport>]
multiport = -p <protocol> -m multiport --dports <port>
ipmset = f2b-<name>
familyopt =
firewalld_familyopt =
[Init?family=inet6]
ipmset = f2b-<name>6
familyopt = family inet6
firewalld_familyopt = --option=family=inet6
# DEV NOTES:
#
# Author: Edgar Hoch, Daniel Black, Sergey Brester and Mihail Politaev
# firewallcmd-new / iptables-ipset-proto6 combined for maximum goodness

View File

@ -0,0 +1,27 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Donald Yandt
# Because of the --remove-rules in stop this action requires firewalld-0.3.8+
[INCLUDES]
before = firewallcmd-common.conf
[Definition]
actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
firewall-cmd --direct --add-rule <family> filter <chain> 0 -m conntrack --ctstate NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -m conntrack --ctstate NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
firewall-cmd --direct --remove-rules <family> filter f2b-<name>
firewall-cmd --direct --remove-chain <family> filter f2b-<name>
# Example actioncheck: firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-apache-modsecurity$'
actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>

View File

@ -0,0 +1,48 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Because of the --remove-rules in stop this action requires firewalld-0.3.8+
[INCLUDES]
before = firewallcmd-common.conf
[Definition]
actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
firewall-cmd --direct --add-rule <family> filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
firewall-cmd --direct --remove-rules <family> filter f2b-<name>
firewall-cmd --direct --remove-chain <family> filter f2b-<name>
actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q 'f2b-<name>$'
actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
# DEV NOTES:
#
# Author: Edgar Hoch
# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch.
# It uses "firewall-cmd" instead of "iptables".
#
# Output:
#
# $ firewall-cmd --direct --add-chain ipv4 filter fail2ban-name
# success
# $ firewall-cmd --direct --add-rule ipv4 filter fail2ban-name 1000 -j RETURN
# success
# $ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -m state --state NEW -p tcp -m multiport --dports 22 -j fail2ban-name
# success
# $ firewall-cmd --direct --get-chains ipv4 filter
# fail2ban-name
# $ firewall-cmd --direct --get-chains ipv4 filter | od -h
# 0000000 6166 6c69 6232 6e61 6e2d 6d61 0a65
# $ firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-name( |$)' ; echo $?
# 0
# $ firewall-cmd -V
# 0.3.8

View File

@ -0,0 +1,30 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Authors: Donald Yandt, Sergey G. Brester
#
# Because of the rich rule commands requires firewalld-0.3.1+
# This action uses firewalld rich-rules which gives you a cleaner iptables since it stores rules according to zones and not
# by chain. So for an example all deny rules will be listed under <zone>_deny and all log rules under <zone>_log.
#
# Also this action logs banned access attempts so you can filter that and increase ban time for offenders.
#
# If you use the --permanent rule you get a xml file in /etc/firewalld/zones/<zone>.xml that can be shared and parsed easliy
#
# This is an derivative of firewallcmd-rich-rules.conf, see there for details and other parameters.
[INCLUDES]
before = firewallcmd-rich-rules.conf
[Definition]
rich-suffix = log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype>
[Init]
# log levels are "emerg", "alert", "crit", "error", "warning", "notice", "info" or "debug"
level = info
# log rate per minute
rate = 1

View File

@ -0,0 +1,45 @@
## Version 2024/08/07
# Fail2Ban configuration file
#
# Author: Donald Yandt
#
# Because of the rich rule commands requires firewalld-0.3.1+
# This action uses firewalld rich-rules which gives you a cleaner iptables since it stores rules according to zones and not
# by chain. So for an example all deny rules will be listed under <zone>_deny.
#
# If you use the --permanent rule you get a xml file in /etc/firewalld/zones/<zone>.xml that can be shared and parsed easliy
#
# Example commands to view rules:
# firewall-cmd [--zone=<zone>] --list-rich-rules
# firewall-cmd [--zone=<zone>] --list-all
# firewall-cmd [--zone=zone] --query-rich-rule='rule'
[INCLUDES]
before = firewallcmd-common.conf
[Definition]
actionstart =
actionstop =
actioncheck =
#you can also use zones and/or service names.
#
# zone example:
# firewall-cmd --zone=<zone> --add-rich-rule="rule family='ipv4' source address='<ip>' port port='<port>' protocol='<protocol>' <rich-blocktype>"
#
# service name example:
# firewall-cmd --zone=<zone> --add-rich-rule="rule family='ipv4' source address='<ip>' service name='<service>' <rich-blocktype>"
#
# Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp
fwcmd_rich_rule = rule family=\"<family>\" source address=\"<ip>\" port port=\"$p\" protocol=\"<protocol>\" %(rich-suffix)s
actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s"; done
actionunban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="%(fwcmd_rich_rule)s"; done
rich-suffix = <rich-blocktype>

View File

@ -0,0 +1,52 @@
## Version 2022/12/18
# Fail2Ban configuration file
#
# Author: Quietsy
#
# Add the following to jail.local (uncommented) to apply the gotify action to all bans with all jails
# Change the url to have a valid gotify address and a valid token
#
# [DEFAULT]
# action = %(action_)s
# gotify[url="https://gotify.domain.com/message?token=lkghlkhjo8y9"]
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = curl --data '{"message": "Started <name>"}' -X POST -H Content-Type:application/json <url>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = curl --data '{"message": "Stopped <name>"}' -X POST -H Content-Type:application/json <url>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl -X POST -H Content-Type:application/json <url> \
--data '{"message": "⛔ <name> ⛔\n\n<ip> got banned for <bantime> seconds after <failures> tries.\n\nUnban command:\nfail2ban-client unban <ip>"}'
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = curl -X POST -H Content-Type:application/json <url> --data '{"message": "✅ <name> ✅\n\n<ip> is now unbanned"}'
[Init]
url =

View File

@ -0,0 +1,18 @@
## Version 2022/08/06
[DEFAULT]
# Usage:
# _grep_logs_args = 'test'
# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ...
#
_grep_logs = logpath="<logpath>"; grep <grepopts> %(_grep_logs_args)s $logpath | <greplimit>
# options `-wF` used to match only whole words and fixed string (not as pattern)
_grep_logs_args = -wF "<ip>"
# Used for actions, that should not by executed if ticket was restored:
_bypass_if_restored = if [ '<restored>' = '1' ]; then exit 0; fi;
[Init]
greplimit = tail -n <grepmax>
grepmax = 1000
grepopts = -m <grepmax>

View File

@ -0,0 +1,63 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Edited for cross platform by: James Stout, Yaroslav Halchenko and Daniel Black
#
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "<daemon_list>: <ip_value>\n" >> <file>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = IP=$(echo "<ip_value>" | sed 's/[][\.]/\\\0/g') && sed -i "/^<daemon_list>: $IP$/d" <file>
[Init]
# Option: file
# Notes.: hosts.deny file path.
# Values: STR Default: /etc/hosts.deny
#
file = /etc/hosts.deny
# Option: daemon_list
# Notes: The list of services that this action will deny. See the man page
# for hosts.deny/hosts_access. Default is all services.
# Values: STR Default: ALL
daemon_list = ALL
# internal variable IP (to differentiate the IPv4 and IPv6 syntax, where it is enclosed in brackets):
ip_value = <ip>
[Init?family=inet6]
ip_value = [<ip>]

View File

@ -0,0 +1,59 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# NetBSD ipfilter (ipf command) ban/unban
#
# Author: Ed Ravin <eravin@panix.com>
#
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
# enable IPF if not already enabled
actionstart = /sbin/ipf -E
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
# don't disable IPF with "/sbin/ipf -D", there may be other filters in use
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = echo block <blocktype> in quick from <ip>/32 | /sbin/ipf -f -
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
# note -r option used to remove matching rule
actionunban = echo block <blocktype> in quick from <ip>/32 | /sbin/ipf -r -f -
[Init]
# Option: Blocktype
# Notes : This is the return-icmp[return-code] mentioned in the ipf man page section 5. Keep this quoted to prevent
# Shell expansion. This should be blank (unquoted) to drop the packet.
# Values: STRING
blocktype = "return-icmp(port-unr)"

View File

@ -0,0 +1,69 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Nick Munger
# Modified by: Cyril Jaquier
#
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ipfw add <blocktype> tcp from <ip> to <localhost> <port>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = ipfw delete `ipfw list | grep -i "[^0-9]<ip>[^0-9]" | awk '{print $1;}'`
[Init]
# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ]
#
port = ssh
# Option: localhost
# Notes.: the local IP address of the network interface
# Values: IP
#
localhost = 127.0.0.1
# Option: blocktype
# Notes.: How to block the traffic. Use a action from man 5 ipfw
# Common values: deny, unreach port, reset
# Values: STRING
#
blocktype = unreach port

View File

@ -0,0 +1,16 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
# made active on all ports from original iptables.conf
#
# Obsolete: superseded by iptables[type=allports]
[INCLUDES]
before = iptables.conf
[Definition]
type = allports

View File

@ -0,0 +1,75 @@
## Version 2023/11/18
# Fail2Ban configuration file
#
# Author: Daniel Black
#
# This is for ipset protocol 4 (ipset v4.2). If you have a later version
# of ipset try to use the iptables-ipset-proto6.conf as it does some things
# nicer.
#
# This requires the program ipset which is normally in package called ipset.
#
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
#
# If you are running on an older kernel you make need to patch in external
# modules. Debian squeeze can do this with:
# apt-get install xtables-addons-source
# module-assistant auto-install xtables-addons
#
# Debian wheezy and above uses protocol 6
[INCLUDES]
before = iptables.conf
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = ipset --create f2b-<name> maxelem <maxelem> iphash
<_ipt_add_rules>
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = ipset --flush f2b-<name>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = <_ipt_del_rules>
<actionflush>
ipset --destroy f2b-<name>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ipset --test f2b-<name> <ip> || ipset --add f2b-<name> <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = ipset --test f2b-<name> <ip> && ipset --del f2b-<name> <ip>
# Several capabilities used internally:
rule-jump = -m set --match-set f2b-<name> src -j <blocktype>
[Init]
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536

View File

@ -0,0 +1,28 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Daniel Black
#
# This is for ipset protocol 6 (and hopefully later) (ipset v6.14).
# Use ipset -V to see the protocol and version. Version 4 should use
# iptables-ipset-proto4.conf.
#
# This requires the program ipset which is normally in package called ipset.
#
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
#
# If you are running on an older kernel you make need to patch in external
# modules which probably won't be protocol version 6.
#
# Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de>
# made config file IPv6 capable (see new section Init?family=inet6)
#
# Obsolete: superseded by iptables-ipset[type=allports]
[INCLUDES]
before = iptables-ipset.conf
[Definition]
type = allports

View File

@ -0,0 +1,28 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Daniel Black
#
# This is for ipset protocol 6 (and hopefully later) (ipset v6.14).
# Use ipset -V to see the protocol and version. Version 4 should use
# iptables-ipset-proto4.conf.
#
# This requires the program ipset which is normally in package called ipset.
#
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
#
# If you are running on an older kernel you make need to patch in external
# modules.
#
# Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de>
# made config file IPv6 capable (see new section Init?family=inet6)
#
# Obsolete: superseded by iptables-ipset[type=multiport]
[INCLUDES]
before = iptables-ipset.conf
[Definition]
type = multiport

View File

@ -0,0 +1,102 @@
## Version 2024/11/07
# Fail2Ban configuration file
#
# Authors: Sergey G Brester (sebres), Daniel Black, Alexander Koeppe
#
# This is for ipset protocol 6 (and hopefully later) (ipset v6.14).
# Use ipset -V to see the protocol and version. Version 4 should use
# iptables-ipset-proto4.conf.
#
# This requires the program ipset which is normally in package called ipset.
#
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
#
# If you are running on an older kernel you make need to patch in external
# modules.
#
[INCLUDES]
before = iptables.conf
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
<_ipt_add_rules>
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = ipset flush <ipmset>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = <_ipt_del_rules>
<actionflush>
ipset destroy <ipmset> 2>/dev/null || { sleep 1; ipset destroy <ipmset>; }
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime>
# actionprolong = %(actionban)s
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = ipset -exist del <ipmset> <ip>
# Several capabilities used internally:
rule-jump = -m set --match-set <ipmset> src -j <blocktype>
[Init]
# Option: ipsettype
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
# Values: hash:ip, hash:net, etc... Default: hash:ip
ipsettype = hash:ip
# Option: default-ipsettime
# Notes: specifies default timeout in seconds (handled default ipset timeout only)
# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban)
default-ipsettime = 0
# Option: ipsettime
# Notes: specifies ticket timeout (handled ipset timeout only)
# Values: [ NUM ] Default: 0 (managed by fail2ban by unban)
ipsettime = 0
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536
# expression to calculate timeout from bantime, example:
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
ipmset = f2b-<name>
familyopt =
[Init?family=inet6]
ipmset = f2b-<name>6
familyopt = family inet6

View File

@ -0,0 +1,69 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Guido Bozzetto
# Modified: Cyril Jaquier
#
# make "f2b-<name>" chain to match drop IP
# make "f2b-<name>-log" chain to log and drop
# insert a jump to f2b-<name> from -I <chain> if proto/port match
#
#
[INCLUDES]
before = iptables.conf
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = <iptables> -N f2b-<name>
<iptables> -A f2b-<name> -j <returntype>
<iptables> -I <chain> 1 -p <protocol> -m multiport --dports <port> -j f2b-<name>
<iptables> -N f2b-<name>-log
<iptables> -I f2b-<name>-log -j LOG --log-prefix "$(expr f2b-<name> : '\(.\{1,23\}\)'):DROP " --log-level warning -m limit --limit 6/m --limit-burst 2
<iptables> -A f2b-<name>-log -j <blocktype>
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = <iptables> -F f2b-<name>
<iptables> -F f2b-<name>-log
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
<actionflush>
<iptables> -X f2b-<name>
<iptables> -X f2b-<name>-log
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = <iptables> -n -L f2b-<name>-log >/dev/null
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j f2b-<name>-log
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = <iptables> -D f2b-<name> -s <ip> -j f2b-<name>-log
[Init]

View File

@ -0,0 +1,15 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
#
# Obsolete: superseded by iptables[type=multiport]
[INCLUDES]
before = iptables.conf
[Definition]
type = multiport

View File

@ -0,0 +1,16 @@
## Version 2020/02/14
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Copied from iptables.conf and modified by Yaroslav Halchenko
# to fulfill the needs of bugreporter dbts#350746.
#
# Obsolete: superseded by iptables[pre-rule='-m state --state NEW<sp>']
[INCLUDES]
before = iptables.conf
[Definition]
pre-rule = -m state --state NEW<sp>

View File

@ -0,0 +1,89 @@
## Version 2025/04/16
# Fail2Ban configuration file
#
# Author: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
#
# Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de>
# made config file IPv6 capable
[INCLUDES]
before = iptables.conf
[Definition]
_ipt_chain_rule = -m recent --update --seconds 3600 --name <iptname> -j <blocktype>
_ipt_check_rule = <iptables> -C <chain> %(_ipt_chain_rule)s
_ipt-iter =
_ipt-done =
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
# Changing iptables rules requires root privileges. If fail2ban is
# configured to run as root, firewall setup can be performed by
# fail2ban automatically. However, if fail2ban is configured to run as
# a normal user, the configuration must be done by some other means
# (e.g. using static firewall configuration with the
# iptables-persistent package).
#
# Explanation of the rule below:
# Check if any packets coming from an IP on the <iptname>
# list have been seen in the last 3600 seconds. If yes, update the
# timestamp for this IP and drop the packet. If not, let the packet
# through.
#
# Fail2ban inserts blacklisted hosts into the <iptname> list
# and removes them from the list after some time, according to its
# own rules. The 3600 second timeout is independent and acts as a
# safeguard in case the fail2ban process dies unexpectedly. The
# shorter of the two timeouts actually matters.
actionstart = if [ `id -u` -eq 0 ];then
{ %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I <chain> %(_ipt_chain_rule)s; }
fi
# Option: actionflush
#
# [TODO] Flushing is currently not implemented for xt_recent
#
actionflush =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = echo / > /proc/net/xt_recent/<iptname>
if [ `id -u` -eq 0 ];then
<iptables> -D <chain> %(_ipt_chain_rule)s;
fi
# Option: actioncheck
# Notes.: command executed as invariant check (error by ban)
# Values: CMD
#
actioncheck = { %(_ipt_check_rule)s >/dev/null 2>&1; } && test -e /proc/net/xt_recent/<iptname>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = echo +<ip> > /proc/net/xt_recent/<iptname>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = echo -<ip> > /proc/net/xt_recent/<iptname>
[Init]
iptname = f2b-<name>
[Init?family=inet6]
iptname = f2b-<name>6

View File

@ -0,0 +1,164 @@
## Version 2025/04/16
# Fail2Ban configuration file
#
# Authors: Sergey G. Brester (sebres), Cyril Jaquier, Daniel Black,
# Yaroslav O. Halchenko, Alexander Koeppe et al.
#
[Definition]
# Option: type
# Notes.: type of the action.
# Values: [ oneport | multiport | allports ] Default: oneport
#
type = oneport
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = <iptables> -F f2b-<name>
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = { <iptables> -C f2b-<name> -j <returntype> >/dev/null 2>&1; } || { <iptables> -N f2b-<name> || true; <iptables> -A f2b-<name> -j <returntype>; }
<_ipt_add_rules>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = <_ipt_del_rules>
<actionflush>
<iptables> -X f2b-<name>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = <_ipt_check_rules>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
# Option: pre-rule
# Notes.: prefix parameter(s) inserted to the begin of rule. No default (empty)
#
pre-rule =
rule-jump = -j <_ipt_rule_target>
# Several capabilities used internally:
_ipt-iter = for chain in $(echo '<chain>' | sed 's/,/ /g'); do for proto in $(echo '<protocol>' | sed 's/,/ /g'); do
_ipt-done = done; done
_ipt_add_rules = <_ipt-iter>
{ %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I $chain %(_ipt_chain_rule)s; }
<_ipt-done>
_ipt_del_rules = <_ipt-iter>
<iptables> -D $chain %(_ipt_chain_rule)s
<_ipt-done>
_ipt_check_rules = <_ipt-iter>
%(_ipt_check_rule)s
<_ipt-done>
_ipt_chain_rule = <pre-rule><ipt_<type>/_chain_rule>
_ipt_check_rule = <iptables> -C $chain %(_ipt_chain_rule)s
_ipt_rule_target = f2b-<name>
[ipt_oneport]
_chain_rule = -p $proto --dport <port> <rule-jump>
[ipt_multiport]
_chain_rule = -p $proto -m multiport --dports <port> <rule-jump>
[ipt_allports]
_chain_rule = -p $proto <rule-jump>
[Init]
# Option: chain
# Notes specifies the iptables chains to which the Fail2Ban rules should be
# added. May be a single chain (e.g. INPUT) or a comma separated list
# (e.g. INPUT, FORWARD)
# Values: STRING Default: INPUT
chain = INPUT
# Default name of the chain
#
name = default
# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ] Default:
#
port = ssh
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp
# Option: blocktype
# Note: This is what the action does with rules. This can be any jump target
# as per the iptables man page (section 8). Common values are DROP
# REJECT, REJECT --reject-with icmp-port-unreachable
# Values: STRING
blocktype = REJECT --reject-with icmp-port-unreachable
# Option: returntype
# Note: This is the default rule on "actionstart". This should be RETURN
# in all (blocking) actions, except REJECT in allowing actions.
# Values: STRING
returntype = RETURN
# Option: lockingopt
# Notes.: Option was introduced to iptables to prevent multiple instances from
# running concurrently and causing erratic behavior. -w was introduced
# in iptables 1.4.20, so might be absent on older systems
# See https://github.com/fail2ban/fail2ban/issues/1122
# Values: STRING
lockingopt = -w
# Option: iptables
# Notes.: Actual command to be executed, including common to all calls options
# Values: STRING
iptables = iptables <lockingopt>
[Init?family=inet6]
# Option: blocktype (ipv6)
# Note: This is what the action does with rules. This can be any jump target
# as per the iptables man page (section 8). Common values are DROP
# REJECT, REJECT --reject-with icmp6-port-unreachable
# Values: STRING
blocktype = REJECT --reject-with icmp6-port-unreachable
# Option: iptables (ipv6)
# Notes.: Actual command to be executed, including common to all calls options
# Values: STRING
iptables = ip6tables <lockingopt>

View File

@ -0,0 +1,108 @@
## Version 2023/11/22
# IPThreat configuration file
#
# Added to fail2ban by Jeff Johnson (jjxtra)
#
# Action to report IP address to ipthreat.net
#
# You must sign up to obtain an API key from ipthreat.net and request bulk report permissions
# https://ipthreat.net/integrations
#
# IPThreat is a 100% free site and service, all data is licensed under a creative commons by attribution license
# Please do not integrate if you do not agree to the license
#
# IMPORTANT:
#
# Reporting an IP is a serious action. Make sure that it is legit.
# Consider using this action only for:
# * IP that has been banned more than once
# * High max retry to avoid user mistyping password
# * Filters that are unlikely to be human error
#
# Example:
# ```
# action = %(known/action)s
# ipthreat[]
# ```
#
# The action accepts the following arguments: ipthreat[ipthreat_flags="8",ipthreat_system="SSH", ipthreat_apikey=...]
# In most cases your action could be as simple as: ipthreat[], since the default flags and system are set to the most correct default values.
# You can optionally override ipthreat_system and ipthreat_flags if desired.
# The ipthreat_apikey must be set at the bottom of this configuration file.
#
# `ipthreat_system` is a short name of the system attacked, i.e. SSH, SMTP, MYSQL, PHP, etc.
#
# For `ipthreat_flags`, most cases will use 8 (BruteForce) which is the default, but you could use others.
# You can use the name or the ordinal.
# Multiple values are comma separated.
# ```
# Name Ordinal Description
# Dns 1 Abuse/attack of dns (domain name server)
# Fraud 2 General fraud, whether orders, misuse of payment info, etc
# DDos 4 Distributed denial of service attack, whether through http requests, large ping attack, etc
# BruteForce 8 Brute force login attack
# Proxy 16 IP is a proxy like TOR or other proxy server
# Spam 32 Email, comment or other type of spam
# Vpn 64 IP is part of a VPN
# Hacking 128 General hacking outside of brute force attack (includes vulnerability scans, sql injection, etc.). Use port scan flag instead if it's just probe on ports.
# BadBot 256 Bad bot that is not honoring robots.txt or just flooding with too many requests, etc
# Compromised 512 The ip has been taken over by malware or botnet
# Phishing 1024 The ip is involved in phishing or spoofing
# Iot 2048 The ip has targeted an iot (Internet of Things) device
# PortScan 4096 Port scan
# See https://ipthreat.net/bulkreportformat for more information
# ```
[Definition]
# bypass action for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
#
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl -sSf "https://api.ipthreat.net/api/report" -X POST -H "Content-Type: application/json" -H "X-API-KEY: <ipthreat_apikey>" -d "{\"ip\":\"<ip>\",\"flags\":\"<ipthreat_flags>\",\"system\":\"<ipthreat_system>\",\"notes\":\"fail2ban\"}"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Option: ipthreat_apikey
# Notes Your API key from ipthreat.net
# Values: STRING Default: None
# Register for ipthreat [https://ipthreat.net], get api key and set below.
# You will need to set the flags and system in the action call in jail.conf
ipthreat_apikey =
# By default, the ipthreat system is the name of the fail2ban jail
ipthreat_system = <name>
# By default the ip threat flags is 8 (brute force), but you can override this per jail if desired
ipthreat_flags = 8

View File

@ -0,0 +1,87 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Output will be buffered until <lines> lines are available.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = if [ -f <tmpfile> ]; then
printf %%b "Hi,\n
These hosts have been banned by Fail2Ban.\n
`cat <tmpfile>`
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary from <fq-hostname>" <dest>
rm <tmpfile>
fi
printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
LINE=$( wc -l <tmpfile> | awk '{ print $1 }' )
if [ $LINE -ge <lines> ]; then
printf %%b "Hi,\n
These hosts have been banned by Fail2Ban.\n
`cat <tmpfile>`
\nRegards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary" <dest>
rm <tmpfile>
fi
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Default name of the chain
#
name = default
# Default number of lines that are buffered
#
lines = 5
# Default temporary file
#
tmpfile = /var/run/fail2ban/tmp-mail.txt
# Destination/Addressee of the mail
#
dest = root

View File

@ -0,0 +1,29 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Common settings for mail actions
#
# Users can override the defaults in mail-whois-common.local
[INCLUDES]
# Load customizations if any available
after = mail-whois-common.local
[DEFAULT]
#original character set of whois output will be sent to mail program
_whois = whois <ip> || echo "missing whois program"
# use heuristics to convert charset of whois output to a target
# character set before sending it to a mail program
# make sure you have 'file' and 'iconv' commands installed when opting for that
_whois_target_charset = UTF-8
_whois_convert_charset = (%(_whois)s) |
{ WHOIS_OUTPUT=$(cat) ; WHOIS_CHARSET=$(printf %%b "$WHOIS_OUTPUT" | file -b --mime-encoding -) ; printf %%b "$WHOIS_OUTPUT" | iconv -f $WHOIS_CHARSET -t %(_whois_target_charset)s//TRANSLIT - ; }
# choose between _whois and _whois_convert_charset in mail-whois-common.local
# or other *.local which include mail-whois-common.conf.
_whois_command = %(_whois)s
#_whois_command = %(_whois_convert_charset)s
[Init]

View File

@ -0,0 +1,93 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified-By: Yaroslav Halchenko to include grepping on IP over log files
#
[INCLUDES]
before = mail-whois-common.conf
helpers-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
Fail2Ban" | <mailcmd> "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban" | <mailcmd> "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
_ban_mail_content = ( printf %%b "Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n"
%(_whois_command)s;
printf %%b "\nLines containing failures of <ip> (max <grepmax>)\n";
%(_grep_logs)s;
printf %%b "\n
Regards,\n
Fail2Ban" )
actionban = %(_ban_mail_content)s | <mailcmd> "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Option: mailcmd
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
# Values: CMD
#
mailcmd = mail -E 'set escape' -s
# Default name of the chain
#
name = default
# Destinataire of the mail
#
dest = root
# Path to the log files which contain relevant lines for the abuser IP
#
logpath = /dev/null
# Number of log lines to include in the email
#
#grepmax = 1000
#grepopts = -m <grepmax>

View File

@ -0,0 +1,72 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = mail-whois-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n
`%(_whois_command)s`\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Default name of the chain
#
name = default
# Destination/Addressee of the mail
#
dest = root

View File

@ -0,0 +1,66 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n
Regards,\n
Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Default name of the chain
#
name = default
# Destination/Addressee of the mail
#
dest = root

View File

@ -0,0 +1,85 @@
## Version 2023/03/08
# Fail2Ban configuration file
#
# Mikrotik routerOS action to add/remove address-list entries
#
# Author: Duncan Bellamy <dunk@denkimushi.com>
# based on forum.mikrotik.com post by pakjebakmeel
#
# in the instructions:
# (10.0.0.1 is ip of mikrotik router)
# (10.0.0.2 is ip of fail2ban machine)
#
# on fail2ban machine:
# sudo mkdir /var/lib/fail2ban/ssh
# sudo chmod 700 /var/lib/fail2ban/ssh
# sudo ssh-keygen -N "" -f /var/lib/fail2ban/ssh/fail2ban_id_rsa
# sudo scp /var/lib/fail2ban/ssh/fail2ban_id_rsa.pub admin@10.0.0.1:/
# ssh admin@10.0.0.1
#
# on mikrotik router:
# /user add name=miki-f2b group=write address=10.0.0.2 password=""
# /user ssh-keys import public-key-file=fail2ban_id_rsa.pub user=miki-f2b
# /quit
#
# on fail2ban machine:
# (check password login fails)
# ssh miki-f2b@10.0.0.1
# (check private key works)
# sudo ssh -i /var/lib/fail2ban/ssh/fail2ban_id_rsa miki-f2b@10.0.0.1
#
# Then create rules on mikrorik router that use address
# list(s) maintained by fail2ban eg in the forward chain
# drop from address list, or in the forward chain drop
# from address list to server
#
# example extract from jail.local overriding some defaults
# action = mikrotik[keyfile="%(mkeyfile)s", user="%(muser)s", host="%(mhost)s", list="%(mlist)s"]
#
# ignoreip = 127.0.0.1/8 192.168.0.0/24
# mkeyfile = /etc/fail2ban/ssh/mykey_id_rsa
# muser = myuser
# mhost = 192.168.0.1
# mlist = BAD LIST
[Definition]
actionstart =
actionstop = %(actionflush)s
actionflush = %(command)s "/ip firewall address-list remove [find list=\"%(list)s\" comment~\"%(startcomment)s-*\"]"
actioncheck =
actionban = %(command)s "/ip firewall address-list add list=\"%(list)s\" address=<ip> comment=%(comment)s"
actionunban = %(command)s "/ip firewall address-list remove [find list=\"%(list)s\" comment=%(comment)s]"
command = ssh -l %(user)s -p%(port)s -i %(keyfile)s %(host)s
# Option: user
# Notes.: username to use when connecting to routerOS
user =
# Option: port
# Notes.: port to use when connecting to routerOS
port = 22
# Option: keyfile
# Notes.: ssh private key to use for connecting to routerOS
keyfile =
# Option: host
# Notes.: hostname or ip of router
host =
# Option: list
# Notes.: name of "address-list" to use on router
list = Fail2Ban
# Option: startcomment
# Notes.: used as a prefix to all comments, and used to match for flushing rules
startcomment = f2b-<name>
# Option: comment
# Notes.: comment to use on routerOS (must be unique as used for ip address removal)
comment = %(startcomment)s-<ip>
[Init]
name="%(__name__)s"

View File

@ -0,0 +1,144 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Russell Odom <russ@gloomytrousers.co.uk>
# Submits attack reports to myNetWatchman (http://www.mynetwatchman.com/)
#
# You MUST configure at least:
# <port> (the port that's being attacked - use number not name).
# <mnwlogin> (your mNW login).
# <mnwpass> (your mNW password).
#
# You SHOULD also provide:
# <myip> (your public IP address, if it's not the address of eth0)
# <protocol> (the protocol in use - defaults to tcp)
#
# Best practice is to provide <port> and <protocol> in jail.conf like this:
# action = mynetwatchman[port=1234,protocol=udp]
#
# ...and create "mynetwatchman.local" with contents something like this:
# [Init]
# mnwlogin = me@example.com
# mnwpass = SECRET
# myip = 10.0.0.1
#
# Another useful configuration value is <getcmd>, if you don't have wget
# installed (an example config for curl is given below)
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
#
# Note: We are currently using <time> for the timestamp because no tag is
# available to indicate the timestamp of the log message(s) which triggered the
# ban. Therefore the timestamps we are using in the report, whilst often only a
# few seconds out, are incorrect. See
# http://sourceforge.net/tracker/index.php?func=detail&aid=2017795&group_id=121032&atid=689047
#
actionban = MNWLOGIN=`perl -e '$s=shift;$s=~s/([\W])/"%%".uc(sprintf("%%2.2x",ord($1)))/eg;print $s' '<mnwlogin>'`
MNWPASS=`perl -e '$s=shift;$s=~s/([\W])/"%%".uc(sprintf("%%2.2x",ord($1)))/eg;print $s' '<mnwpass>'`
PROTOCOL=`awk '{IGNORECASE=1;if($1=="<protocol>"){print $2;exit}}' /etc/protocols`
if [ -z "$PROTOCOL" ]; then PROTOCOL=<protocol>; fi
DATETIME=`perl -e '@t=gmtime(<time>);printf "%%4d-%%02d-%%02d+%%02d:%%02d:%%02d",1900+$t[5],$t[4]+1,$t[3],$t[2],$t[1],$t[0]'`
<getcmd> "<mnwurl>?AT=2&AV=0&AgentEmail=$MNWLOGIN&AgentPassword=$MNWPASS&AttackerIP=<ip>&SrcPort=<srcport>&ProtocolID=$PROTOCOL&DestPort=<port>&AttackCount=<failures>&VictimIP=<myip>&AttackDateTime=$DATETIME" 2>&1 >> <tmpfile>.out && grep -q 'Attack Report Insert Successful' <tmpfile>.out && rm -f <tmpfile>.out
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Option: port
# Notes.: The target port for the attack (numerical). MUST be provided in
# the jail config, as it cannot be detected here.
# Values: [ NUM ] Default: ???
#
port = 0
# Option: mnwlogin
# Notes.: Your mNW login e-mail address. MUST be provided either in the jail
# config or in a .local file.
# Register at http://www.mynetwatchman.com/reg.asp
# Values: [ STRING ] Default: (empty)
#
mnwlogin =
# Option: mnwpass
# Notes.: The password corresponding to your mNW login e-mail address. MUST be
# provided either in the jail config or in a .local file.
# Values: [ STRING ] Default: (empty)
#
mnwpass =
# Option: myip
# Notes.: The target IP for the attack (your public IP). Should be overridden
# either in the jail config or in a .local file unless your PUBLIC IP
# is the first IP assigned to eth0
# Values: [ an IP address ] Default: Tries to find the IP address of eth0,
# which in most cases will be a private IP, and therefore incorrect
#
myip = `ip -4 addr show dev eth0 | grep inet | head -n 1 | sed -r 's/.*inet ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/'`
# Option: protocol
# Notes.: The protocol over which the attack is happening
# Values: [ tcp | udp | icmp | (any other protocol name from /etc/protocols) | NUM ] Default: tcp
#
protocol = tcp
# Option: agent
# Default: Fail2ban
agent = Fail2ban
# Option: getcmd
# Notes.: A command to fetch a URL. Should output page to STDOUT
# Values: CMD Default: wget
#
getcmd = wget --no-verbose --tries=3 --waitretry=10 --connect-timeout=10 --read-timeout=60 --retry-connrefused --output-document=- --user-agent=<agent>
# Alternative value:
# getcmd = curl --silent --show-error --retry 3 --connect-timeout 10 --max-time 60 --user-agent <agent>
# Option: srcport
# Notes.: The source port of the attack. You're unlikely to have this info, so
# you can leave the default
# Values: [ NUM ] Default: 0
#
srcport = 0
# Option: mnwurl
# Notes.: The report service URL on the mNW site
# Values: STRING Default: http://mynetwatchman.com/insertwebreport.asp
#
mnwurl = http://mynetwatchman.com/insertwebreport.asp
# Option: tmpfile
# Notes.: Base name of temporary files
# Values: [ STRING ] Default: /var/run/fail2ban/tmp-mynetwatchman
#
tmpfile = /var/run/fail2ban/tmp-mynetwatchman

View File

@ -0,0 +1,34 @@
## Version 2023/11/18
# Fail2ban Citrix Netscaler Action
# by Juliano Jeziorny
# juliano@jeziorny.eu
#
# The script will add offender IPs to a dataset on netscaler, the dataset can then be used to block the IPs at a cs/vserver or global level
# This dataset is then used to block IPs using responder policies on the netscaler.
#
# The script assumes using HTTPS with insecure certificate to access the netscaler,
# if you have a valid certificate installed remove the -k from the curl lines, or if you want http change it accordingly (and remove the -k)
#
# This action depends on curl
#
# You need to populate the 3 options inside Init
#
# ns_host: IP or hostname of netslcaer appliance
# ns_auth: username:password, suggest base64 encoded for a little added security (echo -n "username:password" | base64)
# ns_dataset: Name of the netscaler dataset holding the IPs to be blocked.
#
# For further details on how to use it please check http://blog.ckzone.eu/2017/01/fail2ban-action-for-citrix-netscaler.html
[Init]
ns_host =
ns_auth =
ns_dataset =
[Definition]
actionstart = curl -kH 'Authorization: Basic <ns_auth>' https://<ns_host>/nitro/v1/config
actioncheck =
actionban = curl -k -H 'Authorization: Basic <ns_auth>' -X PUT -d '{"policydataset_value_binding":{"name":"<ns_dataset>","value":"<ip>"}}' https://<ns_host>/nitro/v1/config/
actionunban = curl -H 'Authorization: Basic <ns_auth>' -X DELETE -k "https://<ns_host>/nitro/v1/config/policydataset_value_binding/<ns_dataset>?args=value:<ip>"

View File

@ -0,0 +1,18 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
# made active on all ports from original iptables.conf
# Modified: Alexander Belykh <albel727@ngs.ru>
# adapted for nftables
#
# Obsolete: superseded by nftables[type=allports]
[INCLUDES]
before = nftables.conf
[Definition]
type = allports

View File

@ -0,0 +1,18 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
# made active on all ports from original iptables.conf
# Modified: Alexander Belykh <albel727@ngs.ru>
# adapted for nftables
#
# Obsolete: superseded by nftables[type=multiport]
[INCLUDES]
before = nftables.conf
[Definition]
type = multiport

View File

@ -0,0 +1,209 @@
## Version 2025/08/08
# Fail2Ban configuration file
#
# Author: Daniel Black
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
# made active on all ports from original iptables.conf
# Modified: Alexander Belykh <albel727@ngs.ru>
# adapted for nftables
#
# This is a included configuration file and includes the definitions for the nftables
# used in all nftables based actions by default.
#
# The user can override the defaults in nftables-common.local
# Example: redirect flow to honeypot
#
# [Init]
# table_family = ip
# chain_type = nat
# chain_hook = prerouting
# chain_priority = -50
# blocktype = counter redirect to 2222
[INCLUDES]
after = nftables-common.local
[Definition]
# Option: type
# Notes.: type of the action.
# Values: [ multiport | allports ] Default: multiport
#
type = multiport
rule_match-custom =
rule_match-allports = meta l4proto \{ <protocol> \}
rule_match-multiport = $proto dport \{ $(echo '<port>' | sed s/:/-/g) \}
match = <rule_match-<type>>
# Option: rule_stat
# Notes.: statement for nftables filter rule.
# leaving it empty will block all (include udp and icmp)
# Values: nftables statement
#
rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype>
# optional iterator over protocol's:
_nft_for_proto-custom-iter =
_nft_for_proto-custom-done =
_nft_for_proto-allports-iter =
_nft_for_proto-allports-done =
_nft_for_proto-multiport-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'); do
_nft_for_proto-multiport-done = done
_nft_list = <nftables> -a list chain <table_family> <table> <chain>
_nft_get_handle_id = grep -oP '@<addr_set>\s+.*\s+\Khandle\s+(\d+)$'
_nft_add_set = <nftables> add set <table_family> <table> <addr_set> \{ type <addr_type>\;<addr_options> \}
<_nft_for_proto-<type>-iter>
<nftables> add rule <table_family> <table> <chain> %(rule_stat)s
<_nft_for_proto-<type>-done>
_nft_del_set = { %(_nft_list)s | %(_nft_get_handle_id)s; } | while read -r hdl; do
<nftables> delete rule <table_family> <table> <chain> $hdl; done
<nftables> delete set <table_family> <table> <addr_set>
# Option: _nft_shutdown_table
# Notes.: command executed after the stop in order to delete table (it checks that no sets are available):
# Values: CMD
#
_nft_shutdown_table = { <nftables> list table <table_family> <table> | grep -qP '^\s+set\s+'; } || {
<nftables> delete table <table_family> <table>
}
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = <nftables> add table <table_family> <table>
<nftables> -- add chain <table_family> <table> <chain> \{ type <chain_type> hook <chain_hook> priority <chain_priority> \; \}
%(_nft_add_set)s
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action);
# uses `nft flush set ...` and as fallback (e. g. unsupported) recreates the set (with references)
# Values: CMD
#
actionflush = { <nftables> flush set <table_family> <table> <addr_set> 2> /dev/null; } || {
%(_nft_del_set)s
%(_nft_add_set)s
}
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = %(_nft_del_set)s
<_nft_shutdown_table>
# Option: actioncheck
# Notes.: command executed once in error case by other command (during the check/restore sane environment process)
# Values: CMD
#
actioncheck = <nftables> list chain <table_family> <table> <chain> | grep -q '@<addr_set>[ \t]'
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = <nftables> add element <table_family> <table> <addr_set> \{ <ip> \}
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = <nftables> delete element <table_family> <table> <addr_set> \{ <ip> \}
[Init]
# Option: table
# Notes.: main table to store chain and sets (automatically created on demand)
# Values: STRING Default: f2b-table
table = f2b-table
# Option: table_family
# Notes.: address family to work in
# Values: [ip | ip6 | inet] Default: inet
table_family = inet
# Option: chain
# Notes.: main chain to store rules
# Values: STRING Default: f2b-chain
chain = f2b-chain
# Option: chain_type
# Notes.: refers to the kind of chain to be created
# Values: [filter | route | nat] Default: filter
#
chain_type = filter
# Option: chain_hook
# Notes.: refers to the kind of chain to be created
# Values: [ prerouting | input | forward | output | postrouting ] Default: input
#
chain_hook = input
# Option: chain_priority
# Notes.: priority in the chain.
# Values: NUMBER Default: -1
#
chain_priority = -1
# Option: addr_type
# Notes.: address type to work with
# Values: [ipv4_addr | ipv6_addr] Default: ipv4_addr
#
addr_type = ipv4_addr
# Default name of the filtering set
#
name = default
# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ] Default:
#
port = ssh
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp ] Default: tcp
#
protocol = tcp
# Option: blocktype
# Note: This is what the action does with rules. This can be any jump target
# as per the nftables man page (section 8). Common values are drop,
# reject, reject with icmpx type host-unreachable, redirect to 2222
# Values: STRING
blocktype = reject
# Option: nftables
# Notes.: Actual command to be executed, including common to all calls options
# Values: STRING
nftables = nft
# Option: addr_set
# Notes.: The name of the nft set used to store banned addresses
# Values: STRING
addr_set = addr-set-<name>
# Option: addr_family
# Notes.: The family of the banned addresses
# Values: [ ip | ip6 ]
addr_family = ip
# Option: addr_options
# Notes: Additional options for the addr-set, by default allows to store CIDR or address ranges.
# Can be set to empty value to create simple addresses set.
addr_options = <sp>flags interval\;
[Init?family=inet6]
addr_family = ip6
addr_type = ipv6_addr
addr_set = addr6-set-<name>

View File

@ -0,0 +1,118 @@
## Version 2022/08/06
# Fail2Ban configuration file for black-listing via nginx
#
# Author: Serg G. Brester (aka sebres)
#
# To use 'nginx-block-map' action you should define some special blocks in your nginx configuration,
# and use it hereafter in your locations (to notify fail2ban by failure, resp. nginx by ban).
#
# Example (argument "token_id" resp. cookie "session_id" used here as unique identifier for user):
#
# http {
# ...
# # maps to check user is blacklisted (banned in f2b):
# #map $arg_token_id $blck_lst_tok { include blacklisted-tokens.map; }
# map $cookie_session_id $blck_lst_ses { include blacklisted-sessions.map; }
# ...
# # special log-format to notify fail2ban about failures:
# log_format f2b_session_errors '$msec failure "$cookie_session_id" - $remote_addr - $remote_user '
# ;# '"$request" $status $bytes_sent '
# # '"$http_referer" "$http_user_agent"';
#
# # location checking blacklisted values:
# location ... {
# # check banned sessionid:
# if ($blck_lst_ses != "") {
# try_files "" @f2b-banned;
# }
# ...
# # notify fail2ban about a failure inside nginx:
# error_page 401 = @notify-f2b;
# ...
# }
# ...
# # location for return with "403 Forbidden" if banned:
# location @f2b-banned {
# default_type text/html;
# return 403 "<br/><center>
# <b style=\"color:red; font-size:18pt; border:2pt solid black; padding:5pt;\">
# You are banned!</b></center>";
# }
# ...
# # location to notify fail2ban about a failure inside nginx:
# location @notify-f2b {
# access_log /var/log/nginx/f2b-auth-errors.log f2b_session_errors;
# }
# }
# ...
#
# Note that quote-character (and possibly other special characters) are not allowed currently as session-id.
# Thus please add any session-id validation rule in your locations (or in the corresponding backend-service),
# like in example below:
#
# location ... {
# if ($cookie_session_id !~ "^[\w\-]+$") {
# return 403 "Wrong session-id"
# }
# ...
# }
#
# The parameters for jail corresponding log-format (f2b_session_errors):
#
# [nginx-blck-lst]
# filter =
# datepattern = ^Epoch
# failregex = ^ failure "<F-ID>[^"]+</F-ID>" - <ADDR>
# usedns = no
#
# The same log-file can be used for IP-related jail (additionally to session-related, to ban very bad IPs):
#
# [nginx-blck-ip]
# maxretry = 100
# filter =
# datepattern = ^Epoch
# failregex = ^ failure "[^"]+" - <ADDR>
# usedns = no
#
[Definition]
# path to configuration of nginx (used to target nginx-instance in multi-instance system,
# and as path for the blacklisted map):
srv_cfg_path = /etc/nginx/
# cmd-line arguments to supply to test/reload nginx:
#srv_cmd = nginx -c %(srv_cfg_path)s/nginx.conf
srv_cmd = nginx
# pid file (used to check nginx is running):
srv_pid = /run/nginx.pid
# command used to check whether nginx is running and configuration is valid:
srv_is_running = [ -f "%(srv_pid)s" ]
srv_check_cmd = %(srv_is_running)s && %(srv_cmd)s -qt
# first test nginx is running and configuration is correct, hereafter send reload signal:
blck_lst_reload = %(srv_check_cmd)s; if [ $? -eq 0 ]; then
%(srv_cmd)s -s reload; if [ $? -ne 0 ]; then echo 'reload failed.'; fi;
fi;
# map-file for nginx, can be redefined using `action = nginx-block-map[blck_lst_file="/path/file.map"]`:
blck_lst_file = %(srv_cfg_path)s/blacklisted-sessions.map
# Action definition:
actionstart_on_demand = false
actionstart = touch '%(blck_lst_file)s'
actionflush = truncate -s 0 '%(blck_lst_file)s'; %(blck_lst_reload)s
actionstop = %(actionflush)s
actioncheck =
_echo_blck_row = printf '\%%s 1;\n' "<fid>"
actionban = %(_echo_blck_row)s >> '%(blck_lst_file)s'; %(blck_lst_reload)s
actionunban = id=$(%(_echo_blck_row)s | sed -e 's/[]\/$*.^|[]/\\&/g'); sed -i "/^$id$/d" %(blck_lst_file)s; %(blck_lst_reload)s

View File

@ -0,0 +1,27 @@
# /etc/fail2ban/action.d/nginx-pathfinder-action.conf
#
# Ação Híbrida Pathfinder Proxy (2026).
# 1. Bloqueia o IP no Firewall (UFW).
# 2. Insere o IP no snippet 'blacklist.conf' do Nginx para bloqueio de aplicação.
# *****************************************************************************
[Definition]
# Comando executado ao iniciar a jail
actionstart = touch /etc/nginx/snippets/blacklist.conf
# Comando de banimento: Firewall + Nginx Blacklist
# Usamos 'prepend' no UFW para garantir que o bloqueio venha antes de qualquer permissão.
actionban = ufw prepend deny from <ip> to any
printf "deny <ip>;\n" >> /etc/nginx/snippets/blacklist.conf
nginx -s reload
# Comando de desbanimento: Remove do Firewall e do arquivo Nginx
# O sed remove a linha exata 'deny IP;' do snippet.
actionunban = ufw delete deny from <ip> to any
sed -i "/deny <ip>;/d" /etc/nginx/snippets/blacklist.conf
nginx -s reload
[Init]
# Nome da jail para logs de auditoria
name = nginx-pathfinder

View File

@ -0,0 +1,62 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# NetBSD npf ban/unban
#
# Author: Nils Ratusznik <nils@NetBSD.org>
# Based on pf.conf action file
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
# we don't enable NPF automatically, as it will be enabled elsewhere
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
# we don't disable NPF automatically either
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = /sbin/npfctl table <tablename> add <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
# note -r option used to remove matching rule
actionunban = /sbin/npfctl table <tablename> rem <ip>
[Init]
# Option: tablename
# Notes.: The pf table name.
# Values: [ STRING ]
#
tablename = fail2ban

View File

@ -0,0 +1,115 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Andrew St. Jean
#
# Use nsupdate to perform dynamic DNS updates on a BIND zone file.
# One may want to do this to update a local RBL with banned IP addresses.
#
# Options
#
# domain DNS domain that will appear in nsupdate add and delete
# commands.
#
# ttl The time to live (TTL) in seconds of the TXT resource
# record.
#
# rdata Data portion of the TXT resource record.
#
# nsupdatecmd Full path to the nsupdate command.
#
# keyfile Full path to TSIG key file used for authentication between
# nsupdate and BIND.
#
# Create an nsupdate.local to set at least the <domain> and <keyfile>
# options as they don't have default values.
#
# The ban and unban commands assume nsupdate will authenticate to the BIND
# server using a TSIG key. The full path to the key file must be specified
# in the <keyfile> parameter. Use this command to generate your TSIG key.
#
# dnssec-keygen -a HMAC-MD5 -b 256 -n HOST <key_name>
#
# Replace <key_name> with some meaningful name.
#
# This command will generate two files. Specify the .private file in the
# <keyfile> option. Note that the .key file must also be present in the same
# directory for nsupdate to use the key.
#
# Don't forget to add the key and appropriate allow-update or update-policy
# option to your named.conf file.
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = echo <ip> | awk -F. '{print "prereq nxrrset "$4"."$3"."$2"."$1".<domain> TXT"; print "update add "$4"."$3"."$2"."$1".<domain> <ttl> IN TXT \"<rdata>\""; print "send"}' | <nsupdatecmd> -k <keyfile>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = echo <ip> | awk -F. '{print "update delete "$4"."$3"."$2"."$1".<domain>"; print "send"}' | <nsupdatecmd> -k <keyfile>
[Init]
# Option: domain
# Notes.: DNS domain that nsupdate will update.
# Values: STRING
#
domain =
# Option: ttl
# Notes.: time to live (TTL) in seconds of TXT resource record
# added by nsupdate.
# Values: NUM
#
ttl = 60
# Option: rdata
# Notes.: data portion of the TXT resource record added by nsupdate.
# Values: STRING
#
rdata = Your IP has been banned
# Option: nsupdatecmd
# Notes.: specifies the full path to the nsupdate program that dynamically
# updates BIND zone files.
# Values: CMD
#
nsupdatecmd = /usr/bin/nsupdate
# Option: keyfile
# Notes.: specifies the full path to the file containing the
# TSIG key for communicating with BIND.
# Values: STRING
#
keyfile =

View File

@ -0,0 +1,91 @@
## Version 2023/02/16
#
# Fail2Ban action configuration for OPNsense
# Author: https://linuxserver.io/
#
# Please ensure jail.local permission are secure (640) as it contains your OPNsense API key
#
# OPNsense API Key/Secret guide: https://docs.opnsense.org/development/how-tos/api.html
#
# This action maintains an OPNsense HOST group alias.
#
# Configure OPNsense with:
# A correctly named empty HOST group alias.
# An associated firewall rule.
#
# In most instances the OPNsense rule will likely take the form of a INBOUND WAN DROP but specifics are left to user discretion.
#
# WARNING: This action allows connections to default OPNsense installs deployed with self signed TLS certificates.
# If required disable this by setting `allow_insecure = false` in your `jail.local`
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
#actionstart =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
#actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
#actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl <_allow_insecure> -s -u "<key>":"<secret>" -H "Content-Type: application/json" -d '{"address":"<ip>"}' https://<firewall>/api/firewall/alias_util/add/<alias>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = curl <_allow_insecure> -s -u "<key>":"<secret>" -H "Content-Type: application/json" -d '{"address":"<ip>"}' https://<firewall>/api/firewall/alias_util/delete/<alias>
# Internal variable handler for `allow_insecure`
_allow_insecure = $(if [ '<allow_insecure>' = true ]; then echo ' -k '; else echo ''; fi;)
[Init]
# Option: alias
# Notes.: The OPNsense host group name to add the Fail2ban IP to.
# Values: [ STRING ]
#
alias =
# Option: firewall
# Notes.: Your OPNsense IP or DNS name.
# Values: [ STRING ]
#
firewall =
# Option: key
# Notes.: Your OPNsense user key.
# Values: [ STRING ]
#
key =
# Option: secret
# Notes.: Your OPNsense user secret.
# Values: [ STRING ]
#
secret =
# Option: allow_insecure
# Notes.: Allow connections to default OPNsense installs deployed with self signed TLS certificates.
# Values: [ BOOLEAN ]
#
allow_insecure = true

View File

@ -0,0 +1,17 @@
## Version 2022/08/06
# Fail2Ban configuration file for using afctl on Mac OS X Server 10.5
#
# Anonymous author
# http://www.fail2ban.org/wiki/index.php?title=HOWTO_Mac_OS_X_Server_(10.5)&diff=prev&oldid=4081
#
# Ref: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/afctl.8.html
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = /usr/libexec/afctl -a <ip> -t <bantime>
actionunban = /usr/libexec/afctl -r <ip>
actionprolong = %(actionunban)s && %(actionban)s

View File

@ -0,0 +1,88 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Nick Munger
# Modified by: Andy Fragen and Daniel Black
#
# Mod for OS X, using random rulenum as OSX ipfw doesn't include tables
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# Values: CMD
#
actionban = ipfw add <rulenum> set <setnum> <blocktype> log <block> from <ip> to <dst> <port>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# Values: CMD
#
actionunban = ipfw delete `ipfw -S list | grep -i 'set <setnum> <blocktype> log <block> from <ip> to <dst>' | awk '{print $1;}'`
[Init]
# Option: port
# Notes.: specifies port to block. Can be blank however may require block="ip"
# Values: [ NUM | STRING ]
#
port = ssh
# Option: dst
# Notes.: the local IP address of the network interface
# Values: IP, any, me or anything support by ipfw as a dst
#
dst = me
# Option: block
# Notes: This is how much to block.
# Can be "ip", "tcp", "udp" or various other options.
# Values: STRING
block = tcp
# Option: blocktype
# Notes.: How to block the traffic. Use a action from man 8 ipfw
# Common values: deny, unreach port, reset
# Values: STRING
#
blocktype = unreach port
# Option: set number
# Notes.: The ipset number this is added to.
# Values: 0-31
setnum = 10
# Option: number for ipfw rule
# Notes: This is meant to be automatically generated and not overwritten
# Values: Random value between 10000 and 12000
rulenum="`echo $((RANDOM%%2000+10000))`"
# Duplicate prevention mechanism
#rulenum = "`a=$((RANDOM%%2000+10000)); while ipfw show | grep -q ^$a\ ; do a=$((RANDOM%%2000+10000)); done; echo $a`"

View File

@ -0,0 +1,129 @@
## Version 2023/12/10
# Fail2Ban configuration file
#
# OpenBSD pf ban/unban
#
# Author: Nick Hilliard <nick@foobar.org>
# Modified by: Alexander Koeppe making PF work seamless and with IPv4 and IPv6
# Modified by: Balazs Mateffy adding allproto option so all traffic gets blocked from the malicious source
#
#
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
# we don't enable PF automatically; to enable run pfctl -e
# or add `pf_enable="YES"` to /etc/rc.conf (tested on FreeBSD)
# also, these rulesets are loaded into (nested) anchors
# to enable them, add as wildcard:
# anchor "f2b/*"
# or using jail names:
# anchor f2b {
# anchor name1
# anchor name2
# ...
# }
# to your main pf ruleset, where "namei" are the names of the jails
# which invoke this action
# to block all protocols use the pf[protocol=all] option
actionstart = echo "table <<tablename>-<name>> persist counters" | <pfctl> -f-
port="<port>"; if [ "$port" != "" ] && case "$port" in \{*) false;; esac; then port="{$port}"; fi
protocol="<protocol>"; if [ "$protocol" != "all" ]; then protocol="proto $protocol"; else protocol=all; fi
echo "<block> $protocol from <<tablename>-<name>> to <actiontype>" | <pfctl> -f-
# Option: start_on_demand - to start action on demand
# Example: `action=pf[actionstart_on_demand=true]`
actionstart_on_demand = false
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
# we only disable PF rules we've installed prior
actionstop = <pfctl> -sr 2>/dev/null | grep -v <tablename>-<name> | <pfctl> -f-
%(actionflush)s
<pfctl> -t <tablename>-<name> -T kill
# Option: actionflush
# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
# Values: CMD
#
actionflush = <pfctl> -t <tablename>-<name> -T flush
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = <pfctl> -sr | grep -q <tablename>-<name>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = <pfctl> -t <tablename>-<name> -T add <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
# note -r option used to remove matching rule
actionunban = <pfctl> -t <tablename>-<name> -T delete <ip>
# Option: pfctl
#
# Use anchor as jailname to manipulate affected rulesets only.
# If more parameter expected it can be extended with `pf[pfctl="<known/pfctl> ..."]`
#
pfctl = pfctl -a f2b/<name>
[Init]
# Option: tablename
# Notes.: The pf table name.
# Values: [ STRING ]
#
tablename = f2b
# Option: block
#
# The action you want pf to take.
# Probably, you want "block quick", but adjust as needed.
# If you want to log all blocked use "blog log quick"
block = block quick
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | ipv6-icmp ] Default: tcp
#
protocol = tcp
# Option: actiontype
# Notes.: defines additions to the blocking rule
# Values: leave empty to block all attempts from the host
# Default: Value of the multiport
actiontype = <multiport>
# Option: allports
# Notes.: default addition to block all ports
# Usage.: use in jail config: "banaction = pf[actiontype=<allports>]"
allports = any
# Option: multiport
# Notes.: addition to block access only to specific ports
# Usage.: use in jail config: "banaction = pf[actiontype=<multiport>]"
multiport = any port $port

View File

@ -0,0 +1,61 @@
## Version 2022/08/15
#
# Fail2Ban action configuration for Pushover
# Author: https://linuxserver.io/
#
# Please ensure jail.local permission are secure as it will contain your Pushover API key
#
# This action requires the setup of a Pushover Application/API Token. This will require an account at https://pushover.net/
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
# Comment out this action as necessary
actionstart = curl -s -F "token=<token>" -F "user=<user>" -F "title=[Fail2Ban] <name>" -F "message=Jail <name> has been started successfully." https://api.pushover.net/1/messages
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
# Comment out this action as necessary
actionstop = curl -s -F "token=<token>" -F "user=<user>" -F "title=[Fail2Ban] <name>" -F "message=Jail <name> has been stopped." https://api.pushover.net/1/messages
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = curl -s -F "token=<token>" -F "user=<user>" -F "title=[Fail2Ban] <name>" -F "message=Banned IP: <ip> Lines containing IP: `grep '<ip>' <logpath>`" https://api.pushover.net/1/messages
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = curl -s -F "token=<token>" -F "user=<user>" -F "title=[Fail2Ban] <name>" -F "message=Unbanned IP: <ip> Lines containing IP: `grep '<ip>' <logpath>`" https://api.pushover.net/1/messages
[Init]
# Option: token
# Notes.: The Pushover API Token/Key setup for Fail2Ban.
# Values: [ STRING ]
#
token =
# Option: user
# Notes.: Your Pushover User Key.
# Values: [ STRING ]
#
user =

View File

@ -0,0 +1,30 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Michael Gebetsroither
#
# This is for blocking whole hosts through blackhole routes.
#
# PRO:
# - Works on all kernel versions and as no compatibility problems (back to debian lenny and WAY further).
# - It's FAST for very large numbers of blocked ips.
# - It's FAST because it Blocks traffic before it enters common iptables chains used for filtering.
# - It's per host, ideal as action against ssh password bruteforcing to block further attack attempts.
# - No additional software required beside iproute/iproute2
#
# CON:
# - Blocking is per IP and NOT per service, but ideal as action against ssh password bruteforcing hosts
[Definition]
actionban = ip route add <blocktype> <ip>
actionunban = ip route del <blocktype> <ip>
actioncheck =
actionstart =
actionstop =
[Init]
# Option: blocktype
# Note: Type can be blackhole, unreachable and prohibit. Unreachable and prohibit correspond to the ICMP reject messages.
# Values: STRING
blocktype = unreachable

View File

@ -0,0 +1,100 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = sendmail-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The jail <name> has been started successfully.\n
Output will be buffered until <lines> lines are available.\n
Regards,\n
Fail2Ban" | <mailcmd>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = if [ -f <tmpfile> ]; then
printf %%b "Subject: [Fail2Ban] <name>: summary from <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
These hosts have been banned by Fail2Ban.\n
`cat <tmpfile>`
Regards,\n
Fail2Ban" | <mailcmd>
rm <tmpfile>
fi
printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname>
From: Fail2Ban <<sender>>
To: <dest>\n
Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban" | <mailcmd>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
LINE=$( wc -l <tmpfile> | awk '{ print $1 }' )
if [ $LINE -ge <lines> ]; then
printf %%b "Subject: [Fail2Ban] <name>: summary from <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
These hosts have been banned by Fail2Ban.\n
`cat <tmpfile>`
Regards,\n
Fail2Ban" | <mailcmd>
rm <tmpfile>
fi
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Default name of the chain
#
name = default
# Default number of lines that are buffered
#
lines = 5
# Default temporary file
#
tmpfile = /var/run/fail2ban/tmp-mail.txt

View File

@ -0,0 +1,78 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Common settings for sendmail actions
#
# Users can override the defaults in sendmail-common.local
[INCLUDES]
after = sendmail-common.local
[Definition]
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
Fail2Ban" | <mailcmd>
# Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD
#
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The jail <name> has been stopped.\n
Regards,\n
Fail2Ban" | <mailcmd>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban =
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban =
[Init]
# Your system mail command
#
mailcmd = /usr/sbin/sendmail -f "<sender>" "<dest>"
# Recipient mail address
#
dest = root
# Sender mail address
#
sender = fail2ban
# Sender display name
#
sendername = Fail2Ban

View File

@ -0,0 +1,60 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Viktor Szépe
#
#
[INCLUDES]
before = sendmail-common.conf
helpers-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionban
# Notes.: Command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# You need to install geoiplookup and the GeoLite or GeoIP databases.
# (geoip-bin and geoip-database in Debian)
# The host command comes from bind9-host package.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n
http://bgp.he.net/ip/<ip>
http://www.projecthoneypot.org/ip_<ip>
http://whois.domaintools.com/<ip>\n\n
Country:`geoiplookup -f /usr/share/GeoIP/GeoIP.dat "<ip>" | cut -d':' -f2-`
AS:`geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat "<ip>" | cut -d':' -f2-`
hostname: <ip-host>\n\n
Lines containing failures of <ip> (max <grepmax>)\n";
%(_grep_logs)s;
printf %%b "\n
Regards,\n
Fail2Ban" ) | <mailcmd>
[Init]
# Default name of the chain
#
name = default
# Path to the log files which contain relevant lines for the abuser IP
#
logpath = /dev/null
# Number of log lines to include in the email
#
#grepmax = 1000
#grepopts = -m <grepmax>

View File

@ -0,0 +1,42 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = sendmail-common.conf
mail-whois-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n
`%(_whois_command)s`\n\n
Matches for <name> with <ipjailfailures> failures IP:<ip>\n
<ipjailmatches>\n\n
Regards,\n
Fail2Ban" | <mailcmd>
[Init]
# Default name of the chain
#
name = default

View File

@ -0,0 +1,42 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = sendmail-common.conf
mail-whois-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n
`%(_whois_command)s`\n\n
Matches with <ipfailures> failures IP:<ip>\n
<ipmatches>\n\n
Regards,\n
Fail2Ban" | <mailcmd>
[Init]
# Default name of the chain
#
name = default

View File

@ -0,0 +1,53 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = sendmail-common.conf
mail-whois-common.conf
helpers-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n"
%(_whois_command)s;
printf %%b "\nLines containing failures of <ip> (max <grepmax>)\n";
%(_grep_logs)s;
printf %%b "\n
Regards,\n
Fail2Ban" ) | <mailcmd>
[Init]
# Default name of the chain
#
name = default
# Path to the log files which contain relevant lines for the abuser IP
#
logpath = /dev/null
# Number of log lines to include in the email
#
#grepmax = 1000
#grepopts = -m <grepmax>

View File

@ -0,0 +1,42 @@
## Version 2022/08/06
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#
[INCLUDES]
before = sendmail-common.conf
mail-whois-common.conf
[Definition]
# bypass ban/unban for restored tickets
norestored = 1
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
The IP <ip> has just been banned by Fail2Ban after
<failures> attempts against <name>.\n\n
Here is more information about <ip> :\n
`%(_whois_command)s`\n\n
Matches:\n
<matches>\n\n
Regards,\n
Fail2Ban" | <mailcmd>
[Init]
# Default name of the chain
#
name = default

Some files were not shown because too many files have changed in this diff Show More