Estou tentando usar nf_conntrack_sip em caixa que está rodando Asterisk, ou seja, não roteando tráfego para outra caixa VoIP. A instalação funciona até eu reiniciar. Após a reinicialização, o nf_conntrack_sip QUASE sempre para de funcionar e o tráfego de mídia é descartado.
conntrack --dump | grep -E 'sip|helper'
# No output matching 'sip' nor 'helper' while a call is in progress (albeit no audio)
As regras do iptables são carregadas corretamente confirmadas por iptables-save
.
Então eu faço systemctl restart iptables
e 9/10 vezes isso corrige. Se isso não acontecer, eu reinicio, repita o reinício do iptables.
conntrack --dump | grep -E 'sip|helper'
conntrack v1.4.4 (conntrack-tools): 9 flow entries have been shown.
udp 17 3597 src=10.7.0.38 dst=10.47.1.11 sport=5063 dport=5060 src=10.47.1.11 dst=10.7.0.38 sport=5060 dport=5063 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 helper=sip use=2
Simplesmente recarregar as regras com iptables-restore < /etc/sysconfig/iptables
não ajuda. Eu suspeito que descarregar/carregar conntrack ou alguns módulos fazem o truque.
Ocasionalmente, funciona na inicialização, mas muito raro. Asterisk iniciar rapidamente. Dar-lhe mais tempo para "terminar de começar algo" não ajuda.
Atualização: reiniciar o iptables enquanto nf_conntrack_sip está funcionando como esperado, pode, raramente, quebrá-lo.
A configuração:
Atualização: Inicialmente, o problema foi descrito como ocorrendo em uma VM, mas desde então reinstalei em hardware real (CPU i5-6500 @ 3,20 GHz com 8 Gb de RAM) com exatamente o mesmo problema ainda ocorrendo. Todos os pacotes idênticos (mesmo script de provisionamento) da VM inicial.
O sistema operacional é CentOS-7.4 Minimal + atualizações, kernel 3.10.0-693.21.1.el7.x86_64. É tudo instalado a partir de RPMs, sem kernels ou módulos personalizados. Atualização: também fiz yum update
os pacotes estáveis e o kernel mais recentes disponíveis no CentOS em 2018-08-10. O problema persiste.
eu fiz yum autoremove firewalld
e yum install iptables-services
.
Difere de /etc/sysconfig/iptables-config
(outros valores são padrões por RPM)
-IPTABLES_MODULES=""
+IPTABLES_MODULES="nf_conntrack_sip"
Arquivo adicionado /etc/modprobe.d/nf_conntrack.conf
:
options nf_conntrack nf_conntrack_helper=0
O todo /etc/sysconfig/iptables
é muito simples:
*raw
-A PREROUTING -p udp --dport 5060 -j CT --helper sip
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 5060 -j ACCEPT
-A INPUT -j LOG --log-level 7 --log-prefix "REJECT in filter.INPUT:"
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Atualização: Definir as opções do módulo options nf_conntrack nf_conntrack_helper=1
e NÃO usar a regra iptables ... -j CT --helper sip
NÃO corrige isso e o comportamento permanece não determinístico.
Não é relevante para o problema, apenas para confirmar que os pacotes foram descartados, em vez de ter problemas de NAT,/etc/rsyslog.d/kern-debug.conf
kern.=debug /var/log/kernel-debug
Testando com um telefone Cisco SPA504G que disca para o PBX e recebe música em espera. Não tentando fazer nada complicado com a mídia. A sinalização SIP e a mídia são trocadas com o mesmo endereço IPv4. A chamada de teste é apenas entre o telefone e o PBX. Nenhuma outra parte envolvida.
Minha tentativa de diagnosticá-lo:
Eu fiz um pequeno script que tenta capturar o estado de várias coisas antes e depois da correção reiniciando o iptables, para comparar por diff
. O roteiro:
for f in $( find /proc/sys/net/netfilter -type f ); do
echo f=${f}
cat "${f}"
done
echo cat /sys/module/nf_conntrack/parameters/*
cat /sys/module/nf_conntrack/parameters/*
echo ls /sys/module/nf_conntrack/holders/
ls /sys/module/nf_conntrack/holders/
echo cat /sys/module/nf_conntrack_sip/parameters/*
cat /sys/module/nf_conntrack_sip/parameters/*
echo ls /sys/module/nf_conntrack_sip/holders/
ls /sys/module/nf_conntrack_sip/holders/
echo ls /sys/module/ip*/holders/
ls /sys/module/{ip,nf_}*/holders/
echo sysctl -a
sysctl -a
echo lsmod
lsmod
echo iptables-save
iptables-save
A única coisa que noto é que o módulo FREQUENTEMENTE nf_conntrack_netlink
ESTÁ listado como carregado após a inicialização, enquanto há um problema. Às vezes, NÃO é listado lsmod
APÓS a inicialização, mas ainda há o problema. Depois de reiniciar o iptables, até onde sei, nunca é listado como carregado. Suspeito que não esteja relacionado porque não há ligação direta entre ele ser carregado e o problema se manifestar.
Solução
A solução foi simplesmente marcar os pacotes de saída a serem tratados pelo conntrack sip helper também:
Causa
O problema era que a regra do firewall estava marcando apenas os pacotes de entrada para o conntrack sip helper.
Quando o PBX fosse o único a enviar o primeiro pacote para o telefone, ele estabeleceria uma entrada conntrack sem o auxiliar de sip. A entrada continuou a corresponder à conversa SIP sem o envolvimento do auxiliar SIP.
Quando o telefone fosse o único a enviar o primeiro pacote para o PBX, ele atingiria a regra com "-j CT --helper sip" listada acima e a entrada conntrack seria criada com o sip helper.
Observe o "helper=sip" no final da entrada, compare com a falta dele na primeira amostra.
O PBX e o telefone enviam pacotes SIP um para o outro para confirmar que o outro está lá, então o tempo fez com que parecesse não determinístico.
O Asterisk preserva o estado dos peers nas reinicializações e os investiga após a reinicialização, sendo muito mais provável que envie o pacote de saída primeiro e causando a entrada não-SIP-helper no conntrack.
Muito obrigado ao usuário AB por me apontar na direção certa nos comentários.
Mistério restante
O que eu não consigo explicar é porque quando eu tinha a opção modprobe
Ele ainda estava sendo quebrado e "consertado" da mesma maneira. Eu não gastei muito tempo no helper acionando automaticamente, então talvez eu tenha feito algo errado. Posso atualizar esta resposta se descobrir mais. Não estou planejando usar o ajudante automático habilitado.