
Un tableau de bord moderne et élégant pour la visualisation et l'analyse du trafic réseau.
Neko Master
Visualisez clairement votre trafic réseau.
Surveillance en temps réel · Audit du trafic · Prise en charge multi-passerelles
English | 中文
[!IMPORTANT] Avertissement
Ce projet est un outil d'analyse et de visualisation du trafic destiné aux environnements de passerelle locale.
Il ne fournit aucun service d'accès réseau, d'abonnement proxy ou de connectivité inter-réseaux. Toutes les données sont collectées depuis l'environnement réseau de l'utilisateur.
Ce projet est open source sous licence MIT. Nous déclinons toute responsabilité quant aux conséquences résultant de l'utilisation de ce logiciel. Veuillez l'utiliser conformément aux lois et réglementations applicables.
Neko (ねこ) signifie chat en japonais. Se prononce /ˈneɪkoʊ/ (NEH-ko).
Comme un chat, Neko Master observe le trafic réseau discrètement et avec précision. C'est un tableau de bord analytique léger conçu pour les environnements de passerelle modernes.
Le fichier
docker-compose.ymlintégré au dépôt mappe3000/3001/3002par défaut. Les scénarios A/B ci-dessous sont des modèles minimaux pour les déploiements courants.
services: neko-master: image: foru17/neko-master:latest container_name: neko-master restart: unless-stopped ports: - "3000:3000" # Web UI volumes: - ./data:/app/data # Local MMDB (optional, files should be downloaded into ./geoip) - ./geoip:/app/data/geoip:ro environment: - NODE_ENV=production - DB_PATH=/app/data/stats.db - COOKIE_SECRET=${COOKIE_SECRET}
> Recommandé dans `.env` (même répertoire que `docker-compose.yml`) :
> `COOKIE_SECRET=<chaîne aléatoire d'au moins 32 octets>` (générer avec `openssl rand -hex 32`)
> Ce mode est entièrement compatible avec les mises à niveau et fonctionne immédiatement.
> Si WS n'est pas routé, l'application bascule automatiquement vers le polling HTTP.
#### Scénario B : WebSocket en temps réel (recommandé avec reverse proxy)```yaml
services:
neko-master:
image: foru17/neko-master:latest
container_name: neko-master
restart: unless-stopped
ports:
- "3000:3000" # Web UI
- "3002:3002" # WebSocket (for Nginx / Tunnel forwarding)
volumes:
- ./data:/app/data
# Local MMDB (optional, files should be downloaded into ./geoip)
- ./geoip:/app/data/geoip:ro
environment:
- NODE_ENV=production
- DB_PATH=/app/data/stats.db
- COOKIE_SECRET=${COOKIE_SECRET}
Puis exécutez :```bash docker compose up -d
Ouvrez <http://localhost:3000> pour commencer.
Si vous utilisez le fichier Compose intégré au dépôt (par défaut `3000/3001/3002`), exécutez la même commande.
### Option 2 : Docker Run```bash
# Generate a fixed cookie secret first (for session persistence)
export COOKIE_SECRET="$(openssl rand -hex 32)"
docker run -d
--name neko-master
-p 3000:3000
-v $(pwd)/data:/app/data
-e COOKIE_SECRET="$COOKIE_SECRET"
--restart unless-stopped
foru17/neko-master:latest
docker run -d
--name neko-master
-p 3000:3000
-p 3002:3002
-v $(pwd)/data:/app/data
-e COOKIE_SECRET="$COOKIE_SECRET"
--restart unless-stopped
foru17/neko-master:latest
Ouvrez <http://localhost:3000> pour commencer.
> Le frontend utilise `/api` en same-origin par défaut, donc le port 3001 n'est généralement pas requis en externe.
> Pour le WS en temps réel, votre reverse proxy/tunnel doit pouvoir atteindre le port `3002`. Sinon, l'application bascule sur un polling HTTP d'environ 5s.
> Pour `docker run`, modifiez les ports externes en utilisant directement les mappings `-p`.
> Uniquement si vous utilisez un accès WS direct (sans reverse proxy) et que le port WS externe n'est pas `3002`, passez également `-e WS_EXTERNAL_PORT=<external-ws-port>`.
>
> Mode de recherche MMDB local (optionnel) : montez `-v $(pwd)/geoip:/app/data/geoip:ro`,
> puis basculez la source sur Local dans `Settings -> Preferences -> IP Lookup Source`.
### Option 3 : Script en un clic
Détecte automatiquement les conflits de ports et configure tout :```bash
# Using curl
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
# Or using wget
wget -qO- https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
Le script va automatiquement :
docker-compose.ymlgit clone https://github.com/foru17/neko-master.git cd neko-master
pnpm install
cp apps/collector/.env.example apps/collector/.env
pnpm dev
Ouvrir <http://localhost:3000> pour configurer.
> En mode source : le collecteur écoute sur `3001/3002`, le web écoute sur `3000` par défaut.
> Si vous avez modifié `API_PORT` (pas 3001), définissez `API_URL` en conséquence (par exemple `API_URL=http://localhost:4001`) afin que la réécriture `/api` du web cible la bonne API.
> `apps/collector/.env.local` a la priorité sur `apps/collector/.env`.
## 🤖 Déploiement de l'agent
Utilisez le mode Agent lorsque vous souhaitez un service Neko Master centralisé et plusieurs appareils distants (OpenWrt, Linux, macOS) collectant les données de la passerelle locale. L'agent s'exécute à proximité de la passerelle, récupère les données et les rapporte au panneau — le panneau ne se connecte jamais directement à la passerelle.
Types de passerelles pris en charge : **Clash / Mihomo** (WebSocket en temps réel) et **Surge v5+** (interrogation HTTP).
### Installation rapide (commande générée par l'interface)
1. Dans le tableau de bord, allez dans `Settings → Backends`, ajoutez un backend `Agent`, sélectionnez le type de passerelle
2. Cliquez sur **"View Agent Script"** et copiez la commande d'installation en une ligne, puis exécutez-la sur l'hôte cible :```bash
# Clash / Mihomo gateway example
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \
| env NEKO_SERVER='http://your-panel:3000' \
NEKO_BACKEND_ID='1' \
NEKO_BACKEND_TOKEN='ag_xxx' \
NEKO_GATEWAY_TYPE='clash' \
NEKO_GATEWAY_URL='http://127.0.0.1:9090' \
sh
# Surge gateway example
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \
| env NEKO_SERVER='http://your-panel:3000' \
NEKO_BACKEND_ID='2' \
NEKO_BACKEND_TOKEN='ag_yyy' \
NEKO_GATEWAY_TYPE='surge' \
NEKO_GATEWAY_URL='http://127.0.0.1:9091' \
sh
Après l'installation, gérez les instances avec nekoagent :```bash
nekoagent list # list all instances
nekoagent status # check running state
nekoagent logs # tail live logs
nekoagent restart # restart
nekoagent upgrade # global upgrade (CLI + binary)
> Le script détecte automatiquement une installation existante — si `neko-agent` est déjà présent, il ajoute uniquement la nouvelle instance sans re-télécharger.
> Plusieurs instances peuvent fonctionner sur le même hôte (avec des `NEKO_INSTANCE_NAME` différents), chacune pointant vers une passerelle différente.
### Documentation de l'agent
- [Vue d'ensemble](https://github.com/foru17/neko-master/blob/main/docs/agent/overview.en.md) : architecture, comparaison Direct vs Agent, modèle de sécurité
- [Démarrage rapide](https://github.com/foru17/neko-master/blob/main/docs/agent/quick-start.en.md) : configuration de bout en bout, de l'interface utilisateur à l'agent en fonctionnement
- [Guide d'installation](https://github.com/foru17/neko-master/blob/main/docs/agent/install.en.md) : méthodes d'installation, démarrage automatique systemd / launchd
- [Configuration](https://github.com/foru17/neko-master/blob/main/docs/agent/config.en.md) : référence complète des options et variables d'environnement
- [Flux de publication](https://github.com/foru17/neko-master/blob/main/docs/agent/release.en.md) : politique de versionnage et de compatibilité
- [Dépannage](https://github.com/foru17/neko-master/blob/main/docs/agent/troubleshooting.en.md) : erreurs courantes et solutions
## 📖 Première utilisation

### Connecter Clash / Mihomo
1. Ouvrez <http://localhost:3000>
2. La boîte de dialogue **Configuration de la passerelle** apparaîtra lors de la première visite
3. Renseignez les informations de connexion de votre passerelle réseau (par exemple, OpenClash) :
- **Nom** : Nom personnalisé (par exemple, « Passerelle maison »)
- **Type** : Sélectionnez `Clash / Mihomo`
- **Hôte** : Adresse du backend de la passerelle (par exemple, `192.168.101.1`)
- **Port** : Port du backend de la passerelle (par exemple, `9090`)
- **Token** : À renseigner si un Secret est configuré, sinon laisser vide
4. Cliquez sur « Ajouter un backend » pour enregistrer
5. Le système commencera automatiquement à collecter et analyser les données de trafic
> 💡 **Obtenir l'adresse de la passerelle** : Accédez au panneau de contrôle de votre passerelle (par exemple, OpenClash) → Activez « Contrôle externe » → Copiez l'adresse de l'API
### Connecter Surge

Neko Master prend en charge la connexion aux passerelles Surge pour une visualisation complète de la chaîne de règles et l'analyse du trafic.
#### 1. Activer l'API HTTP de Surge
Activez l'API distante HTTP dans votre configuration Surge :```ini
[General]
http-api = 127.0.0.1:9091
http-api-tls = false
http-api-web-dashboard = true
Ou configurer via l'interface graphique de Surge :
Settings → General → HTTP Remote API9091Surge192.168.1.1 ou 127.0.0.1)9091)💡 Remarque : Surge utilise le polling HTTP pour récupérer les données (contrairement au flux temps réel WebSocket de Clash), avec un délai de rafraîchissement des données d'environ 2 secondes.
Si vous voyez l'erreur « port already in use », voici les solutions :
Créez un fichier .env dans le même répertoire que docker-compose.yml :```env
WEB_EXTERNAL_PORT=8080 # Change Web UI port
API_EXTERNAL_PORT=8081 # Change API port
WS_EXTERNAL_PORT=8082 # Change WebSocket external port (only for direct access)
COOKIE_SECRET=your-long-random-secret # Strongly recommended to keep fixed
Puis redémarrez :```bash
docker compose down
docker compose up -d
Accédez maintenant à http://localhost:8080
ports:
> Remarque : si vous utilisez un accès WS direct (sans reverse proxy) et que le port WS externe n'est pas `3002`, définissez `WS_EXTERNAL_PORT=<external-ws-port>`.
### Solution 3 : Utiliser un script en un clic```bash
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
Le script détectera et suggérera automatiquement les ports disponibles.
runtime-config.API_URL → NEXT_PUBLIC_API_URL → same-origin /api/api : API_URL (par défaut http://localhost:3001, appliqué dans les rewrites Next.js)runtime-config.WS_URL → NEXT_PUBLIC_WS_URL → candidats automatiques (lorsque runtime-config.WS_PORT est défini, le port direct est préféré ; sinon /_cm_ws est essayé en premier)runtime-config.WS_PORT (depuis WS_EXTERNAL_PORT) → NEXT_PUBLIC_WS_PORT → NODE_ENV=production DB_PATH=/app/data/stats.db COOKIE_SECRET=<at least 32-byte random string>
Utilisez `openssl rand -hex 32` pour générer `COOKIE_SECRET`.
Recommandations supplémentaires :
1. Montez un stockage persistant (par exemple `./data:/app/data`) pour éviter la perte de données et de secrets.
2. Si vous utilisez un accès WS direct et que le port WS externe n'est pas `3002`, définissez `WS_EXTERNAL_PORT` en conséquence.
3. Si le port/l'adresse de l'API change dans le déploiement source, mettez également à jour `API_URL`.
4. Pour la recherche MMDB locale, montez `./geoip:/app/data/geoip:ro` et changez la source dans `Settings -> Preferences -> IP Lookup Source`.
5. Les fichiers MMDB sont volumineux et ne sont pas inclus dans l'image. Téléchargez-les et placez-les dans `./geoip` avec des noms fixes :
`GeoLite2-City.mmdb`, `GeoLite2-ASN.mmdb` (requis), et `GeoLite2-Country.mmdb` (optionnel).
Source recommandée : <https://github.com/P3TERX/GeoLite.mmdb>.
> Les détails avancés de l'Agent (installation, configuration, publication, compatibilité) sont maintenus sous `docs/agent/*`.
## 🗄️ ClickHouse (Optionnel)
SQLite est le moteur de stockage par défaut de Neko Master et convient à la plupart des utilisateurs.
Envisagez d'activer ClickHouse si vous avez besoin de :
- Très grands ensembles de données (des centaines de milliers d'entrées de domaines/IP)
- Requêtes d'agrégation rapides sur de longues périodes (≥ 7 jours)
- Séparation des statistiques historiques du stockage de configuration/métadonnées
> ClickHouse est entièrement optionnel. SQLite reste le magasin de configuration et de métadonnées, que ClickHouse soit activé ou non.
### Aperçu de l'architecture
Lorsque ClickHouse est activé, le système entre en **mode double écriture** :```
BatchBuffer.flush()
│
├──→ SQLite (config / metadata, always written)
└──→ ClickHouse (stats traffic data, dual-write)
└── Buffer tables → SummingMergeTree async merge
La lecture de la source est contrôlée par STATS_QUERY_SOURCE (par défaut : sqlite).
Le fichier docker-compose.yml intégré au dépôt inclut déjà un service ClickHouse, conditionné par
profiles: [clickhouse] afin qu'il ne démarre pas par défaut. Depuis la racine du dépôt, exécutez :```bash
docker compose --profile clickhouse up -d
> Les données ClickHouse sont persistées dans `./data/clickhouse`, séparément du répertoire de données principal de l'application.
Si vous utilisez un **`docker-compose.yml` personnalisé** (comme dans les scénarios A/B ci-dessus), ajoutez manuellement le bloc de service ClickHouse :```yaml
services:
neko-master:
# ... your existing config ...
environment:
# append to existing environment section:
- CH_ENABLED=${CH_ENABLED:-0}
- CH_HOST=${CH_HOST:-clickhouse}
- CH_PORT=${CH_PORT:-8123}
- CH_DATABASE=${CH_DATABASE:-neko_master}
- CH_USER=${CH_USER:-neko}
- CH_PASSWORD=${CH_PASSWORD:-neko_master}
- CH_WRITE_ENABLED=${CH_WRITE_ENABLED:-0}
- STATS_QUERY_SOURCE=${STATS_QUERY_SOURCE:-sqlite}
networks:
- neko-master-network
clickhouse:
image: clickhouse/clickhouse-server:24.8
container_name: neko-master-clickhouse
restart: unless-stopped
profiles: ["clickhouse"]
ports:
- "${CH_EXTERNAL_HTTP_PORT:-8123}:8123"
- "${CH_EXTERNAL_NATIVE_PORT:-9000}:9000"
volumes:
- ./data/clickhouse:/var/lib/clickhouse
environment:
- CLICKHOUSE_DB=${CH_DATABASE:-neko_master}
- CLICKHOUSE_USER=${CH_USER:-neko}
- CLICKHOUSE_PASSWORD=${CH_PASSWORD:-neko_master}
- CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
networks:
- neko-master-network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8123/ping || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
neko-master-network:
driver: bridge
Ajoutez à votre fichier .env (dans le même répertoire que docker-compose.yml) :```env
CH_ENABLED=1
CH_WRITE_ENABLED=1
STATS_QUERY_SOURCE=auto
CH_HOST=clickhouse CH_PORT=8123 CH_DATABASE=neko_master CH_USER=neko CH_PASSWORD=neko_master
Redémarrer :```bash
docker compose --profile clickhouse up -d
Santé et bascule : Après
CH_UNHEALTHY_THRESHOLDéchecs d'écriture consécutifs, le système marque automatiquement ClickHouse comme non sain et reprend les écritures SQLite—même lorsqueCH_ONLY_MODE=1. Une fois ClickHouse rétabli, il est de nouveau marqué comme sain et l'événement est journalisé.
Vous effectuez une mise à niveau depuis une version SQLite uniquement ? Vos données sont en sécurité. Le fichier SQLite (
./data/stats.db) est entièrement préservé. Voici le chemin de migration progressive recommandé :
CH_ENABLED=1 CH_WRITE_ENABLED=1 STATS_QUERY_SOURCE=sqlite # Keep reading from SQLite while CH accumulates data
Surveillez les journaux de `[ClickHouse Writer]` pour confirmer la réussite des écritures.
#### Phase 2 : Basculer la source de lecture```env
STATS_QUERY_SOURCE=auto # Smart routing: recent data from CH, historical from SQLite
# or
STATS_QUERY_SOURCE=clickhouse # Force all reads to ClickHouse
Pour transférer les statistiques SQLite historiques vers ClickHouse :```bash
./scripts/ch-migrate-docker.sh
./scripts/ch-migrate-docker.sh --append
./scripts/ch-migrate-docker.sh --from 2026-02-01T00:00:00Z --to 2026-02-20T00:00:00Z
#### Phase 4 (facultatif) : mode CH uniquement
Une fois que ClickHouse fonctionne de manière stable, arrêtez les écritures de statistiques SQLite :```env
CH_ONLY_MODE=1
Même avec
CH_ONLY_MODE=1, si ClickHouse devient défaillant, le système bascule automatiquement vers des écritures SQLite—aucune perte de données.
Vous pouvez toujours effectuer un retour arrière complet :```env CH_ENABLED=0 CH_WRITE_ENABLED=0 CH_ONLY_MODE=0 STATS_QUERY_SOURCE=sqlite
Redémarrez et tout revient en mode SQLite pur. Les données historiques restent intactes.
---
## 🌐 Reverse Proxy & Tunnel
Approche recommandée : garder Web et WS sous le même domaine, avec un routage par chemin :
`/` → `3000`, `/_cm_ws` → `3002`.
### Exemple standard Nginx```nginx
server {
listen 443 ssl http2;
server_name neko.example.com;
location / {
proxy_pass http://<neko-master-host>:3000;
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 $scheme;
}
location ^~ /_cm_ws {
proxy_pass http://<neko-master-host>:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_buffering off;
}
}
Surcharge d'environnement facultative :```env
### Exemple standard de tunnel Cloudflare
`~/.cloudflared/config.yml` :```yaml
tunnel: <your-tunnel-name-or-id>
credentials-file: /path/to/<credentials>.json
ingress:
- hostname: neko.example.com
path: /_cm_ws*
service: http://localhost:3002
- hostname: neko.example.com
path: /*
service: http://localhost:3000
- service: http_status:404
Exécuter :```bash cloudflared tunnel --config ~/.cloudflared/config.yml run
Pour les routes gérées par le tableau de bord Zero Trust (mode jeton), configurez les deux mêmes routes et placez `/_cm_ws*` au-dessus de `/*`.
### Notes clés
1. N'utilisez pas `ws` (sans barre oblique initiale) comme chemin WS ; cela peut correspondre de manière excessive et provoquer `/_next/static/...` → `426 Upgrade Required`
2. La route WS doit être au-dessus du catch-all `/*`
3. `NEXT_PUBLIC_WS_URL` est facultatif par défaut ; s'il est personnalisé, redémarrez le frontend/conteneur après les modifications
4. Le mappage de `3000` uniquement fonctionne toujours, mais bascule vers l'interrogation HTTP (~5s), avec une réactivité en temps réel moindre
5. Les échecs de `beacon.min.js` (script d'analyse Cloudflare) sont généralement sans rapport avec le flux de données API/WS de l'application
6. Aucune règle de reverse-proxy `/api` supplémentaire n'est requise dans la plupart des configurations ; le frontend utilise `/api` de même origine et l'application gère le transfert interne vers `3001`
> Remarque : `/_next/static/... 426 Upgrade Required` est courant dans les configurations **reverse proxy / tunnel mal configurées** ; c'est peu fréquent en accès local direct sans proxy.
### Prise en charge multi-architecture
Les images Docker prennent en charge à la fois `linux/amd64` et `linux/arm64`.
### Persistance des données
Les données sont stockées dans `/app/data` à l'intérieur du conteneur. Montez-le sur l'hôte pour éviter toute perte de données :```yaml
volumes:
- ./data:/app/data
docker compose pull docker compose up -d
## 🔐 Authentification et sécurité
Neko Master prend en charge l'authentification d'accès pour protéger les données du tableau de bord.
### Base de sécurité pour la production
1. Définissez un `COOKIE_SECRET` fixe (sinon les sessions peuvent être invalidées après un redémarrage).
2. Ne laissez pas `FORCE_ACCESS_CONTROL_OFF=true` activé en fonctionnement normal.
3. Utilisez `SHOWCASE_SITE_MODE=true` uniquement pour les environnements de démonstration publics (les opérations d'écriture sont restreintes).
Exemple :```env
COOKIE_SECRET=<at least 32-byte random string>
# FORCE_ACCESS_CONTROL_OFF=false
# SHOWCASE_SITE_MODE=false
Si vous avez oublié le jeton, définissez temporairement FORCE_ACCESS_CONTROL_OFF=true pour passer en mode d'urgence.
docker-compose.yml : ```yaml
environment:
3000:3000 exposé ?R : Oui. Les fonctionnalités principales fonctionnent toujours.
Si le WS n'est pas routé, l'application bascule automatiquement vers le polling HTTP.
Pour une expérience temps réel complète, routez /_cm_ws vers 3002.
R : Créez/met à jour .env (même répertoire que docker-compose.yml) :```env
WEB_EXTERNAL_PORT=8080
API_EXTERNAL_PORT=8081
WS_EXTERNAL_PORT=8082
Puis redémarrez :```bash
docker compose down
docker compose up -d
R : Généralement parce que COOKIE_SECRET n'est pas fixé ou que le répertoire de données n'est pas persistant.
COOKIE_SECRET fixe./data:/app/dataR : Créez ./geoip dans le répertoire de votre projet (au même niveau que docker-compose.yml de préférence), puis placez :
GeoLite2-City.mmdb (requis)GeoLite2-ASN.mmdb (requis)GeoLite2-Country.mmdb (optionnel)Source recommandée : https://github.com/P3TERX/GeoLite.mmdb.
À l'intérieur du conteneur, le chemin de recherche fixe est /app/data/geoip, donc conservez :
./geoip:/app/data/geoip:ro. Pour mettre à jour ultérieurement, remplacez simplement les fichiers dans ./geoip sur l'hôte.
R : Vérifiez :
R : Sauvegardez d'abord :```bash cp -r ./data ./data-backup-$(date +%Y%m%d)
Restaurer :```bash
docker compose down
cp -r ./data-backup-YYYYMMDD/. ./data/
docker compose up -d
Si vous souhaitez comprendre rapidement la profondeur de la conception du système, lisez dans cet ordre :
RealtimeStore et push WSIndex complet de la documentation : docs/README.md
Cette documentation couvre la conception centrale de la collecte, de l'agrégation, de la mise en cache, du push temps réel et de la gestion multi-backend.
Ce projet utilise les modèles d'issue GitHub (Bug / Fonctionnalité / Support).
Veuillez inclure au minimum :
COOKIE_SECRET=***)docker logs, console du navigateur, erreurs réseau)neko-master/ ├── docker-compose.yml # Docker Compose config ├── Dockerfile # Docker image build ├── setup.sh # One-click setup script ├── docker-start.sh # Docker container startup script ├── start.sh # Source code dev startup script ├── docs/ # Documentation (see docs/README.md) │ ├── README.md # Documentation index (English default) │ ├── README.zh.md # Documentation index (Chinese) │ ├── README.en.md # Documentation index (English mirror) │ ├── architecture.md # System architecture (Chinese) │ ├── architecture.en.md # System architecture (English) │ ├── release-checklist.md │ ├── agent/ # Agent docs (bilingual) │ │ ├── overview.md / overview.en.md │ │ ├── quick-start.md / quick-start.en.md │ │ ├── install.md / install.en.md │ │ ├── config.md / config.en.md │ │ ├── release.md / release.en.md │ │ └── troubleshooting.md / troubleshooting.en.md │ ├── research/ # Research reports │ └── dev/ # Internal development docs ├── assets/ # Screenshots and icons ├── apps/ │ ├── collector/ # Data collection service (Node.js + WebSocket) │ ├── agent/ # Agent daemon (Go) │ └── web/ # Next.js frontend app └── packages/ └── shared/ # Shared types and utilities
## 🛠️ Stack technique
- **Frontend** : [Next.js 16](https://nextjs.org/) + [React 19](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/)
- **Styles** : [Tailwind CSS](https://tailwindcss.com/) + [shadcn/ui](https://ui.shadcn.com/)
- **Graphiques** : [Recharts](https://recharts.org/)
- **i18n** : [next-intl](https://next-intl-docs.vercel.app/)
- **Backend** : [Node.js](https://nodejs.org/) + [Fastify](https://www.fastify.io/) + WebSocket
- **Base de données** : [SQLite](https://www.sqlite.org/) ([better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) + [ClickHouse](https://clickhouse.com/) (facultatif)
- **Build** : [pnpm](https://pnpm.io/) + [Turborepo](https://turbo.build/)
## 🤝 Contribution
Les contributions sont les bienvenues !
- 🐛 [Signaler un bug](https://github.com/foru17/neko-master/issues/new)
- 💡 [Proposer une fonctionnalité](https://github.com/foru17/neko-master/issues/new)
- 🔧 [Contribuer au code](https://github.com/foru17/neko-master/pulls)
Avant d'ouvrir une PR, lisez [CONTRIBUTING.md](https://github.com/foru17/neko-master/blob/main/CONTRIBUTING.md) (workflow, vérifications, exigences i18n/mode sombre).
**Vous développez avec un outil de codage IA ?** (Claude Code, Copilot, Cursor, Codex, ...) Pointez-le vers [AGENTS.md](https://github.com/foru17/neko-master/blob/main/AGENTS.md) — conventions, contrats clés et carte du projet — ainsi que vers les guides de workflow spécifiques aux tâches dans [`.claude/skills/`](https://github.com/foru17/neko-master/blob/main/.claude/skills). Claude Code les détecte automatiquement tous les deux.
## 📄 Licence
[MIT](https://github.com/foru17/neko-master/blob/main/LICENSE) © [foru17](https://github.com/foru17)
---
## ⭐ Historique des étoiles
[](https://www.star-history.com/#foru17/neko-master&type=date&legend=top-left)
---
<p align="center">
<sub>Made with ❤️ by <a href="https://github.com/foru17">@foru17</a></sub><br>
<sub>If this project helps you, please consider giving it a ⭐</sub>
</p>
|
|
|
|
| Fonctionnalité | Description |
|---|
| 📊 Surveillance en temps réel | Collecte en temps réel via WebSocket avec une latence de l'ordre de la milliseconde |
| 📈 Analyse des tendances | Tendances de trafic multidimensionnelles : 30 min / 1 h / 24 h |
| 🌐 Analyse des domaines | Affichez le trafic, les IP associées et le nombre de connexions par domaine |
| 🗺️ Analyse des IP | Affichage de l'ASN, de la géolocalisation et des domaines associés |
| 🚀 Statistiques des proxys | Répartition du trafic et nombre de connexions par nœud proxy |
| 📱 Prise en charge PWA | Installez comme application de bureau pour une expérience native |
| 🌙 Mode sombre | Prise en charge des thèmes clair / sombre / système |
| 🌍 Prise en charge i18n | Basculement transparent anglais / chinois |
| 🔄 Multi-Backend | Surveillez simultanément plusieurs instances backend OpenClash |
| Command | Description |
|---|
help | Affiche le menu d'aide |
list | Liste tous les modules disponibles |
search <keyword> | Recherche des modules par mot-clé |
use <module> | Sélectionne un module à utiliser |
info | Affiche les informations sur le module sélectionné |
options | Affiche les options du module sélectionné |
set <option> <value> | Définit une option pour le module sélectionné |
run | Exécute le module sélectionné |
back | Désélectionne le module actuel |
exit | Quitte le framework |
| Port | Purpose | External Required | Description |
|---|
| 3000 | Web UI | ✅ | Point d'entrée du frontend |
| 3001 | API | Optional | Le frontend utilise /api en same-origin par défaut ; aucune exposition publique n'est généralement nécessaire (le Compose par défaut le mappe) |
| 3002 | WebSocket | Optional | Point de terminaison push en temps réel ; recommandé uniquement pour le transfert via reverse proxy/tunnel (le Compose par défaut le mappe) |
| Variable | Default | Purpose | When to set |
|---|
WEB_PORT | 3000 | Port d'écoute web (à l'intérieur du conteneur) | Généralement inchangé |
API_PORT | 3001 | Port d'écoute de l'API (à l'intérieur du conteneur) | Généralement inchangé |
COLLECTOR_WS_PORT | 3002 | Port d'écoute WS (à l'intérieur du conteneur) | Généralement inchangé |
DB_PATH | /app/data/stats.db | Chemin des données SQLite | Chemin de données personnalisé |
WEB_EXTERNAL_PORT | 3000 | Mappage du port web externe dans docker-compose.yml | Port web externe modifié |
API_EXTERNAL_PORT | 3001 | Mappage du port API externe dans docker-compose.yml | Accès direct à l'API externe nécessaire |
WS_EXTERNAL_PORT | 3002 | Mappage du port WS externe dans docker-compose.yml ; également utilisé pour l'inférence directe du port WS | Accès WS direct sans proxy et port WS externe modifié |
NEXT_PUBLIC_API_URL | empty | Remplacer l'URL de base de l'API du frontend (par ex. https://api.example.com) | L'API n'est pas en same-origin /api |
NEXT_PUBLIC_WS_URL | empty | Remplacer l'URL WS du frontend (URL absolue ou /custom_ws) | Chemin/domaine WS personnalisé |
NEXT_PUBLIC_WS_PORT | 3002 | Port de repli pour la connexion WS directe (uniquement au moment du build — le définir à l'exécution Docker n'a aucun effet ; utilisez WS_EXTERNAL_PORT à la place) | Uniquement pour les builds source personnalisés |
API_URL | http://localhost:3001 | Cible de réécriture /api de Next.js (principalement pour les builds source/personnalisés) | Adresse d'écoute de l'API modifiée |
COOKIE_SECRET | auto-generated | Secret de signature des cookies ; s'il n'est pas fixé, les sessions peuvent être invalidées après redémarrage lorsque le répertoire de données n'est pas persisté | Fortement recommandé en production |
GEOIP_LOOKUP_PROVIDER | online | Source de géolocalisation IP (online / local) | Par défaut, recherche locale via MMDB |
GEOIP_ONLINE_API_URL | https://api.ipinfo.es/ipinfo | Point de terminaison de l'API de géolocalisation IP en ligne (doit être compatible avec le schéma de réponse ipinfo.my) | À définir uniquement lorsque vous déployez un point de terminaison compatible |
FORCE_ACCESS_CONTROL_OFF | false | Forcer la désactivation du contrôle d'accès (récupération d'urgence) | Utilisation temporaire uniquement en cas de perte du token |
SHOWCASE_SITE_MODE | false | Mode vitrine en lecture seule (bloque les opérations d'écriture sensibles) | Sites de démonstration publics uniquement |
| Variable | Default | Description |
|---|
FLUSH_INTERVAL_MS | 30000 | Intervalle de vidage du tampon pour les écritures du collecteur |
FLUSH_MAX_BUFFER_SIZE | 5000 | Nombre maximal d'entrées en tampon avant un vidage anticipé |
REALTIME_MAX_MINUTES | 180 | Taille de la fenêtre en mémoire temps réel (minutes) |
REALTIME_RANGE_END_TOLERANCE_MS | 120000 | Tolérance sur l'heure de fin pour les requêtes de plage |
SURGE_POLICY_SYNC_INTERVAL_MS | 600000 | Intervalle de synchronisation de la politique Surge |
DB_RANGE_QUERY_CACHE_TTL_MS | 8000 | TTL du cache des requêtes de plage |
DB_HISTORICAL_QUERY_CACHE_TTL_MS | 300000 | TTL du cache des requêtes historiques |
DB_RANGE_QUERY_CACHE_MAX_ENTRIES | 1024 | Nombre maximal d'entrées du cache des requêtes de plage |
DB_RANGE_QUERY_CACHE_DISABLED | empty | Définir 1 pour désactiver le cache des requêtes de plage |
DEBUG_SURGE | false | Activer les journaux de débogage du collecteur Surge (true) |
3002NEXT_PUBLIC_WS_URL est généralement inutile sauf si vous utilisez un chemin/domaine WS personnalisé| Variable | Valeur par défaut | Description |
|---|
CH_ENABLED | 0 | Activer la connexion ClickHouse (1 pour activer) |
CH_WRITE_ENABLED | 0 | Activer la double écriture (nécessite CH_ENABLED=1) |
CH_ONLY_MODE | 0 | Lorsque CH est sain, ignorer les écritures de statistiques SQLite (mode CH uniquement) |
CH_HOST | clickhouse | Adresse de l'hôte ClickHouse |
CH_PORT | 8123 | Port HTTP ClickHouse |
CH_DATABASE | neko_master | Nom de la base de données |
CH_USER | neko | Nom d'utilisateur |
CH_PASSWORD | neko_master | Mot de passe |
CH_SECURE | 0 | Utiliser une connexion HTTPS |
CH_REQUIRED | 0 | Refuser de démarrer si CH est indisponible |
CH_AUTO_CREATE_TABLES | 1 | Créer automatiquement les tables au premier démarrage |
CH_WRITE_MAX_PENDING_BATCHES | 200 | Nombre maximal de lots d'écriture en attente |
CH_UNHEALTHY_THRESHOLD | 5 | Nombre d'échecs consécutifs avant de marquer comme non sain (bascule automatique vers SQLite) |
STATS_QUERY_SOURCE | sqlite | Source de lecture : sqlite / auto / clickhouse |
CH_COMPARE_ENABLED | 0 | Activer la vérification de cohérence SQLite ↔ ClickHouse |
CH_EXTERNAL_HTTP_PORT | 8123 | Port HTTP externe ClickHouse (mappage Compose) |
CH_EXTERNAL_NATIVE_PORT | 9000 | Port natif externe ClickHouse (mappage Compose) |