Guia de Segurança do SIP VAULT
Este guia cobre a arquitetura de segurança, mecanismos de autenticação, segurança de rede, proteção de dados e isolamento de tenants no SIP VAULT.
Sumário
- Visão Geral da Arquitetura de Segurança
- Autenticação: Tokens Assinados com HMAC-SHA256
- Geração de Tokens no CDR Viewer
- Gerenciamento de Credenciais S3/R2
- Segurança de Rede
- Recomendações de Firewall
- Isolamento de Clientes
- Verificação de Call-ID Baseada em Hash
- Proteção de Dados em Repouso
- Política de Retenção como Controle de Segurança
- Análise da Superfície de Ataque
- Segurança do Agente
Visão Geral da Arquitetura de Segurança
O SIP VAULT segue um design de segurança com superfície mínima:
- Sem contas de usuário ou senhas -- a autenticação é exclusivamente através de tokens assinados com HMAC-SHA256 gerados pelo CDR Viewer
- Sem banco de dados -- elimina SQL injection, vulnerabilidades de ORM e gerenciamento de credenciais de banco de dados
- Buckets S3 por cliente -- isolamento de dados de tenant na camada de armazenamento
- Tokens de curta duração -- expiração padrão de 1 hora, configurável via
SIPVAULT_HMAC_MAX_AGE - Segredos pré-compartilhados -- autenticação agente-para-servidor usa tokens por cliente configurados em ambos os lados
O modelo de confiança:
CDR Viewer (trusted) --> generates HMAC token --> user's browser
User's browser --> presents token --> SIP VAULT API --> validates HMAC --> serves data
Agent (trusted) --> authenticates with token --> SIP VAULT server --> writes to S3
Autenticação: Tokens Assinados com HMAC-SHA256
Todo acesso ao dashboard é autenticado via tokens assinados com HMAC-SHA256. Não há formulário de login, não há gerenciamento de sessão e não há banco de dados de usuários.
Formato do Token
O token é uma string separada por dois pontos com cinco componentes:
| Componente | Descrição | Exemplo |
|---|---|---|
customer_id |
Identificador do cliente | acme |
call_id |
Valor do cabeçalho SIP Call-ID | a7a186b1ff8c4cfeaa90a9144ba9cb24 |
call_date |
Data da chamada no formato YYYY/MM/DD |
2026/03/14 |
timestamp |
Timestamp Unix de quando o token foi criado | 1710403200 |
signature |
Digest hexadecimal HMAC-SHA256 do payload | e3b0c44298fc1c14... |
Computação da Assinatura
A assinatura é computada sobre o payload (os quatro primeiros componentes unidos por dois pontos):
payload = "{customer_id}:{call_id}:{call_date}:{timestamp}"
signature = HMAC-SHA256(secret, payload)
O segredo é o valor SIPVAULT_HMAC_SECRET configurado em api.env.
Validação do Token
A API valida tokens em cada requisição via a dependência require_token:
- Verificação de formato: O token deve conter exatamente 5 partes separadas por dois pontos
- Verificação de assinatura: Recomputa o HMAC e compara usando comparação em tempo constante (
hmac.compare_digest) para prevenir ataques de timing - Verificação de expiração:
hora_atual - timestampdeve ser menor queSIPVAULT_HMAC_MAX_AGE(padrão: 3600 segundos) - Isolamento de cliente: O
customer_iddo token determina qual bucket S3 será consultado
Se qualquer verificação falhar, a API retorna HTTP 401 com um erro específico:
- invalid token format -- número incorreto de componentes
- invalid timestamp -- timestamp não é um inteiro válido
- invalid signature -- HMAC não corresponde
- token expired -- idade do token excede a idade máxima
Configuração de Expiração do Token
O tempo de vida padrão do token é 1 hora (3600 segundos). Para alterá-lo:
Por segurança, mantenha a expiração o mais curta possível na prática. O token é incorporado na URL do dashboard, então ele permanece válido durante a sessão de navegação do usuário, desde que não tenha expirado.
Geração de Tokens no CDR Viewer
Tokens são gerados no lado do servidor pela aplicação CDR Viewer (tipicamente OpenSIPS Control Panel). O segredo HMAC nunca chega ao navegador do usuário final -- apenas o token assinado chega.
Fluxo de Geração de Tokens
1. Usuário clica em "SIP VAULT" no CDR Viewer
2. Código server-side do CDR Viewer:
a. Obtém call_id e call_date do registro CDR
b. Computa call_hash = SHA-256(call_id)[:16]
c. Constrói payload = "{customer_id}:{call_id}:{call_date}:{now}"
d. Assina: signature = HMAC-SHA256(secret, payload)
e. Constrói token = "{payload}:{signature}"
f. Retorna URL: https://sipvault.example.com/call/{call_hash}?token={token}
3. Navegador do usuário abre a URL
4. SPA do Dashboard extrai o token da query string
5. Todas as requisições de API incluem o token como parâmetro de query
6. API valida o token em cada requisição
Requisitos de Segurança para Geradores de Token
- O segredo HMAC deve ser armazenado com segurança no servidor do CDR Viewer, não no código client-side
- A geração de tokens deve acontecer apenas no lado do servidor
- O segredo no gerador deve corresponder ao
SIPVAULT_HMAC_SECRETem/etc/sipvault/api.envexatamente
Gerenciamento de Credenciais S3/R2
O SIP VAULT usa dois conjuntos separados de credenciais S3 com diferentes níveis de privilégio.
Separação de Credenciais
| Conjunto de Credenciais | Usado Por | Permissões | Configurado Em |
|---|---|---|---|
| Credenciais do servidor | sipvault-server | Object Read & Write | /etc/sipvault/server.env (SIPVAULT_S3_ACCESS_KEY, SIPVAULT_S3_SECRET_KEY) |
| Credenciais da API | FastAPI | Object Read apenas | /etc/sipvault/api.env (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) |
Princípio do Menor Privilégio
- O servidor precisa de acesso de leitura/escrita para armazenar dados de chamadas
- A API precisa apenas de acesso de leitura para gerar URLs pré-assinadas para o dashboard
- Nenhum dos conjuntos de credenciais deve ter permissões de exclusão ou gerenciamento de buckets
Criando Tokens de API do R2
No painel do Cloudflare:
- Navegue até R2 > Manage R2 API Tokens
- Para o token do servidor:
- Permissões: Object Read & Write
- Escopo: Apenas buckets específicos do cliente
- Para o token da API:
- Permissões: Object Read
- Escopo: Todos os buckets de clientes (para acesso multi-tenant)
Buckets por Cliente
Os dados de cada cliente são armazenados em um bucket R2 separado:
Isso fornece isolamento de tenant no nível de armazenamento. Mesmo se um token for comprometido, ele só concede acesso ao bucket daquele cliente.
Permissões de Arquivo
Arquivos de ambiente contendo credenciais são protegidos no nível do sistema de arquivos:
Apenas root pode gravá-los; apenas o grupo sipvault pode lê-los. O usuário de sistema sipvault (que executa os serviços) é membro deste grupo.
Segurança de Rede
Mapa de Portas
| Porta | Protocolo | Direção | Finalidade | Acesso |
|---|---|---|---|---|
| 443 | TCP | Entrada | HTTPS (dashboard + API) | Público |
| 80 | TCP | Entrada | HTTP (redireciona para HTTPS) | Público |
| 9060 | TCP | Entrada | Dados agente-para-servidor | Restrito a IPs de clientes |
| 9060 | UDP | Entrada | Dados RTCP HEP v3 | Restrito a IPs de clientes |
| 8000 | TCP | Somente loopback | FastAPI (encaminhado pelo nginx) | Apenas localhost |
TLS para Dashboard e API
Todo tráfego voltado ao usuário é criptografado com TLS 1.2+: - Certificados são gerenciados pelo Let's Encrypt via certbot - O nginx faz a terminação TLS - HTTP é redirecionado para HTTPS com resposta 301
Conexões Agente-para-Servidor
Os agentes se conectam ao servidor na porta TCP 9060. A conexão:
- Usa um protocolo binário personalizado sobre TCP
- Autentica usando o token por cliente configurado no agent.conf do agente e no SIPVAULT_CUSTOMERS do servidor
- Deve ser restrita a faixas de IP conhecidas dos clientes no nível do firewall
HEP v3 RTCP
Quando o RTPProxy roda em uma máquina separada, dados RTCP são enviados via HEP v3 sobre porta UDP 9060: - Origem: servidor de mídia/RTPProxy - Destino: servidor SIP VAULT - Deve ser restrito a IPs conhecidos dos servidores de mídia no nível do firewall
Comunicação de Serviço Interna
O serviço FastAPI escuta apenas em 127.0.0.1:8000:
- Não é acessível pela rede
- Encaminhado pelo nginx em /api/
- O nginx adiciona cabeçalhos X-Real-IP, X-Forwarded-For e X-Forwarded-Proto
Recomendações de Firewall
Firewall do Servidor (ufw)
# Allow HTTPS (public)
sudo ufw allow 443/tcp comment "HTTPS"
# Allow HTTP redirect (public)
sudo ufw allow 80/tcp comment "HTTP redirect"
# Allow agent connections (restrict to customer IP ranges)
sudo ufw allow from 10.0.0.0/8 to any port 9060 proto tcp comment "SIP VAULT agent TCP"
# Allow HEP RTCP (restrict to media server IPs)
sudo ufw allow from 10.0.0.0/8 to any port 9060 proto udp comment "SIP VAULT HEP UDP"
# Allow SSH (restrict to admin IPs)
sudo ufw allow from ADMIN_IP to any port 22 proto tcp comment "SSH"
# Enable firewall
sudo ufw enable
Para implantações em produção, substitua 10.0.0.0/8 por endereços IP específicos dos clientes ou faixas CIDR.
Firewall do Cliente (Lado do Agente)
O agente precisa apenas de acesso de saída:
# Allow outbound TCP to SIP VAULT server
sudo ufw allow out to SERVER_IP port 9060 proto tcp comment "SIP VAULT agent"
Nenhuma porta de entrada precisa ser aberta para o agente.
Isolamento de Clientes
O SIP VAULT impõe isolamento de tenant em múltiplas camadas:
1. Isolamento de Armazenamento
Cada cliente possui um bucket S3/R2 dedicado:
sipvault-acme-us/ --> Dados apenas do cliente "acme"
sipvault-globex-eu/ --> Dados apenas do cliente "globex"
2. Controle de Acesso Baseado em Token
O token HMAC contém o customer_id, que determina qual bucket a API consulta:
Token: acme:call-id-123:2026/03/14:1710403200:signature
|
customer_id = "acme" --> bucket = "sipvault-acme-us"
Um token válido para o cliente "acme" não pode ser usado para acessar dados do cliente "globex".
3. Autenticação do Agente
O agente de cada cliente se autentica com um token único:
SIPVAULT_CUSTOMERS=[
{"id":"acme", "token":"token-for-acme", "bucket":"sipvault-acme-us"},
{"id":"globex", "token":"token-for-globex", "bucket":"sipvault-globex-eu"}
]
Um agente com credenciais do cliente "acme" só pode gravar no bucket "acme".
4. Isolamento por Hash de URL
As URLs do dashboard usam um hash SHA-256 do Call-ID. Mesmo se alguém adivinhar um hash de Call-ID, ainda precisa de um token HMAC válido com o customer_id e call_id corretos para acessar os dados.
Verificação de Call-ID Baseada em Hash
Call-IDs SIP podem conter informações sensíveis (endereços IP, timestamps, etc.) e são frequentemente longos e inadequados para URLs. O SIP VAULT usa hash SHA-256 para construção de URLs.
Como Funciona
- O CDR Viewer computa
call_hash = SHA-256(call_id)[:16](primeiros 16 caracteres hexadecimais) - A URL do dashboard usa este hash:
https://sipvault.example.com/call/{call_hash} - O
call_idcompleto é carregado dentro do token HMAC (não no caminho da URL) - A API extrai o
call_iddo token validado, computa seu hash e verifica se corresponde ao caminho da URL - O
call_idé então usado para construir o caminho S3 para recuperação de dados
Isso significa: - O Call-ID bruto nunca é exposto no histórico do navegador ou nos logs de acesso do servidor via o caminho da URL - O hash da URL sozinho não pode ser usado para acessar dados sem um token válido - Um atacante com o hash da URL mas sem token recebe HTTP 401 - Um atacante com um token mas o hash de URL errado recebe um erro de incompatibilidade
Proteção de Dados em Repouso
Compressão GZIP
Todos os dados armazenados são comprimidos com GZIP:
- sip.pcap.gz -- Capturas de pacotes SIP
- rtcp.json.gz -- Relatórios RTCP brutos
- log-NNNNNN.gz -- Chunks de log do OpenSIPS
O arquivo quality.json é armazenado sem compressão para acesso rápido pela API.
Criptografia S3/R2
O Cloudflare R2 criptografa todos os objetos em repouso por padrão usando AES-256. Nenhuma configuração adicional é necessária.
URLs Pré-Assinadas
A API nunca serve objetos S3 diretamente. Em vez disso, ela gera URLs pré-assinadas de curta duração que concedem acesso de leitura temporário a objetos específicos. Isso significa: - As credenciais S3 da API nunca são expostas ao cliente - URLs pré-assinadas expiram após um curto período - Cada URL é limitada a um único objeto S3
Política de Retenção como Controle de Segurança
A política de retenção de dados (/etc/sipvault/retention.yml) serve como controle de segurança ao limitar por quanto tempo dados sensíveis de chamadas persistem.
Períodos de Retenção Padrão
| Tipo de Dado | Padrão | Contém |
|---|---|---|
| SIP PCAP | 7 dias | Tráfego SIP no nível de pacote (pode incluir cabeçalhos de autenticação) |
| RTCP bruto | 7 dias | Medições de qualidade de rede, endereços IP |
| Quality JSON | 30 dias | Análise de qualidade agregada (menos sensível) |
| Chunks de log | 14 dias | Logs do OpenSIPS (podem conter SIP URIs, IPs) |
Justificativa de Segurança
- SIP PCAPs contêm os dados mais sensíveis (capturas completas de pacotes) e têm a retenção mais curta
- Quality JSON contém apenas estatísticas agregadas e pode ser mantido por mais tempo
- Chunks de log podem conter SIP URIs e endereços IP, justificando retenção moderada
- Substituições por cliente permitem conformidade com requisitos específicos de retenção de dados de cada cliente
Considerações de Conformidade
Para ambientes regulamentados, a política de retenção pode ser configurada por cliente:
customers:
regulated_customer:
sip_pcap_days: 3 # Minimize PII retention
rtcp_raw_days: 3
quality_json_days: 90 # Keep quality data for SLA reporting
log_chunks_days: 7
Análise da Superfície de Ataque
O que o SIP VAULT NÃO Possui
| Componente Ausente | Benefício de Segurança |
|---|---|
| Banco de dados | Sem SQL injection, sem vulnerabilidades de ORM, sem gerenciamento de credenciais de BD |
| Contas de usuário | Sem armazenamento de senhas, sem credential stuffing, sem tomada de conta |
| Gerenciamento de sessão | Sem sequestro de sessão, sem CSRF (tokens são baseados em URL) |
| Uploads de arquivo | Sem ataques baseados em upload |
| Painel de administração | Sem comprometimento de credenciais de admin |
Vetores de Ataque Remanescentes
| Vetor | Mitigação |
|---|---|
| Comprometimento do segredo HMAC | Manter segredo em /etc/sipvault/api.env (permissões 640). Rotacionar alterando o segredo tanto em api.env quanto na configuração do CDR Viewer |
| Comprometimento de credenciais S3 | Usar tokens com menor privilégio. Rotacionar via painel do Cloudflare |
| Replay de token (dentro da validade) | Manter SIPVAULT_HMAC_MAX_AGE curto (padrão: 1 hora) |
| Comprometimento do token do agente | Rotacionar o token tanto em SIPVAULT_CUSTOMERS quanto no agent.conf do agente |
| Interceptação de rede na porta 9060 | Restringir porta 9060 a IPs conhecidos dos clientes via firewall |
| Vulnerabilidades nginx/FastAPI | Manter pacotes atualizados, monitorar CVEs |
Segurança do Agente
Requisitos de Capability
O binário do agente requer privilégios elevados para captura de pacotes, mas NÃO precisa de acesso root completo:
Modo eBPF:
| Capability | Finalidade |
|---|---|
CAP_BPF |
Carregar e executar programas eBPF |
CAP_NET_ADMIN |
Anexar programas XDP/tc a interfaces de rede |
CAP_SYS_PTRACE |
Anexar kprobes para captura de logs |
Modo pcap:
| Capability | Finalidade |
|---|---|
CAP_NET_RAW |
Abrir sockets raw para captura de pacotes via libpcap |
Usuário de Sistema do Agente
O instalador não cria um usuário de sistema dedicado para o agente -- o serviço systemd roda como root (necessário para captura de pacotes). Em sistemas onde as capabilities são definidas no binário, o serviço pode ser configurado para rodar como um usuário com menos privilégios.
Segurança do Buffer de Disco
O agente armazena dados em buffer em /var/lib/sipvault/buffer.dat (padrão, configurável). Este arquivo pode conter pacotes SIP capturados e dados de log. Certifique-se de que:
- O diretório do buffer tem permissões restritivas:
chmod 750 /var/lib/sipvault - O arquivo de buffer é limpo quando o agente é desinstalado
- O tamanho máximo do buffer (padrão: 100 MB) previne esgotamento de disco
O que o Agente Captura
O agente captura APENAS: - Diálogos INVITE -- nenhum REGISTER, OPTIONS, SUBSCRIBE ou NOTIFY - Pacotes RTCP na faixa de portas RTP configurada - Logs do OpenSIPS relacionados aos Call-IDs capturados
Ele NÃO captura:
- Mídia RTP (dados de voz)
- Mensagens SIP fora de diálogos INVITE
- Tráfego em portas não configuradas em sip_ports ou rtp_port_min/rtp_port_max