Retour aux mises à jour
New releaseAug 21, 2026

UltraViolet v1.0.11

Moteur de découverte réseau et de recherche auto-hébergé avec scan de ports continu, sondage approfondi de protocoles sur ~100 services, mise en correspondance locale de CVE, et recherche en texte intégral pour l'inventaire d'infrastructure et la surveillance des risques.

Partager

UltraViolet

Découverte et recherche réseau auto-hébergées — votre propre Shodan, sur votre matériel.

Scan TCP/UDP · ~100 sondes de protocoles · Empreintes TLS/JARM · Correspondance CVE · recherche en texte intégral · suivi des différences · alertes


Go React PostgreSQL Docker CI License: MIT

Démarrage rapide · Fonctionnalités · Architecture · Documentation · Production


Important. Ne scannez que les réseaux dont vous êtes propriétaire ou pour lesquels vous disposez d'une autorisation écrite. UltraViolet effectue une reconnaissance passive des services — il n'exploite pas de vulnérabilités.

Pourquoi UltraViolet

Cas d'usageCe que vous obtenez
Périmètre et inventaireDécouverte continue des ports et services ouverts sur des plages CIDR
Recherche d'infrastructureRecherche en texte intégral sur les corps HTTP, bannières, TLS, DNS et CVE
Risque et conformitéCorrespondance NVD locale plus CISA KEV et EPSS — aucune dépendance au cloud
Déploiements isolésArchive hors ligne avec images Docker, graine CVE et MMDB GeoIP sur disque
Suivi des changementsDifférences entre scans, événements WebSocket, alertes sur recherches enregistrées

Locataire unique, une pile Docker Compose, contrôle total de vos données.

✨ Fonctionnalités

Découverte

  • Scanner TCP connect avec masscan ou zmap comme moteur de découverte
  • Sondes UDP sur ports configurables
  • Cadré par SCAN_ALLOWED_CIDRS avec limites d'hôtes et de ports

Sondes approfondies (~100 protocoles)

  • Web : HTTP/HTTPS, HTTP/3, GraphQL, hash favicon, robots.txt, security.txt, pile technologique
  • TLS : chaînes de certificats, JARM, JA3S/JA4S, évaluation de la configuration
  • Courrier et annuaires : SMTP, POP3/IMAP, LDAP, IPMI
  • Bases de données et files d'attente : MySQL, PostgreSQL, MongoDB, Redis, Kafka, MQTT, NATS, AMQP…
  • ICS/SCADA : Modbus, BACnet, DNP3, IEC 104, S7Comm, ENIP, OPC UA…
  • IoT et médias : ONVIF, RTSP, Chromecast, AirPlay, UPnP…
  • Liste complète dans la documentation des protocoles

Enrichissement

  • DNS inversé, GeoIP (MMDB), ASN
  • DNS direct optionnel et découverte des journaux CT

CVE et risque

  • Miroir NVD local avec synchronisation en arrière-plan et correspondance basée sur les empreintes
  • CISA KEV et FIRST EPSS

Opérations

  • RBAC (viewer / operator / admin), JWT + jetons d'actualisation
  • Planifications de scan, pause/reprise, récupération des orphelins après redémarrage d'un worker
  • Prometheus /metrics, profil Grafana optionnel
  • Journal d'audit, limitation de débit, politiques de rétention

🏗 Architecture

flowchart 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

L'image UI publiée fait office de proxy /api/ et /realtime vers uv-apiorigine unique, aucune reconstruction du frontend par URL d'API.

RépertoireObjectif
service-api/Go : uv-api (API HTTP, WebSocket, workers) + uv-scanner (pipeline)
service-frontend/React 19 + Vite + RTK — scans, hôtes, recherche, tableau de bord
service-documentation-frontend/VitePress — documentation utilisateur et opérateur
service-env/docker-compose, secrets, install.sh / upgrade.sh / backup

Règles de développement backend : CLAUDE.md.

🚀 Démarrage rapide

Prérequis : Go 1.25+, Docker Engine ≥ 24, ~4 Go de RAM. Les images de production ciblent Linux amd64.

Exécution depuis Docker Hub (sans compilation source)

Parcours débutant — tirez les images publiées avec 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

Voir Docker Registry dans le site de documentation.

Développer depuis les sources

Les images API/scanner copient les binaires précompilés depuis service-api/bin/ (ils ne sont pas compilés dans Docker). make dev exécute make -C service-api build-linux avant 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
URLObjectif
http://localhost:3000UI (API via nginx /api/)
http://localhost:8080API directement
http://localhost:9090/metricsPrometheus

Bootstrap de développement : admin / admin (uniquement quand APP_ENV≠production).

📖 Documentation

Guide complet — VitePress dans service-documentation-frontend/docs/ :

make docs-dev    # → http://localhost:5173

En production, activez le profil docs :

cd service-env && docker compose --profile docs up -d
# → http://localhost:${UV_DOCUMENTATION_PORT:-3002}

Sections clés : installation · scan · API · déploiement · installation hors ligne.

