Três achados reportados pelo usuário numa mensagem só: (1) Rotas de Entrada não tinha edição depois de criada — implementada no mesmo padrão de Filas; (2) telas de Platform > Infraestrutura sempre davam "Timeout no ESL" nesta VM — não era limitação permanente como o comentário antigo dizia, e sim ESL_HOST=freeswitch (nome DNS que só existe dentro da rede do Docker) mais um segundo bug independente (`show gateways as json` não é comando válido nesta versão do FreeSWITCH); (3) ramal externo registrava mas sem áudio — diagnosticado com contadores de pacote do iptables: a VM está atrás de um roteador sem port-forward pra faixa de RTP, achado de infraestrutura de rede, não bug de código. Também integra o softphone WebRTC (handphone.js/OpenSIPS, já em produção): código-fonte encontrado em git.falehandix.com.br/Handix/handphone-2.0, patch mínimo pra aceitar o endereço do proxy em runtime (era build-time), nova config global (Platform > Infraestrutura > Softphone WebRTC) e widget na topbar do tenant que pega usuário/domínio/senha do ramal vinculado ao agente logado. Adiciona docs/QA_SETUP.md — runbook completo pra subir o ambiente do zero numa máquina nova (Docker, migrations, seed, systemd), e completa o .env.example que estava faltando a maioria das variáveis reais. Testado ponta a ponta com Playwright: edição de rota (criar/editar/F5), as 3 telas de Infraestrutura com dado real, e um tenant/ramal/agente de teste criados na hora confirmando que o script do softphone recebe as credenciais certas. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
65 lines
3.4 KiB
Markdown
65 lines
3.4 KiB
Markdown
# Arquitetura de Rede
|
|
|
|
## Estado atual (fase FreeSWITCH inicial)
|
|
|
|
`freeswitch` roda na rede padrão do Docker Compose (bridge, `b2bcall_default`),
|
|
igual a `postgres` e `redis`. Nenhuma porta é publicada no host — nem 8021
|
|
(ESL), nem SIP (5060/5080), nem RTP. Isso é intencional: ainda não existe
|
|
nenhum tronco SIP real nem ramal externo, então não há motivo pra expor nada.
|
|
|
|
`apps/api` roda hoje **direto no host** (fora do Docker), então usa
|
|
`APP_DATABASE_URL`/`REDIS_URL` apontando pra `localhost` nas portas publicadas
|
|
pelo Postgres/Redis. Ela não consegue (nem precisa, ainda) alcançar o
|
|
FreeSWITCH.
|
|
|
|
## Decisão pendente: `network_mode` do FreeSWITCH (agente.md secao 19)
|
|
|
|
Quando existir um tronco SIP real (fase Trunks), será preciso decidir entre:
|
|
|
|
- **`network_mode: host`**: mais simples pra SIP/RTP (sem NAT entre o
|
|
container e a rede), mas perde isolamento de rede do Docker.
|
|
- **macvlan/ipvlan**: dá ao FreeSWITCH um IP próprio na rede física, sem expor
|
|
outros serviços do host: mais trabalho de configurar, melhor isolamento.
|
|
|
|
Não decidido ainda — só vira relevante quando houver um carrier/SBC real pra
|
|
conectar (secao 17: "FreeSWITCH não deverá depender de IP SIP público" — a
|
|
topologia esperada é `Internet → OpenSIPS → rede SIP privada → FreeSWITCH`,
|
|
então o FreeSWITCH em si tende a ficar em rede privada mesmo, o que favorece
|
|
manter bridge/macvlan em vez de host).
|
|
|
|
## Achado real (PHASE 65): VM atrás de roteador, ramal externo sem áudio
|
|
|
|
Esta VM de laboratório está atrás de um roteador (NAT) — o IP da interface de
|
|
rede (`ens18`) é privado (`10.10.32.x`), o roteador é quem faz NAT pro IP
|
|
público real. Reportado pelo usuário: um softphone externo registrava com
|
|
sucesso, mas sem áudio.
|
|
|
|
Diagnóstico (contadores de pacotes do `iptables`, não suposição): 10 pacotes
|
|
chegaram em `5060/udp` (SIP), **zero** pacotes chegaram em qualquer porta da
|
|
faixa de RTP (`16384-16584/udp`). O REGISTER funciona porque a resposta
|
|
trafega de volta pelo mesmo "buraco" NAT que o próprio pacote do cliente abriu
|
|
— mas RTP usa portas completamente diferentes, como um fluxo NOVO. Sem uma
|
|
regra de **port forward no roteador** pra essa faixa (apontando pro IP
|
|
privado desta VM), esses pacotes nunca chegam até o Docker/FreeSWITCH.
|
|
|
|
Do lado desta VM estava tudo certo: `docker-compose.yml` publica a faixa de
|
|
RTP pra rede (não só loopback), `Ext-RTP-IP`/`Ext-SIP-IP` resolvem certo via
|
|
STUN (`sofia status profile internal` mostra o IP público real), e a
|
|
detecção de NAT do próprio FreeSWITCH (`apply-nat-acl value="nat.auto"`,
|
|
`nat.auto` é uma ACL auto-gerada pelo core do FreeSWITCH — RFC1918 exceto a
|
|
própria rede local do container, não precisa existir em `acl.conf.xml`)
|
|
funciona corretamente (testado direto via `fs_cli -x "acl <ip> nat.auto"`).
|
|
|
|
**Não tem fix de código pra isso** — é infraestrutura de rede fora do
|
|
controle desta aplicação. Checklist pra quem for expor telefonia real atrás
|
|
de um roteador: encaminhar UDP `5060` e toda a faixa RTP (`16384-16584`,
|
|
Dockerfile do FreeSWITCH) pro IP privado da VM, sem tradução de porta.
|
|
|
|
## Quando `apps/api` virar container
|
|
|
|
Hoje ela roda no host por conveniência de desenvolvimento. Quando virar o
|
|
serviço Docker `b2bcall-api` (agente.md secao 14), as connection strings
|
|
precisam trocar de `localhost` pros hostnames internos do compose
|
|
(`postgres`, `redis`, `freeswitch`) — ver nota em docs/AUTHENTICATION.md sobre
|
|
essa pegadinha.
|