
Mecanismo de descoberta e pesquisa de rede auto-hospedado com varredura contínua de portas, sondagem profunda de protocolos em ~100 serviços, correspondência local de CVEs e pesquisa de texto completo para inventário de infraestrutura e monitoramento de riscos.
Descoberta e busca de rede auto-hospedada — seu próprio Shodan, no seu hardware.
Varredura TCP/UDP · ~100 sondas de protocolo · impressões digitais TLS/JARM · correspondência de CVE · busca em texto completo · rastreamento de deltas · alertas
Início rápido · Recursos · Arquitetura · Documentação · Checklist de produção
Importante. Varra apenas redes que você possui ou para as quais tenha autorização por escrito para varrer. O UltraViolet realiza reconhecimento passivo de serviços — ele não explora vulnerabilidades.
Locatário único, um único stack Docker Compose, controle total sobre seus dados.
Descoberta
SCAN_ALLOWED_CIDRS com limites de host e portaSondas profundas (~100 protocolos)
robots.txt, security.txt, stack de tecnologiaEnriquecimento
CVE e risco
Operações
viewer / operator / admin), JWT + tokens de atualização/metrics, perfil opcional de Grafanaflowchart TB
Browser["Browser"]
FE["service-frontend<br/>React + nginx"]
API["uv-api<br/>REST · WS · metrics"]
PG[("PostgreSQL 16")]
SCAN["uv-scanner<br/>probe pipeline"]
Browser --> FE
FE -->|"/api"| API
FE -->|"/realtime"| API
API <--> PG
SCAN <--> PG
API -.->|LISTEN/NOTIFY| API
A imagem de UI do release faz proxy de /api/ e /realtime para uv-api — origem única, sem reconstrução do frontend por URL de API.
Regras de desenvolvimento do backend: CLAUDE.md.
Requisitos: Go 1.25+, Docker Engine ≥ 24, ~4 GB de RAM. As imagens de produção são voltadas para Linux amd64.
Caminho para iniciantes — baixe as imagens publicadas com
service-env/docker-compose.registry.yml:
cd service-env
cp env.registry.example .env
# set POSTGRES_PASSWORD, AUTH_JWT_SECRET, AUTH_BOOTSTRAP_PASSWORD
mkdir -p geoip catalog-seed
docker compose -f docker-compose.registry.yml pull
docker compose -f docker-compose.registry.yml up -d
# UI → http://localhost:3000
Veja Docker Registry no site de documentação.
As imagens da API/scanner copiam binários pré-compilados de service-api/bin/ (eles não são compilados dentro do Docker). O make dev executa make -C service-api build-linux antes de docker compose … --build.
git clone https://github.com/yakushstanislav/UltraViolet.git
cd UltraViolet/service-env
cp .env.example .env
mkdir -p secrets
openssl rand -hex 32 > secrets/postgres_password
openssl rand -hex 32 > secrets/auth_jwt_secret
cd ..
make dev
| URL | Propósito |
|---|---|
| http://localhost:3000 | UI (API via nginx /api/) |
| http://localhost:8080 | API diretamente |
Bootstrap de desenvolvimento: admin / admin (somente quando APP_ENV≠production).
Guia completo — VitePress em service-documentation-frontend/docs/:
make docs-dev # → http://localhost:5173
Em produção, habilite o perfil docs:
cd service-env && docker compose --profile docs up -d
# → http://localhost:${UV_DOCUMENTATION_PORT:-3002}
Seções principais: instalação · varredura · API · implantação · instalação offline.
make dev # build-linux → compose prod + dev override --build
Recompile os binários Go após alterações no backend (make -C service-api build-linux) e reinicie ou execute novamente o make dev.
make dev-db # PostgreSQL only on :5432
cd service-api && make build
export LOGGER_NAME=uv-api LOGGER_DEBUG=true
export SERVER_ADDR=0.0.0.0 SERVER_PORT=8080
export METRICS_ADDR=0.0.0.0 METRICS_PORT=9090
export REALTIME_ADDR=0.0.0.0 REALTIME_PORT=8081
export POSTGRES_ADDR=localhost POSTGRES_PORT=5432
export POSTGRES_USERNAME=ultraviolet
export POSTGRES_PASSWORD="$(cat ../service-env/secrets/postgres_password)"
export POSTGRES_DATABASE=ultraviolet
export POSTGRES_SCHEMA_PATH="$(pwd)/deploy/migrations"
export AUTH_JWT_SECRET="$(cat ../service-env/secrets/auth_jwt_secret)"
./bin/uv-api
Frontend: cd service-frontend && npm run dev (o Vite faz proxy de /api → :8080 e /realtime → :8081).
cd service-env && make geoip-download # IPLocate MMDB → geoip/
make -C service-env cve-catalog-dump # CVE dump (requires running postgres)
make build && make lint && make frontend-build && make docs-build
Plataforma alvo: linux/amd64. No Apple Silicon, defina DOCKER_PLATFORM=linux/amd64 para arquivos offline.
git tag v0.1.0
make release VERSION=v0.1.0
make release-promote VERSION=v0.1.0 # :latest — required for local releases; GitHub Actions does this automatically
| Arquivo | Conteúdo |
|---|---|
ultraviolet-vX.Y.Z.tar.gz | compose, scripts, .env.example (~50 KB, online) |
ultraviolet-vX.Y.Z-offline.tar.gz | + imagens Docker amd64 |
ultraviolet-vX.Y.Z-offline-full.tar.gz | + seed de CVEs + GeoIP MMDB |
Online: extraia → cp .env.example .env → ./install.sh (baixar do registry).
Offline: ./install.sh (docker load, sem pull). Atualização: mantenha .env, secrets/ e o volume do Postgres → ./upgrade.sh.
Variáveis: UV_REGISTRY (padrão docker.io/styakush), DRY_RUN=1 — build de teste local sem push.
# from the build machine
scp dist/ultraviolet-v0.1.0-offline.tar.gz user@host:~/
# on the server (Docker ≥ 24, amd64)
tar xzf ultraviolet-v0.1.0-offline.tar.gz && cd ultraviolet-v0.1.0
cp .env.example .env
./install.sh
Atualização (preservando os dados):
docker compose -f docker-compose.yml down
# back up .env + secrets/, extract the new archive, run ./upgrade.sh
Mantenha o nome do diretório (ultraviolet-v0.1.0) estável — o volume Docker postgres-data está vinculado a ele.
secrets/, nunca no git.CORS_ALLOWED_ORIGINS apenas para as origens reais da UI.SCAN_ALLOWED_CIDRS e os limites de host/porta.AUTH_JWT_SECRET (o install.sh rejeita placeholders).APP_ENV=production — o uv-api recusa admin/admin e senhas com menos de 8 caracteres.service-env/examples/nginx-tls.conf.AUDIT_TRUST_PROXY_HEADERS=true.service-env/scripts/backup.sh + cron; o upgrade.sh também cria um dump.Encerramento de TLS no nginx externo — vincule a UI apenas ao loopback:
# docker-compose.override.yml
services:
service-frontend:
ports:
- "127.0.0.1:3000:8080"
CORS_ALLOWED_ORIGINS=https://ultraviolet.example.com
AUDIT_TRUST_PROXY_HEADERS=true
Sub-caminho (/ultraviolet/):
VITE_BASE_PATH=/ultraviolet/ make frontend-build
# UV_BASE_PATH=/ultraviolet/ in compose — must match VITE_BASE_PATH
Cron de backup (diário, retenção de 14 dias):
0 3 * * * cd /opt/ultraviolet/service-env && ./scripts/backup.sh && find backups -name 'uv-*.dump' -mtime +14 -delete
Atualização do GeoIP (primeiro dia de cada mês):
0 4 1 * * cd /opt/ultraviolet/service-env && ./scripts/geoip-refresh.sh >> /var/log/uv-geoip.log 2>&1
Após POST /v1/auth/login, você recebe um access_token (Bearer) e um refresh_token (/v1/auth/refresh).
| Papel | Capacidades |
|---|---|
viewer | Ler hosts, busca, CVEs, painel |
operator | + iniciar e gerenciar varreduras |
admin | + usuários, auditoria, configurações |
GET /v1/me · GET /v1/version · GET /readyz (health + versão + commit).
Veja CONTRIBUTING.md. Relatos de segurança: SECURITY.md. Padrões da comunidade: CODE_OF_CONDUCT.md.
O UltraViolet é distribuído sob a Licença MIT.
UltraViolet — descubra o que você possui, entenda o que mudou, mantenha-o na sua rede.
| Caso de uso | O que você obtém |
|---|
| Perímetro e inventário | Descoberta contínua de portas abertas e serviços em intervalos de CIDR |
| Busca de infraestrutura | Busca em texto completo em corpos HTTP, banners, TLS, DNS e CVEs |
| Risco e conformidade | Correspondência local com NVD, além de CISA KEV e EPSS — sem dependência de nuvem |
| Implantações em ambientes isolados (air-gapped) | Arquivo offline com imagens Docker, seed de CVEs e MMDB do GeoIP em disco |
| Rastreamento de mudanças | Deltas entre varreduras, eventos WebSocket, alertas em buscas salvas |
| Diretório | Finalidade |
|---|
service-api/ | Go: uv-api (API HTTP, WebSocket, workers) + uv-scanner (pipeline) |
service-frontend/ | React 19 + Vite + RTK — varreduras, hosts, busca, painel |
service-documentation-frontend/ | VitePress — documentação de usuário e operador |
service-env/ | docker-compose, segredos, install.sh / upgrade.sh / backup |
| http://localhost:9090/metrics |
| Prometheus |
:9090/metrics; Grafana via perfil observability.service-env/scripts/geoip-refresh.sh em um cron mensal.