🛠 Développement

Docker complet

make dev    # build-linux → compose prod + dev override --build

Recompilez les binaires Go après des modifications du backend (make -C service-api build-linux), puis redémarrez ou relancez make dev.

Mode hybride (itération backend plus rapide)

make dev-db   # PostgreSQL uniquement sur :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 (Vite fait office de proxy /api:8080, /realtime:8081).

GeoIP et CVE

cd service-env && make geoip-download      # IPLocate MMDB → geoip/
make -C service-env cve-catalog-dump       # CVE dump (requires running postgres)

Compilation sans Docker

make build && make lint && make frontend-build && make docs-build

📦 Publication et installation

Plateforme cible : linux/amd64. Sur Apple Silicon, définissez DOCKER_PLATFORM=linux/amd64 pour les archives hors ligne.

git tag v0.1.0
make release VERSION=v0.1.0
make release-promote VERSION=v0.1.0   # :latest — requis pour les versions locales ; GitHub Actions le fait automatiquement
ArchiveContenu
ultraviolet-vX.Y.Z.tar.gzcompose, scripts, .env.example (~50 Ko, en ligne)
ultraviolet-vX.Y.Z-offline.tar.gz+ images Docker amd64
ultraviolet-vX.Y.Z-offline-full.tar.gz+ graine CVE + MMDB GeoIP

En ligne : extraire → cp .env.example .env./install.sh (tirage depuis le registre).

Hors ligne : ./install.sh (docker load, pas de tirage). Mise à niveau : conservez .env, secrets/ et le volume Postgres → ./upgrade.sh.

Variables : UV_REGISTRY (par défaut docker.io/styakush), DRY_RUN=1 — build de test local sans push.

Installation hors ligne — pas à pas
# depuis la machine de build
scp dist/ultraviolet-v0.1.0-offline.tar.gz user@host:~/

# sur le serveur (Docker ≥ 24, amd64)
tar xzf ultraviolet-v0.1.0-offline.tar.gz && cd ultraviolet-v0.1.0
cp .env.example .env
./install.sh

Mise à niveau (préserver les données) :

docker compose -f docker-compose.yml down
# sauvegardez .env + secrets/, extrayez la nouvelle archive, exécutez ./upgrade.sh

Gardez le nom du répertoire (ultraviolet-v0.1.0) stable — le volume Docker postgres-data y est lié.

✅ Checklist de production

  1. Stockez les secrets dans secrets/, jamais dans git.
  2. Définissez CORS_ALLOWED_ORIGINS uniquement sur les origines UI réelles.
  3. Configurez SCAN_ALLOWED_CIDRS et les limites d'hôtes/ports.
  4. Changez le mot de passe de bootstrap et AUTH_JWT_SECRET (install.sh rejette les valeurs factices).
  5. Définissez APP_ENV=production — uv-api refuse admin/admin et les mots de passe de moins de 8 caractères.
  6. Terminez le TLS au niveau d'un reverse proxy — exemple : service-env/examples/nginx-tls.conf.
  7. Derrière un proxy : définissez AUDIT_TRUST_PROXY_HEADERS=true.
  8. Sauvegardez PostgreSQL : service-env/scripts/backup.sh + cron ; upgrade.sh crée également un dump.
  9. Métriques sur :9090/metrics ; Grafana via le profil observability.
  10. Actualisez GeoIP : service-env/scripts/geoip-refresh.sh via un cron mensuel.
HTTPS, déploiement en sous-chemin, cron de sauvegarde

Terminaison TLS sur nginx externe — liez l'UI au loopback uniquement :

# 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

Sous-chemin (/ultraviolet/) :

VITE_BASE_PATH=/ultraviolet/ make frontend-build
# UV_BASE_PATH=/ultraviolet/ dans compose — doit correspondre à VITE_BASE_PATH

Cron de sauvegarde (quotidien, rétention de 14 jours) :

0 3 * * * cd /opt/ultraviolet/service-env && ./scripts/backup.sh && find backups -name 'uv-*.dump' -mtime +14 -delete

Actualisation GeoIP (1er de chaque mois) :

0 4 1 * * cd /opt/ultraviolet/service-env && ./scripts/geoip-refresh.sh >> /var/log/uv-geoip.log 2>&1

🔐 API et RBAC

Après POST /v1/auth/login, vous recevez un access_token (Bearer) et un refresh_token (/v1/auth/refresh).

RôleCapacités
viewerLire les hôtes, rechercher, CVE, tableau de bord
operator+ démarrer et gérer les scans
admin+ utilisateurs, audit, paramètres

GET /v1/me · GET /v1/version · GET /readyz (santé + version + commit).

🤝 Contribuer

Voir CONTRIBUTING.md. Rapports de sécurité : SECURITY.md. Normes communautaires : CODE_OF_CONDUCT.md.

📄 Licence

UltraViolet est publié sous la Licence MIT.


UltraViolet — découvrez ce que vous possédez, comprenez ce qui a changé, gardez-le sur votre réseau.

Catégories