Configuard is a self-hosted web application for centralized management of network device configurations. It collects, organizes, versions and schedules backups of routers, switches, firewalls and any device accessible via SSH or Telnet.
- Português
- Features
- Requirements
- Quick Start
- Configuration
- User roles
- Backup templates
- Schedules
- Search
- Scripts reference
- API
- Security notes
- Contributing
| Area | What it does |
|---|---|
| Device inventory | Register devices with IP, port, OS type, brand, model and category |
| Credentials | Encrypted SSH/Telnet credentials (AES-256-GCM), shared across devices |
| Backup templates | Vendor-specific command sequences with prompt detection, pagination and output cleanup |
| SSH / Telnet | Dual-mode SSH (Paramiko + pexpect fallback for legacy devices), Telnet via pexpect |
| Versioning | Every changed backup creates a new version; unchanged configs are not stored again |
| Diff viewer | Side-by-side unified diff between any two versions |
| Schedules | Daily, weekly, monthly or arbitrary cron expressions; per-device or per-category |
| Global search | Full-text search using PostgreSQL FTS (GIN index); supports partial IPs, CIDR, regex |
| Dashboard | Success rate, change rate, recent backup jobs, alerts for failed or disabled devices |
| Audit logs | Every CRUD action is logged with user, timestamp and affected record |
| Email notifications | SMTP alerts on backup success or failure; configurable per event type |
| LDAP / Active Directory | Optional LDAP authentication alongside local accounts |
| Multi-language UI | Portuguese (pt-BR) and English (en); toggle in the Admin panel |
| Inactivity timeout | Automatic logout after configurable idle period |
| Role-based access | Admin, Moderator and User roles with granular permissions |
- Docker Engine 24+
- Docker Compose v2
- Node.js 18+ and npm (only needed to rebuild the frontend after code changes)
- Docker (for PostgreSQL)
- Python 3.12+
- Node.js 18+ and npm
# 1. Clone the repository
git clone https://github.com/thiagoe/configuard.git
cd configuard
# 2. Configure environment variables
cp .env.example .env
# Edit .env — set DB_PASSWORD, API_TOKEN and ENCRYPTION_KEY to secure values
# 3. Start everything
docker compose up -d --build
# 4. Open the browser
# Frontend: http://localhost:8080
# API docs: http://localhost:8000/api/docsDefault credentials — change immediately in production:
| Field | Value |
|---|---|
admin@configuard.com |
|
| Password | Admin@123 |
Stop all containers:
docker compose downRebuild after code changes:
./scripts/reload.sh # full rebuild: frontend build + restart containers
./scripts/reload.sh frontend # frontend only (npm run build + nginx reload)
./scripts/reload.sh backend # backend only (picks up new Python dependencies)The backend container runs
uvicorn --reload, so Python code changes are picked up automatically without a restart. Usereload.sh backendonly when you add or remove Python dependencies.
Useful when you want live hot-reload for both frontend and backend without rebuilding Docker images.
# 1. Start only the database
docker compose up -d postgresql
# 2. Backend (new terminal)
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # edit: DB_HOST=localhost, secrets
uvicorn main:app --reload --port 8000
# 3. Frontend (new terminal)
cd frontend
npm install
cp .env.example .env # VITE_API_URL=http://localhost:8000/api
npm run dev # http://localhost:5173Used by docker-compose.yml. Copy .env.example to .env and set secure values.
# Database
DB_NAME=configuard
DB_USER=configuard
DB_PASSWORD=TROQUE_PELA_SENHA_DO_BANCO
DB_PORT=5432
# Backend
DEBUG=false
ENVIRONMENT=production
# Static API token for internal service communication
# Generate: openssl rand -hex 32
API_TOKEN=TROQUE_POR_TOKEN_SEGURO
# AES-256 encryption key — exactly 64 hex characters
# Generate: openssl rand -hex 32
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
# CORS origins (comma-separated; in Docker the nginx proxy handles this)
CORS_ORIGINS_STR=http://localhost:8080
# Timezone
TIMEZONE=America/Sao_Paulo
# Logging
LOG_LEVEL=INFO
LOG_RETENTION_DAYS=30
# Exposed host ports
BACKEND_PORT=8000
FRONTEND_PORT=8080DB_HOST=localhost
DB_PORT=5432
DB_USER=configuard
DB_PASSWORD=configuard123
DB_NAME=configuard
# JWT — MUST be changed in production (min 32 chars)
JWT_SECRET_KEY=your-secret-key-min-32-characters
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# AES-256 encryption key (64 hex chars = 32 bytes)
# Generate: openssl rand -hex 32
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
CORS_ORIGINS_STR=http://localhost:5173,http://localhost:8080
TIMEZONE=America/Sao_Paulo
LOG_LEVEL=INFO
LOG_DIR=logs# Development (direct to backend)
VITE_API_URL=http://localhost:8000/api
# Docker mode (nginx proxy — already set in frontend/.env.production)
# VITE_API_URL=/api
# Auto-logout after N minutes of inactivity (0 to disable)
VITE_INACTIVITY_TIMEOUT_MINUTES=30In Docker mode,
frontend/.env.productionalready setsVITE_API_URL=/api. You do not need to change it.
| Role | Capabilities |
|---|---|
| Admin | Full access: user management, audit logs, system settings, LDAP, email, database stats |
| Moderator | Devices, templates, credentials, brands, categories, schedules, backups |
| User | View devices; execute manual backups on devices they own |
Role assignment is done in Admin → Users.
A template defines how Configuard connects to a device and what commands to run to collect its configuration.
| Setting | Description |
|---|---|
prompt_pattern |
Regex to detect the device shell prompt (e.g. [#>$]) |
login_success_pattern |
Separate regex for post-login detection only (falls back to prompt_pattern if unset) |
login_prompt |
String to wait for during the login sequence |
password_prompt |
String to wait for when the device asks for the password |
pagination_pattern |
Regex for "press space for more" prompts (e.g. --More--) |
line_ending |
\n for Cisco/Linux devices; \r\n for MikroTik/Windows |
use_steps |
Enable step-based execution (advanced mode) |
output_cleanup_patterns |
Regex patterns (one per line) to strip from the final output |
connection_timeout |
Seconds to wait for the SSH/Telnet connection |
command_timeout |
Seconds to wait for each command response |
transport_options |
JSONB object with Telnet sync behavior (see below) |
Per-template JSON configuration for devices that require terminal synchronization after login:
{
"telnet_sync": {
"enabled": true,
"idle_ms": 400,
"settle_ms": 500,
"after_login": true,
"enter_count": 2,
"before_commands": []
}
}Useful for devices (e.g. TP-Link) that emit async audit logs immediately after login with no newline.
| Type | Behavior |
|---|---|
command |
Send a command, wait for the prompt (or a custom expect_pattern) |
expect |
Wait for a pattern without sending anything |
pause |
Sleep for N seconds |
set_prompt |
Change the active prompt pattern mid-session |
send_key |
Send a special key: enter, space, tab, escape, ctrl+c, ctrl+z |
conditional |
Execute the step only if a captured variable matches a condition |
Steps support on_failure (stop / continue / retry), max_retries, capture_output and variable_name for storing output into variables used by later conditional steps.
Templates can be exported and imported as JSON files — useful for sharing between environments or teams.
Schedules run backups automatically against a set of devices or entire categories.
- Frequencies: hourly, daily, weekly, monthly, or a custom cron expression
- Targets: individual devices, all devices in one or more categories, or both
- On failure: email notification sent if SMTP is configured
- History: every execution is recorded in the backup executions table (success, failure, config changed or unchanged)
Enable or disable a schedule at any time without deleting it.
The search page performs full-text search across all stored configuration snapshots.
| Mode | How it works |
|---|---|
| Default | PostgreSQL plainto_tsquery with GIN index — fast, ranked results |
| Partial token | Automatic ILIKE fallback for partial IPs (e.g. 192.168) and CIDR prefixes |
| Regex | PostgreSQL ~* operator (case-insensitive); enable with the Regex toggle |
| Filter | Description |
|---|---|
| Device | Restrict to one or more specific devices |
| Category | Restrict to all devices in a category |
| Period | Last 7, 30, 90 days or one year |
| Latest only | Search only the most recent version per device (faster, less noise) |
Results display matched lines with syntax highlighting and links to the device page and full version history.
Tip: The search input accepts regular expressions when the Regex toggle is on. Example:
interface GigabitEthernet\d+
All scripts live in scripts/ and are run from the project root.
| Command | Description |
|---|---|
./scripts/reload.sh [all|frontend|backend] |
Rebuild and reload in Docker container mode |
./scripts/start.sh [all|db|backend|frontend] |
Start services in local dev mode |
./scripts/stop.sh [all|db|backend|frontend] |
Stop local dev services |
./scripts/status.sh |
Show running status and URLs |
Interactive API documentation:
- Swagger UI:
http://localhost:8000/api/docs - ReDoc:
http://localhost:8000/api/redoc
All protected endpoints require Authorization: Bearer <access_token>.
The templates/ directory contains ready-to-use backup templates that can be imported directly in the Backup Templates page.
| File | Device |
|---|---|
template-cisco.yaml |
Cisco |
template-mikrotik-rb750.yaml |
MikroTik RB750 |
template-huawei-ne8k.yaml |
Huawei NE8K |
template-huawei-sw-6730.yaml |
Huawei SW-6730 |
template-olt-huawei.yaml |
OLT Huawei |
template-olts-zte.yaml |
OLT ZTE |
template-olts-zte-titan.yaml |
OLT ZTE Titan |
template-hillstone.yaml |
Hillstone |
template-a10-th1040.yaml |
A10 TH1040 |
template-sw-datacom.yaml |
Switch Datacom |
template-sw-tp-link.yaml |
Switch TP-Link |
To import: go to Backup Templates → Import and select the desired file.
- Credentials are encrypted with AES-256-GCM before storage. The
ENCRYPTION_KEYmust be kept secret and backed up — losing it means losing access to all stored credentials. - JWT secret (
JWT_SECRET_KEY) must be at least 32 characters and changed from the example value before any production deployment. - Default admin password (
Admin@123) must be changed immediately after the first login. - LDAP bind password is also stored encrypted with the same key.
- Roles are stored only in the
user_rolestable — never in JWT tokens or browser storage. - All SQL queries use parameterized statements; user input is never interpolated into raw SQL.
- CORS is restricted to the origins defined in
CORS_ORIGINS_STR.
Bug reports and feature requests are welcome via Issues.
Backup de configuração de rede com versionamento, diff e busca.
O Configuard é uma aplicação web auto-hospedada para gerenciamento centralizado de configurações de dispositivos de rede. Ele coleta, organiza, versiona e agenda backups de roteadores, switches, firewalls e qualquer dispositivo acessível via SSH ou Telnet.
- Recursos
- Requisitos
- Início rápido
- Configuração PT
- Papéis de usuário
- Templates de backup
- Agendamentos
- Busca
- Referência dos scripts PT
- API
- Templates de exemplo
- Segurança
- Contribuindo
| Área | O que faz |
|---|---|
| Inventário de dispositivos | Cadastro com IP, porta, tipo de OS, marca, modelo e categoria |
| Credenciais | Credenciais SSH/Telnet criptografadas (AES-256-GCM), compartilhadas entre dispositivos |
| Templates de backup | Sequências de comandos por fabricante com detecção de prompt, paginação e limpeza de saída |
| SSH / Telnet | SSH dual-mode (Paramiko + pexpect para dispositivos legados), Telnet via pexpect |
| Versionamento | Cada backup com mudança gera uma nova versão; configs sem alteração não são re-armazenadas |
| Diff | Comparação lado a lado entre quaisquer duas versões |
| Agendamentos | Diário, semanal, mensal ou cron customizado; por dispositivo ou por categoria |
| Busca global | Full-text search em todas as configurações (GIN index); suporte a IPs parciais, CIDR e regex |
| Dashboard | Taxa de sucesso, taxa de mudança, jobs recentes e alertas |
| Auditoria | Toda ação CRUD é registrada com usuário, timestamp e registro afetado |
| Notificações por email | Alertas SMTP em sucesso ou falha de backup; configurável por tipo de evento |
| LDAP / Active Directory | Autenticação LDAP opcional ao lado de contas locais |
| Interface multi-idioma | Português (pt-BR) e Inglês (en); alternável no painel Admin |
| Timeout de inatividade | Logout automático após período de inatividade configurável |
| Controle de acesso | Papéis Admin, Moderador e Usuário com permissões granulares |
- Docker Engine 24+
- Docker Compose v2
- Node.js 18+ e npm (apenas para rebuild do frontend após mudanças no código)
- Docker (para o PostgreSQL)
- Python 3.12+
- Node.js 18+ e npm
# 1. Clone o repositório
git clone https://github.com/thiagoe/configuard.git
cd configuard
# 2. Configure as variáveis de ambiente
cp .env.example .env
# Edite o .env — defina valores seguros para DB_PASSWORD, API_TOKEN e ENCRYPTION_KEY
# 3. Suba tudo
docker compose up -d --build
# 4. Abra no navegador
# Frontend: http://localhost:8080
# API docs: http://localhost:8000/api/docsCredenciais padrão — altere imediatamente em produção:
| Campo | Valor |
|---|---|
admin@configuard.com |
|
| Senha | Admin@123 |
Parar todos os containers:
docker compose downRebuild após mudanças no código:
./scripts/reload.sh # rebuild completo: frontend build + restart dos containers
./scripts/reload.sh frontend # só frontend (npm run build + nginx reload)
./scripts/reload.sh backend # só backend (necessário ao adicionar dependências Python)O container do backend roda
uvicorn --reload, então mudanças no código Python são detectadas automaticamente sem reiniciar. Usereload.sh backendapenas ao adicionar ou remover dependências Python.
# 1. Suba apenas o banco de dados
docker compose up -d postgresql
# 2. Backend (novo terminal)
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # edite: DB_HOST=localhost e secrets
uvicorn main:app --reload --port 8000
# 3. Frontend (novo terminal)
cd frontend
npm install
cp .env.example .env # VITE_API_URL=http://localhost:8000/api
npm run dev # http://localhost:5173Usado pelo docker-compose.yml. Copie .env.example para .env e defina valores seguros.
# Banco de dados
DB_NAME=configuard
DB_USER=configuard
DB_PASSWORD=TROQUE_PELA_SENHA_DO_BANCO
DB_PORT=5432
# Backend
DEBUG=false
ENVIRONMENT=production
# Token estático para comunicação interna entre serviços
# Gerar: openssl rand -hex 32
API_TOKEN=TROQUE_POR_TOKEN_SEGURO
# Chave de criptografia AES-256 — exatamente 64 caracteres hexadecimais
# Gerar: openssl rand -hex 32
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
# CORS (no modo Docker, o proxy nginx cuida disso)
CORS_ORIGINS_STR=http://localhost:8080
# Fuso horário
TIMEZONE=America/Sao_Paulo
# Logs
LOG_LEVEL=INFO
LOG_RETENTION_DAYS=30
# Portas expostas no host
BACKEND_PORT=8000
FRONTEND_PORT=8080DB_HOST=localhost
DB_PORT=5432
DB_USER=configuard
DB_PASSWORD=configuard123
DB_NAME=configuard
# JWT — DEVE ser alterado em produção (mínimo 32 chars)
JWT_SECRET_KEY=sua-chave-secreta-minimo-32-caracteres
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# Chave de criptografia AES-256 (64 hex chars = 32 bytes)
# Gerar: openssl rand -hex 32
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
CORS_ORIGINS_STR=http://localhost:5173,http://localhost:8080
TIMEZONE=America/Sao_Paulo
LOG_LEVEL=INFO
LOG_DIR=logs# Desenvolvimento (direto ao backend)
VITE_API_URL=http://localhost:8000/api
# Modo Docker (proxy nginx — já definido em frontend/.env.production)
# VITE_API_URL=/api
# Logout automático após N minutos de inatividade (0 para desativar)
VITE_INACTIVITY_TIMEOUT_MINUTES=30No modo Docker,
frontend/.env.productionjá defineVITE_API_URL=/api. Não é necessário alterar.
| Papel | Permissões |
|---|---|
| Admin | Acesso total: gestão de usuários, auditoria, configurações do sistema, LDAP, email, stats do banco |
| Moderador | Dispositivos, templates, credenciais, marcas, categorias, agendamentos, backups |
| Usuário | Visualizar dispositivos; executar backups manuais nos próprios dispositivos |
A atribuição de papéis é feita em Admin → Usuários.
Um template define como o Configuard se conecta a um dispositivo e quais comandos executar para coletar a configuração.
| Configuração | Descrição |
|---|---|
prompt_pattern |
Regex para detectar o prompt do dispositivo (ex: [#>$]) |
login_success_pattern |
Regex separado usado apenas para detecção pós-login (fallback para prompt_pattern se não definido) |
login_prompt |
String a aguardar durante a sequência de login |
password_prompt |
String a aguardar quando o dispositivo pede a senha |
pagination_pattern |
Regex para prompts de paginação (ex: --More--) |
line_ending |
\n para Cisco/Linux; \r\n para MikroTik/Windows |
use_steps |
Ativa execução por etapas (modo avançado) |
output_cleanup_patterns |
Padrões regex (um por linha) para remover da saída final |
connection_timeout |
Segundos para aguardar a conexão SSH/Telnet |
command_timeout |
Segundos para aguardar a resposta de cada comando |
transport_options |
Objeto JSONB com comportamento de sincronização Telnet (ver abaixo) |
Configuração JSON por template para dispositivos que exigem sincronização do terminal após login:
{
"telnet_sync": {
"enabled": true,
"idle_ms": 400,
"settle_ms": 500,
"after_login": true,
"enter_count": 2,
"before_commands": []
}
}Útil para dispositivos (ex: TP-Link) que emitem logs de auditoria assíncronos imediatamente após o login sem nova linha.
| Tipo | Comportamento |
|---|---|
command |
Envia um comando e aguarda o prompt (ou um expect_pattern customizado) |
expect |
Aguarda um padrão sem enviar nada |
pause |
Dorme por N segundos |
set_prompt |
Altera o padrão de prompt durante a sessão |
send_key |
Envia uma tecla especial: enter, space, tab, escape, ctrl+c, ctrl+z |
conditional |
Executa a etapa apenas se uma variável capturada corresponder a uma condição |
As etapas suportam on_failure (stop / continue / retry), max_retries, capture_output e variable_name para armazenar a saída em variáveis usadas por etapas condicionais posteriores.
Templates podem ser exportados e importados como arquivos JSON — útil para compartilhar entre ambientes ou equipes.
Os agendamentos executam backups automaticamente em um conjunto de dispositivos ou categorias inteiras.
- Frequências: horária, diária, semanal, mensal ou expressão cron customizada
- Alvos: dispositivos individuais, todos os dispositivos de uma ou mais categorias, ou ambos
- Em caso de falha: notificação por email enviada se o SMTP estiver configurado
- Histórico: toda execução é registrada na tabela de execuções de backup (sucesso, falha, config alterada ou inalterada)
Ative ou desative um agendamento a qualquer momento sem excluí-lo.
A tela de busca realiza full-text search em todos os snapshots de configuração armazenados.
| Modo | Como funciona |
|---|---|
| Padrão | PostgreSQL plainto_tsquery com índice GIN — resultados rápidos e ranqueados |
| Token parcial | Fallback automático para ILIKE em IPs parciais (ex: 192.168) e prefixos CIDR |
| Regex | Operador ~* do PostgreSQL (case-insensitive); ative com o botão Regex |
| Filtro | Descrição |
|---|---|
| Dispositivo | Restringir a um ou mais dispositivos específicos |
| Categoria | Restringir a todos os dispositivos de uma categoria |
| Período | Últimos 7, 30, 90 dias ou um ano |
| Versão atual | Buscar apenas na versão mais recente por dispositivo (mais rápido, menos ruído) |
Os resultados exibem as linhas correspondentes com destaque de sintaxe e links para a página do dispositivo e o histórico completo de versões.
Dica: O campo de busca aceita expressões regulares quando o botão Regex está ativo. Exemplo:
interface GigabitEthernet\d+
Todos os scripts ficam em scripts/ e são executados a partir da raiz do projeto.
| Comando | Descrição |
|---|---|
./scripts/reload.sh [all|frontend|backend] |
Rebuild e reload no modo container Docker |
./scripts/start.sh [all|db|backend|frontend] |
Inicia os serviços em modo dev local |
./scripts/stop.sh [all|db|backend|frontend] |
Para os serviços em modo dev local |
./scripts/status.sh |
Exibe o status dos serviços e as URLs |
Documentação interativa da API:
- Swagger UI:
http://localhost:8000/api/docs - ReDoc:
http://localhost:8000/api/redoc
Todos os endpoints protegidos exigem Authorization: Bearer <access_token>.
O diretório templates/ contém templates de backup prontos para uso, importáveis diretamente na página Templates de Backup.
| Arquivo | Dispositivo |
|---|---|
template-cisco.yaml |
Cisco |
template-mikrotik-rb750.yaml |
MikroTik RB750 |
template-huawei-ne8k.yaml |
Huawei NE8K |
template-huawei-sw-6730.yaml |
Huawei SW-6730 |
template-olt-huawei.yaml |
OLT Huawei |
template-olts-zte.yaml |
OLT ZTE |
template-olts-zte-titan.yaml |
OLT ZTE Titan |
template-hillstone.yaml |
Hillstone |
template-a10-th1040.yaml |
A10 TH1040 |
template-sw-datacom.yaml |
Switch Datacom |
template-sw-tp-link.yaml |
Switch TP-Link |
Para importar: acesse Templates de Backup → Importar e selecione o arquivo desejado.
- Credenciais são criptografadas com AES-256-GCM antes do armazenamento. A
ENCRYPTION_KEYdeve ser mantida em segredo e ter backup — perdê-la significa perder o acesso a todas as credenciais armazenadas. - Segredo JWT (
JWT_SECRET_KEY) deve ter pelo menos 32 caracteres e ser alterado do valor de exemplo antes de qualquer deploy em produção. - Senha padrão do admin (
Admin@123) deve ser alterada imediatamente após o primeiro login. - Senha de bind LDAP também é armazenada criptografada com a mesma chave.
- Papéis são armazenados apenas na tabela
user_roles— nunca em tokens JWT ou no armazenamento do navegador. - Todas as queries SQL usam statements parametrizados; entradas do usuário nunca são interpoladas em SQL cru.
- CORS é restrito às origens definidas em
CORS_ORIGINS_STR.
Reportes de bugs e solicitações de features são bem-vindos via Issues.