From 2cd638d26f0cc7e286f0330db52aa0dfc11582ff Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 30 Aug 2026 15:37:49 -0300 Subject: [PATCH] feat(freeswitch): publica SIP/RTP no host pra registro de ramal de verdade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usuário tentou registrar um ramal e não conseguiu — nenhuma porta SIP/RTP estava publicada no host, só o Event Socket (interno). O teste ponta a ponta da fase anterior só funcionava porque os softphones de teste rodavam dentro da mesma rede Docker. RTP restrito a um range fixo de 200 portas (16384-16584, via sed em switch.conf.xml) — o default vanilla (~16k portas) é inviável de publicar uma a uma. docker-compose.yml publica 5060/udp+tcp (SIP) e 16384-16584/udp (RTP); Event Socket continua nunca publicado. Verificado: iptables -t nat -L DOCKER confirma DNAT correto pras 201 portas; sofia status confirma que o STUN já configurado (external_rtp_ip/ external_sip_ip) resolve pro IP público real da VM, então o SDP vai anunciar o IP certo — não só o registro, o áudio também deve funcionar. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8 --- TODO.md | 27 +++++++++++++++++++++++++++ docker-compose.yml | 10 ++++++++-- infrastructure/freeswitch/Dockerfile | 15 +++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index 4627acf..0aa2d93 100644 --- a/TODO.md +++ b/TODO.md @@ -1969,6 +1969,33 @@ resolvidos sem nunca registrar um SIP de verdade (Discagem interna corrigida + `*8`) foram mantidas — são configuração funcional de verdade, não lixo de teste +## PHASE 54 — Publicar SIP/RTP no host (usuário tentou registrar um ramal +de fora da rede Docker e não conseguiu) +- [x] achado real: nenhuma porta SIP/RTP do FreeSWITCH estava publicada no + host — só o Event Socket (8021), e mesmo esse só na rede interna do + compose. O teste ponta a ponta da PHASE 53 só funcionou porque os + softphones de teste rodavam DENTRO da mesma rede Docker + (`b2bcall_default`); um softphone de verdade fora do Docker não tem + como alcançar o FreeSWITCH +- [x] `infrastructure/freeswitch/Dockerfile`: RTP restrito a um range fixo + de 200 portas (16384-16584) via `sed` em `switch.conf.xml` — o + default vanilla (16384-32768, ~16k portas) é inviável de publicar + uma a uma no host +- [x] `docker-compose.yml`: publicado `5060/udp`+`5060/tcp` (SIP) e + `16384-16584/udp` (RTP) pro container. Event Socket continua NUNCA + publicado (só uso interno) +- [x] Confirmado via `iptables -t nat -L DOCKER`: as 201 portas RTP + a + porta SIP têm DNAT correto pro container; `ss -lunp` confirma + `docker-proxy` escutando 5060 no host. `sofia status profile + internal` confirma que o STUN (`external_rtp_ip`/`external_sip_ip` + em `vars.xml`, já configurado desde antes) resolve corretamente pro + IP público de verdade da VM (`191.240.175.55`) — SDP vai anunciar o + IP certo, não só o registro deve funcionar, o áudio também +- [ ] Não verificado (fora do alcance daqui): se a VM está atrás de um + firewall de provedor de nuvem (security group), as mesmas portas + precisam estar liberadas lá também — só o `iptables` local foi + confirmado + --- ## Riscos conhecidos diff --git a/docker-compose.yml b/docker-compose.yml index 8172523..074044f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -91,9 +91,15 @@ services: # host e precisa enxergar os mesmos arquivos que o FreeSWITCH grava # (agente.md secao 90-91) — ver docs/RECORDING.md. - ./data/recordings-spool:/recordings - # Nenhuma porta publicada no host: SIP/RTP ainda não têm troncos reais - # configurados, e o Event Socket (8021) só deve ser alcançável por outros + # Event Socket (8021) NUNCA publicado — só alcançável por outros # containers na rede interna do compose (agente.md secao 22). + # SIP (5060) e RTP (16384-16584, range fixo no Dockerfile) publicados + # a partir da PHASE 54 — necessário pra registrar um softphone/telefone + # de fora da rede Docker (achado testando registro de verdade). + ports: + - "5060:5060/udp" + - "5060:5060/tcp" + - "16384-16584:16384-16584/udp" healthcheck: test: ["CMD-SHELL", "fs_cli -p \"$$ESL_PASSWORD\" -x status | grep -q 'is ready'"] interval: 10s diff --git a/infrastructure/freeswitch/Dockerfile b/infrastructure/freeswitch/Dockerfile index 4ce43c5..5539cc0 100644 --- a/infrastructure/freeswitch/Dockerfile +++ b/infrastructure/freeswitch/Dockerfile @@ -78,10 +78,25 @@ RUN sed -i \ /etc/freeswitch/sip_profiles/internal.xml \ && ! grep -q "force-register-domain\|force-subscription-domain\|force-register-db-domain" /etc/freeswitch/sip_profiles/internal.xml +# RTP num range fixo e pequeno (PHASE 54, docs/EXTENSIONS.md) — o range +# vanilla default (16384-32768, ~16k portas) é inviável de publicar uma a +# uma no host; achado ao tentar registrar um softphone de fora da rede +# Docker pela primeira vez (nenhuma porta SIP/RTP estava publicada até +# aqui — só o Event Socket interno). Restrito a 200 portas, suficiente +# pra alguns testes/chamadas simultâneas em laboratório. +RUN sed -i \ + -e 's###' \ + -e 's###' \ + /etc/freeswitch/autoload_configs/switch.conf.xml \ + && grep -q '' /etc/freeswitch/autoload_configs/switch.conf.xml \ + && grep -q '' /etc/freeswitch/autoload_configs/switch.conf.xml + COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh EXPOSE 8021 +EXPOSE 5060/udp 5060/tcp +EXPOSE 16384-16584/udp ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["/usr/bin/freeswitch", "-nonat"]