feat(freeswitch): publica SIP/RTP no host pra registro de ramal de verdade

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
2026-08-30 15:37:49 -03:00
parent af46739af2
commit 2cd638d26f
3 changed files with 50 additions and 2 deletions

27
TODO.md
View File

@@ -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

View File

@@ -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

View File

@@ -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#<!-- <param name="rtp-start-port" value="16384"/> -->#<param name="rtp-start-port" value="16384"/>#' \
-e 's#<!-- <param name="rtp-end-port" value="32768"/> -->#<param name="rtp-end-port" value="16584"/>#' \
/etc/freeswitch/autoload_configs/switch.conf.xml \
&& grep -q '<param name="rtp-start-port" value="16384"/>' /etc/freeswitch/autoload_configs/switch.conf.xml \
&& grep -q '<param name="rtp-end-port" value="16584"/>' /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"]