Download
Código-fonte:
curl -O https://minirepo.minidc.com.br/download/minirepo.tar.gz
Binário compilado:
curl -O https://minirepo.minidc.com.br/download/minirepo-bin.tar.gz
O download é liberado apenas para IPs autorizados.
Changelog
-
v2.14.0 Rebrand para miniProxy 27/06/2026- Produto renomeado de "HAProxy Admin" para **miniProxy**. Logos SVG em static/img (miniproxy-logo/-dark/-icon), do miniproxy.zip entregue. - base.html: logo na sidebar (logo-dark) + favicon (icon). login.html: logo + favicon. - Titulos de todas as paginas, docstring do app e markers de comentario gerados (WAF/Cloudflare/CRS) passam a usar "miniProxy". As regex de remocao casam em "(gerenciado", entao blocos antigos com o nome anterior continuam sendo limpos. - miniproxy.zip adicionado ao .gitignore (logos ficam versionados em static/img).
-
v2.13.0 Portas TCP: preservar porta no destino (FTP passivo 24/06/2026- A UI so permitia destino com porta fixa; FTP passivo precisa encaminhar cada porta para a MESMA porta no backend (port-preserving), que em HAProxy e `server <ip>` sem porta. - `build_tcp_block`: porta vazia -> `server <ip>` (sem porta, sem check). - `tcp_add`/`tcp_add_server`: checkbox `srv_preserve` (dispensa a porta do destino). - tcp.html: switch "Preservar porta" nos modais (desabilita o campo de porta) e badge "mesma porta" na listagem. `parse_tcp_proxies` ja lia servidores sem porta.
-
v2.12.0 Remover prefixo do path (gateways 23/06/2026- Gateway por path encaminhava a URL inteira (/news/healthcheck) ao microservico, que atende na raiz (/healthcheck) -> 404 da app. - Opcao "Remover prefixo" por regra de path: adiciona no backend de destino `http-request set-path %[path,regsub(^<prefixo>,),regsub(^$,/)] if { path_beg <prefixo> }` (escopado pelo prefixo; nao quebra roteamento nem parse, pois fica no backend). - Helpers set_path_strip/path_strip_active/_backend_bounds; rota POST /domains/path/strip; checkbox na criacao (add_domain_path) e toggle por regra na UI.
-
v2.11.0 Alterar backend do dominio + 404 limpo p/ gateways 23/06/2026- Contexto: dominio gateway por path (api2) sem backend principal -> trafego nao mapeado caia no default_backend vazio (bk_default/<NOSRV>) -> 503 em /, /favicon.ico etc. - Rota `POST /domains/backend` + botao "Backend" no card: troca o use_backend principal do dominio (ou insere, antes do default_backend e depois das regras de path) sem remover/recriar. `_set_domain_backend` faz replace-ou-insert. - Opcao "404 limpo": `ensure_bk_404` cria `backend bk_404` com `http-request return status 404` (sem servidor) -> resposta 404 limpa para paths nao mapeados, em vez de 503.
-
v2.10.0 Contador do WAF na dashboard 22/06/2026- Novo card "WAF" na linha de stats: contador de eventos recentes do WAF (matches no tail do log do coraza) + nº de dominios protegidos/em bloqueio; "off" se a infra do WAF nao estiver instalada. Linka para a aba WAF. - Atualiza ao vivo: api_status passou a devolver waf_events (refresh de 5s). - Linha de stats passou de 4 para 5 cards (col-6 col-md).
-
v2.9.0 Graficos historicos dos backends na dashboard 22/06/2026- As metricas do card Backends (scur, bin, bout, rtime, check_duration) ja eram persistidas em server_stats; faltava visualizar conexoes e in/out. - Dashboard: 2 novos graficos por servidor - "Conexoes por Servidor" (scur) e "Trafego In/Out por Servidor (KB/s)" (taxa = delta dos contadores bin/bout / dt, reset de contador clampado em 0; in solido, out tracejado). So frontend; usa a api_history_servers existente.
-
v2.8.0 Cloudflare por dominio 22/06/2026- Refatorado de "modo global" para **flag por dominio** (botao CF na aba Dominios; `cloudflare.json` guarda a lista de ACLs; `cf_domains.lst` os hosts). - Bloco gerenciado escopado por `acl cf_domain hdr(host) -i -f cf_domains.lst`: IP real (`set-src` so para dominio CF vindo de cf_src+header -> anti-spoof nos diretos), atendimento na :80 em Flexible (loopback) e bloqueio de acesso direto (opcional, global). - Redirect escopado: dominio NAO-CF sempre redireciona; dominio CF so quando nao veio com XFP=https (evita loop e permite servir via loopback). - Rota `POST /domains/cloudflare` (toggle por dominio); aba Cloudflare passou a ser ajustes globais (atualizar IPs, bloqueio) + lista de dominios CF. remove_domain limpa a flag. - setup.sh volta ao redirect canonico (o XFP-aware agora e por-dominio no app).
-
v2.7.1 Cloudflare modo Flexible (servir conteudo na :80 22/06/2026- Quando o Cloudflare esta em SSL/TLS **Flexible** (fala HTTP com a origem) e nao da pra mudar para Full, o redirect XFP-aware sozinho deixaria a :80 sem backend de conteudo. Novo toggle "Modo Flexible": injeta `use_backend bk_https_loopback if XFP=https` no ft_http e o backend `bk_https_loopback` (`server 127.0.0.1:443 ssl sni req.hdr(host)`), reaproveitando todo o pipeline do ft_https (roteamento, WAF, restricoes). O CF-Connecting-IP e propagado pelo loopback, preservando o IP real (set-src no ft_https, cf_src inclui 127/8 e ::1). - Fix: a checagem de existencia do backend usava substring ('use_backend bk_...' contem 'backend bk_...'); passou a usar regex de inicio de linha.
-
v2.7.0 Integracao Cloudflare (IP real + lockdown 22/06/2026- Redirect http->https consciente de proxy (`X-Forwarded-Proto`) -> mata o loop ERR_TOO_MANY_REDIRECTS do Cloudflare em modo Flexible. Aplicado no servidor e no setup.sh. - Aba **Cloudflare**: estado em /etc/haproxy/cloudflare.json. - `fetch_cloudflare_ips()` baixa ips-v4/ips-v6 para /etc/haproxy/cloudflare_ips.lst. - `apply_cloudflare()` injeta bloco em ft_http/ft_https: `acl cf_src src -f ...`, `set-src hdr(CF-Connecting-IP)` (IP real) e, opcional, `deny if !cf_src` (lockdown, com excecao do desafio LE via condicao inline path_beg). - Rotas: GET /cloudflare, POST /cloudflare/save, POST /cloudflare/refresh-ips. - Restaurar o IP real faz logs por dominio, restricao por IP, rate-limit e WAF operarem sobre o IP do visitante (set-src roda antes do roteamento).
-
v2.6.2 Fix wizard: config sem LF final ao criar dominio sem WAF/restricao 22/06/2026- `provision_domain` so garantia o `\n` final do haproxy.cfg quando havia restricao ou WAF; criar dominio "Sem WAF" e sem restricao gerava config sem LF na ultima linha ("Missing LF on last line") e nada era aplicado. Adicionado o `\n` final apos o join.
-
v2.6.1 Fix setup-waf.sh: injecao do filter quebrava o bind 22/06/2026- O sed que injeta `filter spoe` em ft_https casava o bind so ate `ssl`, fazendo `crt ... alpn ...` vazar para a linha do filter -> "unknown keyword 'crt'" e haproxy.cfg invalido em instalacao nova. Regex passa a casar a linha inteira (`...ssl.*`) para o `&` reproduzir o bind completo.
-
v2.6.0 Backend em HTTPS configuravel 21/06/2026- `server_ssl_opt(enabled)` -> ` ssl verify none sni ssl_fc_sni`; aplicado em add_backend_web, add_server, edit_server e provision_domain (novo backend) via campo de form. - `parse_all_backends` agora detecta `ssl` por servidor; o modal de edicao reflete o estado. - UI: toggle "Backend em HTTPS (TLS na 443)" nos modais de backend/servidor (servers.html) e no wizard de dominio (domains.html). - Contexto: dominios cujo upstream responde so em 443 (ex. impecavel.com.br/cwp45) davam 502 por o HAProxy mandar HTTP puro na porta TLS; agora basta marcar HTTPS.
-
v2.5.0 Logs de acesso/erro por dominio 21/06/2026- `ft_https`: `http-request capture req.hdr(Host)` + `log-format` parseavel (`status=%ST ... vhost=%[capture.req.hdr(0)]`) para permitir filtrar por dominio. - Removido `log global` do spoe-agent (coraza.cfg) - silencia o ruido de debug do SPOE que dominava o log do HAProxy (~65% do volume). - `read_domain_logs(hosts, kind)` filtra por Host e status (access/erro 4xx-5xx), lendo de /var/log/haproxy.log ou journald. Rota `GET /api/domain-logs`. - UI: botao "Logs" por dominio -> modal com abas Acesso/Erros, busca e tail ao vivo. - setup.sh (ft_https) e setup-waf.sh (SPOE sem log global) alinhados.
-
v2.4.0 Wizard "Criar Dominio" 21/06/2026- Nova rota `provision_domain` (POST /domains/provision) que orquestra num so passo: backend (novo/existente) + ACL/use_backend com aliases + restricao IP/DDNS opcional + WAF (deteccao/bloqueio) numa unica validacao/reload, e depois o certificado Let's Encrypt para todos os hosts (best-effort: o dominio fica criado mesmo se o cert falhar). Resumo por etapa via flash. - Modal "Adicionar Dominio" reescrito como wizard (Dominio / Backend / SSL / WAF / Acesso).
-
v2.3.0 CRS em disco + atualizacao sem recompilar 21/06/2026- O CRS deixa de depender so do embutido no binario: e baixado para `/etc/coraza-spoa/coreruleset/` (do `coraza-coreruleset`, compativel com Coraza). `crs_on_disk()`/`_crs_includes()` fazem o gerador apontar p/ disco quando presente, com fallback para o embutido (`@owasp_crs`). - `install_crs(version)`: baixa o tarball da tag, troca o diretorio de forma atomica (com rollback se nao validar) e recarrega o daemon. `crs_installed_version()` / `crs_latest_version()` (GitHub). - Rotas: `GET /api/waf/crs/latest`, `POST /waf/crs/update`, `POST /waf/crs/auto`. - UI: card *OWASP Core Rule Set* na aba Politica (fonte/versao, verificar/atualizar, toggle de auto-update semanal via systemd timer `coraza-crs-update.timer`). - `setup-waf.sh` baixa o CRS para disco no install e aponta o config p/ la.
-
v2.2.0 Triagem de falso-positivo do WAF 20/06/2026### Audit log (atribuicao ao dominio) - Gerador habilita `SecAuditEngine RelevantOnly` (JSON) em /var/log/coraza-spoa/audit.log - `audit_host_index()`: o log de erro nao tem Host; cruza com o audit pelo id da transacao (== unique_id) para descobrir o dominio de cada deteccao - logrotate para os logs do coraza (setup-waf.sh + /etc/logrotate.d/coraza-spoa) ### Motor de triagem - `build_waf_triage()`: agrupa por (dominio, regra, path); heuristica `_score_false_positive` (IPs distintos, frequencia, severidade, tipo de endpoint) -> veredito fp/review/attack - Regras de scoring/correlacao (949*, 980*) ficam fora da triagem (nao excluiveis) - Decisoes persistidas em /etc/haproxy/waf-triage.json (somem da lista) ### Exclusao por dominio + path - Novo `path_exclusions` na politica; gerado como Host+URI numa variavel tx casada de uma vez (NAO chain: no Coraza o ctl do chain-starter executa so com o Host, vazando o escopo) - Rotas: `POST /waf/triage` (fp/attack/ignore), `POST /waf/triage/reset` ### UI - Aba **Triagem** (primeira) com cards: veredito, motivos, contadores, e escopo da exclusao escolhido na hora (dominio+path / dominio / global)
-
v2.1.0 Gerenciamento de regras/politicas do WAF 19/06/2026### Geracao do config.yaml (DRY) - O painel agora **gera** `/etc/coraza-spoa/config.yaml` a partir de `/etc/haproxy/waf-policy.json` (`generate_coraza_config`/`write_coraza_config`), validando com `coraza-spoa -validate` e recarregando via SIGHUP (`reload_coraza`) - As applications `detection` e `blocking` compartilham a mesma base de regras (so muda o `SecRuleEngine`) ### Politica e exclusoes - `load_waf_policy`/`save_waf_policy`: paranoia level, thresholds in/out, inspecao de corpo, regras removidas globais e exclusoes por dominio - Exclusao global via `SecRuleRemoveById` (apos o Include do CRS - load-time) - Exclusao por dominio escopada pelo header `Host` via `ctl:ruleRemoveById` (runtime, antes do Include) - a regra continua ativa nos demais dominios - Rotas: `GET /waf`, `POST /waf/policy`, `POST /waf/domain-rules`, `POST /waf/exclude` ### Eventos - `read_waf_events`/`waf_events_summary`: le o log JSON do Coraza (tail), agrega por regra e lista eventos recentes; `GET /api/waf/events` - Nova aba **WAF** (`templates/waf.html`) com Politica / Exclusoes por dominio / Eventos, e botao para criar exclusao direto de um evento - Aba **Logs**: tail ao vivo do log do coraza-spoa (`read_waf_log`, `GET /api/waf/logs`) com filtro por nivel, busca, modo JSON cru e auto-refresh; alterna arquivo x journal (`read_coraza_journal`) e download (`GET /waf/log/download`)
-
v2.0.0 WAF OWASP (Coraza) por dominio 19/06/2026### Infraestrutura (servidor) - `coraza-spoa` v0.7.2 compilado do source (Go) e instalado em `/usr/local/bin/coraza-spoa` - Servico systemd `coraza-spoa` (usuario `coraza`, hardening, bind `127.0.0.1:9000`) - `/etc/coraza-spoa/config.yaml` com duas applications: `detection` (DetectionOnly) e `blocking` (On), ambas com OWASP CRS **embutido** no binario (`@owasp_crs/*.conf`) - SPOE `/etc/haproxy/coraza.cfg` + wiring estatico em `ft_https` (`filter spoe`) e `backend coraza-spoa` (mode tcp, `option spop-check`) - `setup-waf.sh` idempotente reproduz toda a instalacao ### App (`app.py`) - Estado por dominio em `/etc/haproxy/waf.json` (`load_waf_state`/`save_waf_state`) - `build_waf_block`/`apply_waf_block`/`remove_waf_block`: bloco gerenciado (entre marcadores) inserido antes do `default_backend`, com `set-var(txn.coraza.app)` + `send-spoe-group` por dominio e um `deny` global. Filtra ACLs inexistentes (sem referencia orfa) e e idempotente - Rota `POST /domains/waf` (acoes: `detection`/`blocking`/`off`), com guarda `waf_infra_ready` - `remove_domain` agora limpa o WAF do dominio removido - `domains_page` enriquecido com `waf_mode` por dominio + status do daemon ### UI (`domains.html`) - Banner de status do WAF (daemon ativo/inativo, dominios protegidos/bloqueio/deteccao) - Badge e botao **WAF** por dominio + modal com as tres acoes - **Fail-open**: sem deny em erro do SPOA (daemon caido => trafego passa)
-
API REST Remota + Backends Independentes 30/03/2026### API REST (`app.py`) - Novo decorator `api_login_required` que aceita **Basic Auth** (para uso remoto) alem de session cookie - App agora escuta em `10.110.2.15:5000` (interface ens21) #### Endpoints de Dominios - `GET /haproxy-admin/api/domains` - lista dominios com ACLs - `POST /haproxy-admin/api/domains/add` - cria dominio (JSON: domain, acl_name, backend, include_www) - `POST /haproxy-admin/api/domains/remove` - remove dominio por acl_name #### Endpoints de Certificados - `GET /haproxy-admin/api/certs` - lista certificados - `POST /haproxy-admin/api/certs/generate` - gera cert Let's Encrypt (JSON: domain, email, include_www) - `POST /haproxy-admin/api/certs/renew` - renova todos os certs - `POST /haproxy-admin/api/certs/remove` - remove cert por filename #### Endpoints de Backends (NOVO - backends independentes) - `GET /haproxy-admin/api/backends` - lista todos os backends com servidores e opcoes - `POST /haproxy-admin/api/backends/create` - cria backend novo com servidor(es) (JSON: name, servers, balance, options) - `POST /haproxy-admin/api/backends/remove` - remove backend inteiro + referencias use_backend - `POST /haproxy-admin/api/backends/add-server` - adiciona servidor a backend especifico - `POST /haproxy-admin/api/backends/remove-server` - remove servidor de backend especifico - `POST /haproxy-admin/api/backends/toggle-server` - habilita/desabilita servidor em qualquer backend #### Endpoint de Provisionamento - `POST /haproxy-admin/api/provision` - cria backend + dominio + certificado em uma unica chamada - Aceita lista de servers, auto-gera nome do backend a partir do dominio (ex: `bk_loja_example_com`) - Retorna status de cada etapa (backend, domain, cert) separadamente ### Helpers (`app.py`) - Nova funcao `parse_all_backends(cfg)` - parseia todas as secoes backend do config (nome, opcoes, servidores) - Funcao `parse_servers()` agora aceita parametro `backend_name` (antes hardcoded `bk_cwp`) - Funcao `get_server_stats()` agora retorna stats de todos os backends (chave `backend/server` e `server` para compat) ### Rotas Web atualizadas - `add_server`, `remove_server`, `toggle_server`, `edit_server` agora recebem campo `backend` no form (nao mais hardcoded em `bk_cwp`) - Nova rota `POST /haproxy-admin/backends/add` - criar backend via formulario web - Nova rota `POST /haproxy-admin/backends/remove/<bk_name>` - remover backend via web ### Interface Web (`servers.html`) - Pagina renomeada de "Servidores CWP" para "Backends & Servidores" - Cada backend renderiza como secao separada com header destacado (borda accent) - Exibe nome do backend, quantidade de servidores e opcoes de configuracao - Botao "Novo Backend" - modal para criar backend com primeiro servidor (nome, balance, servidor) - Botao "Adicionar Servidor" - modal com dropdown para escolher backend destino - Botao de remover backend inteiro (com confirmacao, protege bk_cwp) - Auto-refresh de stats usa chave `backend/server` para identificar corretamente cada servidor - Sidebar atualizada: icone e label alterados para "Backends" ---
-
Grafico de Trafego IPv4 vs IPv6 12/03/2026### Backend (`app.py`) - Criada funcao `_get_traffic_bytes()` que le contadores de octetos IPv4 (`/proc/net/netstat` IpExt InOctets/OutOctets) e IPv6 (`/proc/net/snmp6` Ip6InOctets/Ip6OutOctets) - Novo endpoint `GET /haproxy-admin/api/traffic` retornando JSON com `ipv4_in`, `ipv4_out`, `ipv6_in`, `ipv6_out` ### Frontend (`dashboard.html`) - Adicionado card com grafico Chart.js (CDN chart.js@4.4.7) entre os stat cards e as tabelas - Duas linhas: IPv4 In (azul `#00b4d8`) e IPv6 In (amarelo `#f0a500`) em KB/s - Polling a cada 5 segundos, calcula taxa via delta de bytes entre leituras - Maximo 60 pontos no grafico (5 minutos de historico visual) - Eixo Y com auto-escala KB/s -> MB/s ---
-
Aumento de Capacidade para 80% dos Recursos 12/03/2026### HAProxy (`/etc/haproxy/haproxy.cfg`) - `maxconn` (global + defaults): 400.000 -> **750.000** - `stick-table size`: 200k -> **500k** IPs rastreados ### Kernel (`/etc/sysctl.conf`) - `net.ipv4.tcp_mem`: 786432/1048576/1572864 -> **1572864/4194304/6291456** (~6-24 GB em pages 4KB) - `net.ipv4.tcp_max_orphans`: 262.144 -> **500.000** - `net.core.netdev_max_backlog`: 250.000 -> **500.000** ### Capacidade Resultante - ~750.000 conexoes simultaneas (~25 GB de 31 GB = 80% RAM) - ~100k req/s de throughput estimado com SSL - 15 req/s por IP (rate limit mantido) - File descriptors: 2M (LimitNOFILE inalterado, suficiente) ---
-
Modal de Logs em Tempo Real 12/03/2026### Backend (`app.py`) - Novo endpoint `GET /haproxy-admin/api/logs` que le logs via `journalctl -u haproxy` - Parametros: `?lines=50|100|200|500`, `?level=all|warn|error`, `?search=texto` - Filtro por nivel detecta status HTTP 4xx/5xx e keywords error/warning - Limite maximo de 500 linhas por request ### Frontend (`dashboard.html`) - Botao "Logs" adicionado na topbar do dashboard ao lado dos botoes de controle - Modal fullscreen com fundo terminal escuro (`#010409`) - Syntax highlighting: IPs (azul), status 2xx (verde), 4xx (amarelo), 5xx (vermelho), backends ft_/bk_ (roxo), timestamps (cinza) - Controles: campo de busca, filtro de nivel, quantidade de linhas, toggle tempo real, toggle auto-scroll, botao refresh manual - Polling a cada 3 segundos quando "Tempo real" esta ativo - Polling para automaticamente quando o modal e fechado ---
-
SSL Offloading (Limpeza 12/03/2026### HAProxy (`/etc/haproxy/haproxy.cfg`) - Removida linha duplicada `http-request set-header X-Forwarded-Proto https if { ssl_fc }` do `bk_cwp` (ja era setado no `ft_https`) - Confirmado fluxo de offloading: Cliente --[HTTPS/TLS]--> HAProxy (ft_https :443) --[HTTP puro]--> CWP Servers - Headers de offloading enviados aos backends: `X-Forwarded-Proto: https`, `X-Forwarded-Port: 443`, `X-Real-IP: %[src]`, `X-Forwarded-For` (via `option forwardfor`) - Backends recebem HTTP puro (sem flag `ssl` nas linhas `server`)