
Um dashboard moderno e elegante para visualização e análise de tráfego de rede.
Neko Master
Veja seu tráfego de rede com clareza.
Monitoramento em tempo real · Auditoria de tráfego · Suporte a múltiplos gateways
English | 中文
[!IMPORTANT] Aviso Legal
Este projeto é uma ferramenta de análise e visualização de tráfego para ambientes de gateway local.
Ele não fornece nenhum serviço de acesso à rede, assinatura de proxy ou conectividade entre redes. Todos os dados são coletados do próprio ambiente de rede do usuário.
Este projeto é open-source sob a Licença MIT. Não assumimos qualquer responsabilidade por consequências decorrentes do uso deste software. Por favor, use-o em conformidade com as leis e regulamentos aplicáveis.
Neko (ねこ) significa gato em japonês. Pronunciado /ˈneɪkoʊ/ (NEH-ko).
Como um gato, o Neko Master observa o tráfego de rede de forma silenciosa e precisa. É um painel de análise leve projetado para ambientes de gateway modernos.
O
docker-compose.ymlintegrado ao repositório mapeia3000/3001/3002por padrão. Os cenários A/B abaixo são templates mínimos para implantações comuns.
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}
> Recomendado em `.env` (mesmo diretório que `docker-compose.yml`):
> `COOKIE_SECRET=<string aleatória de pelo menos 32 bytes>` (gerar com `openssl rand -hex 32`)
> Este modo é totalmente compatível com atualizações e funciona imediatamente.
> Se o WS não estiver roteado, a aplicação recorre automaticamente ao polling HTTP.
#### Cenário B: WebSocket em tempo real (recomendado com proxy reverso)```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}
Em seguida, execute:```bash docker compose up -d
Abra <http://localhost:3000> para começar.
Se você usar o arquivo Compose integrado do repositório (padrão `3000/3001/3002`), execute o mesmo comando.
### Opção 2: Docker Run```bash
# Generate a fixed cookie secret first (for session persistence)
export COOKIE_SECRET="$(openssl rand -hex 32)"
# Clone o repositório
git clone https://github.com/example/tool.git
cd tool
# Instale as dependências
pip install -r requirements.txt
python tool.py --target example.com
Este projeto está licenciado sob a Licença MIT - consulte o arquivo LICENSE para obter detalhes.```bash
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
Abra <http://localhost:3000> para começar.
> O frontend usa `/api` de mesma origem por padrão, então a porta 3001 geralmente não é necessária externamente.
> Para WS em tempo real, seu proxy reverso/túnel precisa conseguir alcançar a porta `3002`. Caso contrário, o aplicativo recorre a polling HTTP de ~5s.
> Para `docker run`, altere as portas externas usando mapeamentos `-p` diretamente.
> Apenas se você usar acesso WS direto (sem proxy reverso) e a porta WS externa não for `3002`, passe também `-e WS_EXTERNAL_PORT=<external-ws-port>`.
>
> Modo de consulta MMDB local (opcional): monte `-v $(pwd)/geoip:/app/data/geoip:ro`,
> depois mude a fonte para Local em `Settings -> Preferences -> IP Lookup Source`.
### Opção 3: Script de Um Clique
Detecta automaticamente conflitos de porta e configura tudo:```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
O script irá automaticamente:
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
Abra <http://localhost:3000> para configurar.
> No modo source: o collector escuta em `3001/3002`, o web escuta em `3000` por padrão.
> Se você alterou `API_PORT` (não 3001), defina `API_URL` de acordo (por exemplo `API_URL=http://localhost:4001`) para que o rewrite de `/api` do web aponte para a API correta.
> `apps/collector/.env.local` tem precedência sobre `apps/collector/.env`.
## 🤖 Implantação do Agent
Use o modo Agent quando você quiser um serviço Neko Master centralizado e vários dispositivos remotos (OpenWrt, Linux, macOS) coletando dados do gateway local. O agent é executado próximo ao gateway, extrai os dados e reporta ao painel — o painel nunca se conecta diretamente ao gateway.
Tipos de gateway suportados: **Clash / Mihomo** (WebSocket em tempo real) e **Surge v5+** (polling HTTP).
### Instalação Rápida (comando gerado pela UI)
1. No dashboard, vá em `Settings → Backends`, adicione um backend `Agent`, selecione o tipo de gateway
2. Clique em **"View Agent Script"** e copie o comando de instalação de uma linha, depois execute-o no host de destino:```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
Após a instalação, gerencie as instâncias com 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)
> O script detecta automaticamente uma instalação existente — se o `neko-agent` já estiver presente, ele apenas adiciona a nova instância sem baixar novamente.
> Várias instâncias podem ser executadas no mesmo host (com `NEKO_INSTANCE_NAME` diferente), cada uma apontando para um gateway diferente.
### Documentação do Agent
- [Visão Geral](https://github.com/foru17/neko-master/blob/main/docs/agent/overview.en.md): arquitetura, comparação entre Direct e Agent, modelo de segurança
- [Início Rápido](https://github.com/foru17/neko-master/blob/main/docs/agent/quick-start.en.md): configuração ponta a ponta, da UI ao agent em execução
- [Guia de Instalação](https://github.com/foru17/neko-master/blob/main/docs/agent/install.en.md): métodos de instalação, inicialização automática com systemd / launchd
- [Configuração](https://github.com/foru17/neko-master/blob/main/docs/agent/config.en.md): referência completa de flags e variáveis de ambiente
- [Fluxo de Release](https://github.com/foru17/neko-master/blob/main/docs/agent/release.en.md): política de versionamento e compatibilidade
- [Solução de Problemas](https://github.com/foru17/neko-master/blob/main/docs/agent/troubleshooting.en.md): erros comuns e correções
## 📖 Primeiro Uso

### Conectar Clash / Mihomo
1. Abra <http://localhost:3000>
2. A caixa de diálogo **Gateway Configuration** aparecerá na primeira visita
3. Preencha as informações de conexão do seu gateway de rede (por exemplo, OpenClash):
- **Name**: Nome personalizado (por exemplo, "Home Gateway")
- **Type**: Selecione `Clash / Mihomo`
- **Host**: Endereço do backend do gateway (por exemplo, `192.168.101.1`)
- **Port**: Porta do backend do gateway (por exemplo, `9090`)
- **Token**: Preencha se o Secret estiver configurado, caso contrário deixe vazio
4. Clique em "Add Backend" para salvar
5. O sistema começará automaticamente a coletar e analisar dados de tráfego
> 💡 **Obter Endereço do Gateway**: Vá ao painel de controle do seu gateway (por exemplo, OpenClash) → Ative "External Control" → Copie o endereço da API
### Conectar Surge

O Neko Master suporta a conexão com gateways Surge para visualização completa da cadeia de regras e análise de tráfego.
#### 1. Ativar a API HTTP do Surge
Ative a API remota HTTP na sua configuração do Surge:```ini
[General]
http-api = 127.0.0.1:9091
http-api-tls = false
http-api-web-dashboard = true
Ou configure através da interface gráfica do Surge:
Settings → General → HTTP Remote API9091Surge192.168.1.1 ou 127.0.0.1)9091)💡 Nota: O Surge utiliza polling HTTP para obter dados (em comparação com o stream em tempo real via WebSocket do Clash), com um atraso de atualização de dados de aproximadamente 2 segundos.
Se vir o erro "port already in use", aqui estão as soluções:
Crie um ficheiro .env no mesmo diretório que o 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
Em seguida, reinicie:```bash
docker compose down
docker compose up -d
Agora acesse http://localhost:8080
ports:
> Nota: se você usar acesso WS direto (sem proxy reverso) e a porta WS externa não for `3002`, defina `WS_EXTERNAL_PORT=<external-ws-port>`.
### Solução 3: Usar Script de Um Clique```bash
curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
O script detectará e sugerirá automaticamente as portas disponíveis.
runtime-config.API_URL → NEXT_PUBLIC_API_URL → /api de mesma origem/api: API_URL (padrão http://localhost:3001, aplicado nas reescritas do Next.js)runtime-config.WS_URL → NEXT_PUBLIC_WS_URL → candidatos automáticos (quando runtime-config.WS_PORT está definido, a porta direta é preferida; caso contrário, /_cm_ws é tentado primeiro)runtime-config.WS_PORT (de WS_EXTERNAL_PORT) → NEXT_PUBLIC_WS_PORT → NODE_ENV=production DB_PATH=/app/data/stats.db COOKIE_SECRET=<at least 32-byte random string>
Use `openssl rand -hex 32` para gerar `COOKIE_SECRET`.
Recomendações adicionais:
1. Monte armazenamento persistente (por exemplo `./data:/app/data`) para evitar perda de dados e segredos.
2. Se usar acesso WS direto e a porta WS externa não for `3002`, defina `WS_EXTERNAL_PORT` de acordo.
3. Se a porta/endereço da API mudar na implantação de origem, atualize `API_URL` também.
4. Para consulta MMDB local, monte `./geoip:/app/data/geoip:ro` e altere a origem em `Settings -> Preferences -> IP Lookup Source`.
5. Os arquivos MMDB são grandes e não estão incluídos na imagem. Baixe-os e coloque-os em `./geoip` com nomes fixos:
`GeoLite2-City.mmdb`, `GeoLite2-ASN.mmdb` (obrigatório) e `GeoLite2-Country.mmdb` (opcional).
Fonte recomendada: <https://github.com/P3TERX/GeoLite.mmdb>.
> Detalhes avançados do Agent (instalação, configuração, release, compatibilidade) são mantidos em `docs/agent/*`.
## 🗄️ ClickHouse (Opcional)
SQLite é o mecanismo de armazenamento padrão do Neko Master e funciona bem para a maioria dos usuários.
Considere habilitar o ClickHouse se você precisar de:
- Conjuntos de dados muito grandes (centenas de milhares de entradas de domínio/IP)
- Consultas de agregação rápidas em longos intervalos de tempo (≥ 7 dias)
- Separação de estatísticas históricas do armazenamento de configuração/metadados
> O ClickHouse é totalmente opcional. O SQLite permanece como armazenamento de configuração e metadados independentemente de o ClickHouse estar habilitado.
### Visão Geral da Arquitetura
Quando o ClickHouse está habilitado, o sistema entra em **modo de escrita dupla**:```
BatchBuffer.flush()
│
├──→ SQLite (config / metadata, always written)
└──→ ClickHouse (stats traffic data, dual-write)
└── Buffer tables → SummingMergeTree async merge
A leitura da fonte é controlada por STATS_QUERY_SOURCE (padrão: sqlite).
O docker-compose.yml integrado ao repositório já inclui um serviço ClickHouse, controlado por
profiles: [clickhouse] para que não seja iniciado por padrão. A partir da raiz do repositório, execute:```bash
docker compose --profile clickhouse up -d
> Os dados do ClickHouse são persistidos em `./data/clickhouse`, separadamente do diretório de dados principal da aplicação.
Se você usar um **`docker-compose.yml` personalizado** (como o Cenário A/B acima), adicione o
bloco de serviço do ClickHouse manualmente:```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
Adicione ao seu .env (mesmo diretório 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
Reiniciar:```bash
docker compose --profile clickhouse up -d
Saúde e Fallback: Após
CH_UNHEALTHY_THRESHOLDfalhas de escrita consecutivas, o sistema marca automaticamente o ClickHouse como não saudável e retoma as escritas no SQLite — mesmo quandoCH_ONLY_MODE=1. Assim que o ClickHouse se recupera, ele é marcado novamente como saudável e isso é registrado.
Atualizando de uma versão apenas SQLite? Seus dados estão seguros. O arquivo SQLite (
./data/stats.db) é totalmente preservado. Aqui está o caminho de migração gradual recomendado:
CH_ENABLED=1 CH_WRITE_ENABLED=1 STATS_QUERY_SOURCE=sqlite # Keep reading from SQLite while CH accumulates data
Inicie e observe os logs do `[ClickHouse Writer]` para confirmar gravações bem-sucedidas.
#### Fase 2: Alternar a fonte de leitura```env
STATS_QUERY_SOURCE=auto # Smart routing: recent data from CH, historical from SQLite
# or
STATS_QUERY_SOURCE=clickhouse # Force all reads to ClickHouse
Para mover estatísticas históricas do SQLite para o 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
#### Fase 4 (opcional): modo somente CH
Depois que o ClickHouse estiver em execução estável, interrompa as gravações de estatísticas no SQLite:```env
CH_ONLY_MODE=1
Mesmo com
CH_ONLY_MODE=1, se o ClickHouse ficar indisponível, o sistema recorre automaticamente a escritas no SQLite — sem perda de dados.
Pode sempre reverter completamente:```env CH_ENABLED=0 CH_WRITE_ENABLED=0 CH_ONLY_MODE=0 STATS_QUERY_SOURCE=sqlite
Reinicie e tudo retorna ao modo SQLite puro. Os dados históricos permanecem intactos.
---
## 🌐 Proxy Reverso e Túnel
Abordagem recomendada: manter Web e WS sob o mesmo domínio, com roteamento por caminho:
`/` → `3000`, `/_cm_ws` → `3002`.
### Exemplo Padrão do 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;
}
}
Substituição opcional por variável de ambiente:```env
### Exemplo Padrão do Cloudflare Tunnel
`~/.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
Executar:```bash cloudflared tunnel --config ~/.cloudflared/config.yml run
Para rotas gerenciadas pelo painel Zero Trust (modo token), configure as mesmas duas rotas e mantenha `/_cm_ws*` acima de `/*`.
### Notas Importantes
1. Não use `ws` (sem barra inicial) como caminho WS; ele pode fazer overmatch e causar `/_next/static/...` → `426 Upgrade Required`
2. A rota WS deve estar acima do catch-all `/*`
3. `NEXT_PUBLIC_WS_URL` é opcional por padrão; se personalizado, reinicie o frontend/container após as alterações
4. Mapear apenas `3000` ainda funciona, mas recorre a HTTP polling (~5s), com menor responsividade em tempo real
5. Falhas do `beacon.min.js` (script de analytics do Cloudflare) normalmente não estão relacionadas ao fluxo de dados da API/WS do app
6. Nenhuma regra extra de reverse-proxy `/api` é necessária na maioria das configurações; o frontend usa `/api` na mesma origem e o app lida com o encaminhamento interno para `3001`
> Nota: `/_next/static/... 426 Upgrade Required` é comum em configurações de **reverse proxy / tunnel mal configurados**; é incomum em acesso local direto sem proxy.
### Suporte Multi-Arquitetura
As imagens Docker suportam tanto `linux/amd64` quanto `linux/arm64`.
### Persistência de Dados
Os dados são armazenados em `/app/data` dentro do container. Monte-o no host para evitar perda de dados:```yaml
volumes:
- ./data:/app/data
docker compose pull docker compose up -d
## 🔐 Autenticação e Segurança
O Neko Master suporta autenticação de acesso para proteger os dados do dashboard.
### Linha de Base de Segurança para Produção
1. Defina um `COOKIE_SECRET` fixo (caso contrário, as sessões podem ser invalidadas após a reinicialização).
2. Não mantenha `FORCE_ACCESS_CONTROL_OFF=true` ativado em operação normal.
3. Use `SHOWCASE_SITE_MODE=true` apenas para ambientes de demonstração públicos (as operações de escrita são restringidas).
Exemplo:```env
COOKIE_SECRET=<at least 32-byte random string>
# FORCE_ACCESS_CONTROL_OFF=false
# SHOWCASE_SITE_MODE=false
Se você esqueceu o token, defina temporariamente FORCE_ACCESS_CONTROL_OFF=true para entrar no modo de emergência.
docker-compose.yml: ```yaml
environment:
3000:3000?R: Sim. As funcionalidades principais continuam a funcionar.
Se o WS não estiver roteado, a aplicação recorre automaticamente ao polling HTTP.
Para uma experiência em tempo real completa, roteie /_cm_ws para 3002.
R: Crie/atualize o .env (no mesmo diretório que o docker-compose.yml):```env
WEB_EXTERNAL_PORT=8080
API_EXTERNAL_PORT=8081
WS_EXTERNAL_PORT=8082
Em seguida, reinicie:```bash
docker compose down
docker compose up -d
R: Normalmente porque COOKIE_SECRET não é fixo ou o diretório de dados não é persistido.
COOKIE_SECRET fixo./data:/app/dataR: Crie ./geoip no diretório do seu projeto (recomenda-se no mesmo nível de docker-compose.yml), depois coloque:
GeoLite2-City.mmdb (obrigatório)GeoLite2-ASN.mmdb (obrigatório)GeoLite2-Country.mmdb (opcional)Fonte recomendada: https://github.com/P3TERX/GeoLite.mmdb.
Dentro do container, o caminho de consulta fixo é /app/data/geoip, então mantenha:
./geoip:/app/data/geoip:ro. Para atualizar depois, basta substituir os arquivos no host ./geoip.
R: Verifique:
R: Faça backup primeiro:```bash cp -r ./data ./data-backup-$(date +%Y%m%d)
Restaurar:```bash
docker compose down
cp -r ./data-backup-YYYYMMDD/. ./data/
docker compose up -d
Se você quer entender rapidamente a profundidade do design do sistema, leia nesta ordem:
RealtimeStore e push via WSÍndice completo da documentação: docs/README.md
Esta documentação cobre o design central de coleta, agregação, cache, push em tempo real e gerenciamento multi-backend.
Este projeto usa GitHub Issue Templates (Bug / Feature / Support).
Por favor, inclua pelo menos:
COOKIE_SECRET=***)docker logs, console do navegador, erros de rede)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 Tecnológico
- **Frontend**: [Next.js 16](https://nextjs.org/) + [React 19](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/)
- **Estilização**: [Tailwind CSS](https://tailwindcss.com/) + [shadcn/ui](https://ui.shadcn.com/)
- **Gráficos**: [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
- **Banco de Dados**: [SQLite](https://www.sqlite.org/) ([better-sqlite3](https://github.com/WiseLibs/better-sqlite3)) + [ClickHouse](https://clickhouse.com/) (opcional)
- **Build**: [pnpm](https://pnpm.io/) + [Turborepo](https://turbo.build/)
## 🤝 Contribuindo
Contribuições são bem-vindas!
- 🐛 [Reportar Bug](https://github.com/foru17/neko-master/issues/new)
- 💡 [Solicitar Funcionalidade](https://github.com/foru17/neko-master/issues/new)
- 🔧 [Contribuir com Código](https://github.com/foru17/neko-master/pulls)
Antes de abrir um PR, leia o [CONTRIBUTING.md](https://github.com/foru17/neko-master/blob/main/CONTRIBUTING.md) (fluxo de trabalho, verificações, requisitos de i18n/modo escuro).
**Desenvolvendo com uma ferramenta de codificação com IA?** (Claude Code, Copilot, Cursor, Codex, ...) Aponte-a para [AGENTS.md](https://github.com/foru17/neko-master/blob/main/AGENTS.md) — convenções, contratos principais e o mapa do projeto — além dos guias de fluxo de trabalho específicos por tarefa em [`.claude/skills/`](https://github.com/foru17/neko-master/blob/main/.claude/skills). O Claude Code captura ambos automaticamente.
## 📄 Licença
[MIT](https://github.com/foru17/neko-master/blob/main/LICENSE) © [foru17](https://github.com/foru17)
---
## ⭐ Histórico de Estrelas
[](https://www.star-history.com/#foru17/neko-master&type=date&legend=top-left)
---
<p align="center">
<sub>Feito com ❤️ por <a href="https://github.com/foru17">@foru17</a></sub><br>
<sub>Se este projeto te ajuda, considere dar uma ⭐</sub>
</p>
|
|
|
|
| Recurso | Descrição |
|---|
| 📊 Monitoramento em Tempo Real | Coleta em tempo real via WebSocket com latência em milissegundos |
| 📈 Análise de Tendências | Tendências de tráfego multidimensionais: 30min / 1h / 24h |
| 🌐 Análise de Domínios | Visualize tráfego, IPs associados e contagem de conexões por domínio |
| 🗺️ Análise de IP | Exibição de ASN, geolocalização e domínios associados |
| 🚀 Estatísticas de Proxy | Distribuição de tráfego e contagem de conexões por nó de proxy |
| 📱 Suporte a PWA | Instale como aplicativo de desktop para uma experiência nativa |
| 🌙 Modo Escuro | Suporte a tema Claro / Escuro / Sistema |
| 🌍 Suporte a i18n | Alternância perfeita entre Inglês / Chinês |
| 🔄 Multi-Backend | Monitore múltiplas instâncias de backend OpenClash simultaneamente |
| Porta | Finalidade | Externo Obrigatório | Descrição |
|---|
| 3000 | Interface Web | ✅ | Ponto de entrada do frontend |
| 3001 | API | Opcional | O frontend usa /api de mesma origem por padrão; geralmente não é necessária exposição pública (o Compose padrão a mapeia) |
| 3002 | WebSocket | Opcional | Endpoint de push em tempo real; recomendado apenas para encaminhamento via proxy reverso/túnel (o Compose padrão o mapeia) |
| Variável | Padrão | Finalidade | Quando definir |
|---|
WEB_PORT | 3000 | Porta de escuta da Web (dentro do contêiner) | Geralmente inalterada |
API_PORT | 3001 | Porta de escuta da API (dentro do contêiner) | Geralmente inalterada |
COLLECTOR_WS_PORT | 3002 | Porta de escuta do WS (dentro do contêiner) | Geralmente inalterada |
DB_PATH | /app/data/stats.db | Caminho dos dados SQLite | Caminho de dados personalizado |
WEB_EXTERNAL_PORT | 3000 | Mapeamento da porta web externa em docker-compose.yml | Porta web externa alterada |
API_EXTERNAL_PORT | 3001 | Mapeamento da porta da API externa em docker-compose.yml | Acesso direto à API externa necessário |
WS_EXTERNAL_PORT | 3002 | Mapeamento da porta WS externa em docker-compose.yml; também usado para inferência direta da porta WS | Acesso direto ao WS sem proxy e porta WS externa alterada |
NEXT_PUBLIC_API_URL | vazio | Substituir a URL base da API do frontend (ex.: https://api.example.com) | A API não é /api de mesma origem |
NEXT_PUBLIC_WS_URL | vazio | Substituir a URL do WS do frontend (URL absoluta ou /custom_ws) | Caminho/domínio WS personalizado |
NEXT_PUBLIC_WS_PORT | 3002 | Porta de fallback para conexão direta ao WS (somente em tempo de build — defini-la em tempo de execução do Docker não tem efeito; use WS_EXTERNAL_PORT em vez disso) | Apenas para builds de código-fonte personalizados |
API_URL | http://localhost:3001 | Alvo de reescrita de /api do Next.js (principalmente builds de código-fonte/personalizados) | Endereço de escuta da API alterado |
COOKIE_SECRET | gerado automaticamente | Segredo de assinatura de cookies; se não for fixado, as sessões podem ser invalidadas após reinício quando o diretório de dados não é persistido | Fortemente recomendado em produção |
GEOIP_LOOKUP_PROVIDER | online | Fonte de geolocalização de IP (online / local) | Padrão para consulta local em MMDB |
GEOIP_ONLINE_API_URL | https://api.ipinfo.es/ipinfo | Endpoint da API online de geolocalização de IP (deve ser compatível com o esquema de resposta de ipinfo.my) | Defina apenas quando você implantar um endpoint compatível |
FORCE_ACCESS_CONTROL_OFF | false | Forçar a desativação do controle de acesso (recuperação de emergência) | Uso temporário apenas quando o token for perdido |
SHOWCASE_SITE_MODE | false | Modo vitrine somente leitura (bloqueia operações de escrita sensíveis) | Apenas para sites de demonstração públicos |
| Variável | Padrão | Descrição |
|---|
FLUSH_INTERVAL_MS | 30000 | Intervalo de descarga do buffer para gravações do coletor |
FLUSH_MAX_BUFFER_SIZE | 5000 | Número máximo de entradas no buffer antes da descarga antecipada |
REALTIME_MAX_MINUTES | 180 | Tamanho da janela em memória em tempo real (minutos) |
REALTIME_RANGE_END_TOLERANCE_MS | 120000 | Tolerância de horário final para consultas de intervalo |
SURGE_POLICY_SYNC_INTERVAL_MS | 600000 | Intervalo de sincronização da política de Surge |
DB_RANGE_QUERY_CACHE_TTL_MS | 8000 | TTL do cache de consultas de intervalo |
DB_HISTORICAL_QUERY_CACHE_TTL_MS | 300000 | TTL do cache de consultas históricas |
DB_RANGE_QUERY_CACHE_MAX_ENTRIES | 1024 | Número máximo de entradas no cache de consultas de intervalo |
DB_RANGE_QUERY_CACHE_DISABLED | vazio | Defina 1 para desativar o cache de consultas de intervalo |
DEBUG_SURGE | false | Ativar logs de depuração do coletor Surge (true) |
3002NEXT_PUBLIC_WS_URL geralmente é desnecessário, a menos que você use um caminho/domínio WS personalizado| Variável | Padrão | Descrição |
|---|
CH_ENABLED | 0 | Ativa a conexão com o ClickHouse (1 para ativar) |
CH_WRITE_ENABLED | 0 | Ativa a escrita dupla (requer CH_ENABLED=1) |
CH_ONLY_MODE | 0 | Quando o CH está saudável, ignora as escritas de estatísticas no SQLite (modo apenas CH) |
CH_HOST | clickhouse | Endereço do host do ClickHouse |
CH_PORT | 8123 | Porta HTTP do ClickHouse |
CH_DATABASE | neko_master | Nome do banco de dados |
CH_USER | neko | Nome de usuário |
CH_PASSWORD | neko_master | Senha |
CH_SECURE | 0 | Usar conexão HTTPS |
CH_REQUIRED | 0 | Recusar a inicialização se o CH estiver indisponível |
CH_AUTO_CREATE_TABLES | 1 | Criar tabelas automaticamente na primeira inicialização |
CH_WRITE_MAX_PENDING_BATCHES | 200 | Máximo de lotes de escrita pendentes |
CH_UNHEALTHY_THRESHOLD | 5 | Falhas consecutivas antes de marcar como não saudável (fallback automático para SQLite) |
STATS_QUERY_SOURCE | sqlite | Fonte de leitura: sqlite / auto / clickhouse |
CH_COMPARE_ENABLED | 0 | Ativa a verificação de consistência SQLite ↔ ClickHouse |
CH_EXTERNAL_HTTP_PORT | 8123 | Porta HTTP externa do ClickHouse (mapeamento do Compose) |
CH_EXTERNAL_NATIVE_PORT | 9000 | Porta Native externa do ClickHouse (mapeamento do Compose) |