Eu tenho um contêiner Docker baseado no Ubuntu 16.04 que executa o serviço ntpd 4.2.8. Após a instanciação do contêiner, publiquei a porta 123/udp.
No host ou outro computador na LAN, posso usar ntpq -p <container_host>
para obter a lista de pares e o status de sincronização. Mas monitorá-lo usando collectd ou executando ntpdc -c kerninfo <container_host>
falhas/tempo limite. E isso está me intrigando!
Eu testei dentro do contêiner com algumas restrict
declarações razoáveis e também sem nenhuma. Mas em ambos os casos eu limitei o tempo limite. A execução do tcpdump no contêiner (após elevá-lo para contêiner privilegiado) mostra que o pacote UDP chega, mas nada é respondido. Claro, usando o tcpdump vejo solicitação e resposta ao usar o ntpq que está funcionando.
Se eu executar o servidor ntpd diretamente no host, usando o mesmo arquivo ntp.conf, o ntpdc -c kerninfo <container_host>
e o collectd serão bem-sucedidos no host e em outros computadores na LAN que eu autorizei! No entanto, o host ainda está executando uma versão mais antiga do Ubuntu (14.04) que vem com o NTP 4.2.6.
Portanto, as únicas diferenças são a rede Docker (NAT, pelo que entendi) e a versão NTP (4.2.6 vs 4.2.8). Mas a documentação do ntp.org não menciona nada sobre NAT nem sobre atualizações 4.2.8. Então, o tempo limite do meu comando está expirando apenas porque o cliente está em uma sub-rede diferente da do servidor (devido ao NAT)? Ou como algo mudou no 4.2.8?
Nota: minha imagem de contêiner é baseada em ubuntu:16.04 que executa ntpd[e-mail protegido](dos repositórios oficiais do Ubuntu). O host executa o Ubuntu 14.04 que executa 4.2.6p5.
PS: Collectd envia um comando equivalente ao ntpdc -c kerninfo <container_host>
e timeout quando o ntpd é executado no contêiner, mesmo que todas as instruções de restrição estejam corretas.
Atualizar: esqueci de mencionar que também executei o ntpd dentro do contêiner com a -ddd
opção de obter uma saída mais detalhada. Os únicos dados relevantes que foram registrados são:
read_network_packet: fd=19 length 192 from 192.168.1.3
receive: at 26 172.17.0.2<-192.168.1.3 flags 19 restrict 000
Atualização2: Depois de descobrir a solução, mudei a pergunta na esperança de que outras pessoas que se deparam com o mesmo problema possam encontrar melhor a pergunta/resposta ao procurá-la. Também corrigi um erro, pensei que o host estava rodando o Ubuntu 16.04, mas na verdade ainda estava rodando o 14.04.
Responder1
Eu resolvi meu problema. O erro ocorre porque o NTP 4.2.8 descontinua (e desativa por padrão) a ferramenta ntpdc
e o modo de comunicação que ela estava usando (também conhecido como mode7).
A partir do ntp 4.2.8 e versões mais recentes, a ferramenta ntpq
deve ser usada no lugar do ntpdc. Agora ele suporta os mesmos comandos do ntpdc. Para que eu possa executar ntpq -c kerninfo <container_host>
com sucesso. O ntpq
comando usa um modo diferente (também conhecido como mode6) para a comunicação.
Com o ntp 4.2.8, ainda é possível reativar o mode7 para suportar a compatibilidade com ferramentas que ainda não foram migradas. Deve-se adicionar a seguinte linha no arquivo /etc/ntp.conf
:
enable mode7
Porém, deve-se ter muito cuidado com a restrição. Parece que ativar o modo7 e deixar o servidor ntpd muito aberto poderia ser usado para conduzir ataques de amplificação DDoS. Atualmente estou usando a restrição padrão para IPv4 e IPv6 no Ubuntu, que -Eu penso- bloqueia o uso deste modo:
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
Como o collectd suporta apenas o mode7 (vejaedição #932), decidi reativar esse modo na minha configuração dentro do contêiner. Contanto que o ntp suporte a reativação deste modo, esta mudança deve corrigir o problema de que o collectd não pode monitorar o ntpd no Ubuntu 16.04 (ou qualquer distro usando o ntp 4.2.8+).
Nota: para que as pessoas encontrem melhor uma solução caso encontrem esse problema, vou editar a pergunta para ser menos enganosa em relação ao NAT, que inicialmente considerei ser a causa raiz.