NTS – Mantenha a hora certa em seu servidor com segurança!

Este tutorial foi escrito pelo meu amigo: Iulisloi Zacarias

Manter o relógio dos seus servidores corretamente ajustado pode evitar muita dor de cabeça. Alguns softwares simplesmente podem não funcionar com a hora incorreta, como exemplo cito aqui o DNSSEC e estrutura de chaves RPKI (nada muito grave, não é mesmo?!). Vale lembrar também que rastrear um problema ou conduzir uma auditoria fica muito mais fácil e assertivo se você manter os registros de data e hora nos logs com a informação correta.

O NTP é um protocolo que é utilizado para sincronizar a hora dos seus servidores e computador com uma fonte confiável de informação de hora, como por exemplo os servidores do projeto NTP.br. Há um tutorial muito completo sobre como manter seus servidores com a data correta aqui.

Mas você já parou para pensar sobre a segurança do NTP. As informações trafegam pela rede de forma aberta (isso não é um problema, já que saber a hora não é nenhum segredo) e sem mecanismos que permitam verificar se ela foi modificada, e isto sim pode ser um problema. Este tipo de ataque é chamado de ataque man-in-the-middle e consiste em um indivíduo mal-intencionado modificar a informação enquanto ela trafega pela rede. Além disso outro ataque bem comum é o “replay” de pacotes, ou seja, um atacante captura um pacote da comunicação original, e em seguida cria vários pacotes com as mesmas informações do pacote original, mas manipulando os campos que ele tem interesse e em seguida envia para as máquinas que ele deseja atacar. Pensando em resolver este problema de segurança, o NTS foi proposto (RFC 8915 https://datatracker.ietf.org/doc/rfc8915/).

Neste tutorial vamos utilizar o NTPsec, que é um “fork” da implementação de referência NTP e vêm ganhando popularidade no mundo Linux por ser umas das primeiras implementações NTP a ter suporte ao NTS.

É importante lembrar que o NTPsec têm a mesma função do pacote ntp no Debian e você não deve usar os dois ao mesmo tempo!

Lembrando que utilizei o Debian 10:

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

IMPORTANTE:
O uso do TLS 1.3 é obrigatório para o NTS e portanto este tutorial NÃO funcionará com Debian 9 ou Ubuntu 16.04.
Neste tutorial uso o repositório backports do Debian. As versões dos programas são testadas no Debian stable, no entanto não são testadas tão extensivamente como as versões dos repositórios padrão do Debian.

Se você for um usuário iniciante no Debian/Linux, não recomendo fazer esta configuração em um servidor em produção!!!!

Sem mais delongas, vamos lá…
Iniciando
Torne-se root no seu sistema utilizando o comando “su -”

$ su -

(OBS: utilize o comando “su menos”)
Vamos garantir que outros clientes NTP não estejam em execução:

# systemctl stop ntp
# systemctl stop chrony
# systemctl stop openntpd
# systemctl stop systemd-timesyncd.service
# systemctl disable ntp
# systemctl disable chrony
# systemctl disable openntpd
# systemctl disable systemd-timesyncd.service

Instalação do NTPsec e suas dependências

Como o NTS é bem recente, vamos precisar instalar o NTPsec 1.2.0. No momento em que estou escrevendo este tutorial a versão do NTPsec nos repositórios padrão do Debian 10 é a 1.1.3. Nós vamos habilitar o repositório backports (stable-bpo) para que seja possível instalar a versão 1.2.0 do NTPsec no nosso Debian 10. Será necessário instalar também o pacote “ca-certificates” para podermos validar os certificados que os servidores vão nos oferecer.

# echo "deb http://deb.debian.org/debian buster-backports main" | tee /etc/apt/sources.list.d/buster-backports.list
# apt update
# apt install -y ntpsec/buster-backports ca-certificates

Vamos ajustar as configurações do NTPsec para utilizar os servidores da Netnod (uma empresa que mantém servidores de hora para o governo da Suécia) e da Cloudflare. Por enquanto não temos servidores oficiais de hora no Brasil com suporte ao NTS (hey NTP.br, vamos?!). Você pode incluir outros servidores NTS quando eles forem disponibilizados. Seguindo a metodologia do Remontti, vamos criar um arquivo para a nossa configuração e manter cópia do arquivo de configuração original:

# mv /etc/ntpsec/ntp.conf /etc/ntpsec/ntp.conf.orig
# vim /etc/ntpsec/ntp.conf

Conteúdo do arquivo:

# /etc/ntpsec/ntp.conf, configuração para o ntpd; veja ntp.conf(5) para ajuda
# Configuraçao do drift file para o NTPsec computar os erros do relógio do seu computador
driftfile /var/lib/ntpsec/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list

# Configuracao do diretório de log
statsdir /var/log/ntpsec/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# Lista dos servidores com suporte NTS, você pode adicionar mais servidores à lista
server nts.netnod.se:4460 nts iburst
server sth1.nts.netnod.se:4460 nts iburst
server sth2.nts.netnod.se:4460 nts iburst
server time.cloudflare.com:4460 nts

# Permite trocar informações de hora com qualquer computador mas não permite configuração
# Segundo o guia do netnod essa configuração atende 99% dos casos ;-)
restrict default kod limited nomodify nopeer noquery
restrict -6 default kod limited nomodify nopeer noquery

# Permite consultas locais
restrict 127.0.0.1
restrict -6 ::1

Crie o arquivo ntp.drift e o diretório para os logs e reinicie o serviço

# touch /var/lib/ntpsec/ntp.drift
# chown ntpsec:ntpsec /var/lib/ntpsec/ntp.drift
# mkdir /var/log/ntpsec
# chown -R ntpsec:ntpsec /var/log/ntpsec
# systemctl restart ntpsec

Vamos verificar com quais servidores estamos tentando sincronizar:

# ntpq -p -u -w

Irá listar algo como

     remote                                   refid      st t when poll reach   delay   offset   jitter
=======================================================================================================
+sth-ts.nts.netnod.se                    96.180.207.109   2 8   22   64   77 310.16ms 7.2680ms 10.631ms
*ntsts.sth1.ntp.se                       96.180.207.109   2 8   18   64   77 307.50ms 6.5467ms 13.046ms
+sth2-ts.nts.netnod.se                   156.133.237.214  2 8   22   64   77 305.86ms 4.2228ms 9.6702ms
-162.159.200.1                           10.191.8.4       3 8   23   64   77 61.953ms -31.52ms 19.442ms

Verifique a coluna “st”. Esta coluna indica o stratum (ou estrato) e o valor 16 indica que o servidor está inoperante. No meu exemplo todos os servidores estão em operação pois os valores são 2, 2, 2, e 3. Veja também que há uma linha que inicia com um asterisco (*ntsts.sth1.ntp.se), esta informação indica que o NTPsec decidiu usar este servidor como principal referência para sincronização.

A coluna “refid” indica o servidor de referência do servidor NTS que você está consultando, isto é, onde o servidor NTS busca sua informação de hora. Se você observar o valor “.NTS.” na coluna “refid” no lugar dos IPs ou nomes de servidores, significa que o NTPsec ainda está negociando a conexão segura com o servidor e ainda não foi capaz de buscar informações de hora. Outra informação importante está na coluna “t” (quarta coluna da esquerda para a direita) que indica a quantidade de “cookies” que seu computador têm para usar com o servidor. Este valor deve ser 8. Números menores na coluna “t” indica conexões interrompidas (o valor 7 pode indicar que uma requisição está em progresso).

Por fim se tudo estiver funcionando corretamente, você pode incluir o NTPsec na inicialização do Linux:

# systemctl enable ntpsec

É isso, agora a sincronização do seu relógio está protegida pela tecnologia mais avançada em termos de NTP 🙂

OBS: se a data do computador estiver muito atrasada ou muito adiantada, o NTS pode encontrar problemas em estabelecer uma conexão com o servidor de chaves do NTS e neste caso você precisa ajustar a data do servidor para um valor aproximado do atual (um dia de atraso não chega a ser um problema). Use o comando abaixo para ajustar a data, escrevendo a data no formato YYYYMMDD (Ano com quatro dígitos, Mês com dois dígitos e Dia com dois dígitos).

date +%Y%m%d -s "20210617"

Criando um servidor NTS

Como dito anteriormente, o NTS é uma forma segura de sincronizar a hora do seu computador, para tanto ele usa uma camada de segurança baseada em TLS 1.3 e assim é OBRIGATÓRIO que você use um certificado digital. O certificado não pode ser autoassinado pois não funcionará (até funciona, com algumas “gambiarras”). A maneira mais fácil é usando um certificado Let’s Encrypt, mas vai precisar que seu servidor tenham um nome FQDN (ou seja, precisará de um domínio registrado, por exemplo: nts.meuservidor.com.br).
Só para facilitar, lista dos requisitos:

  • Debian 10
  • Certificado Digital
  • Um nome FQDN (domínio registrado)
  • Cliente NTS já configurado e funcionando

Se você já tem um certificado válido no seu servidor e você vai usar o mesmo nome de máquina para o servidor NTS, você pode reusar o mesmo certificado. Caso contrário será necessário usar o certbot para solicitar um novo certificado.

Instale o certbot para obtermos o certificado digital:

# apt install certbot

Pare qualquer servidor HTTP antes de solicitar o novo certificado.

systemctl stop apache2
systemctl stop nginx

Solicite um novo certificado:

# certbot certonly --standalone

Preencha os dados do seu certificado (no meu caso eu chamei meu servidor de nts.remontti.com.br, adapte para seu servidor) e responda o resto das perguntas como o modelo abaixo

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): seumelhoremail@example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): nts.remontti.com.br
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nts.remontti.com.br
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/nts.remontti.com.br/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/nts.remontti.com.br/privkey.pem
   Your cert will expire on 2021-09-21. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Agora você á pode reiniciar o servidor HTTP, caso tenha parado o serviço antes de solicitar o certificado.

Vamos copiar o certificado para a pasta do NTPsec para garantir a segurança do mesmo, afinal não queremos dar permissões em excesso para o arquivo possibilitando que alguém roube nossa chave privada invalidando toda nossa segurança.
Não esqueça de ajustar o caminho dos arquivos do certificado digital, pois o certbot usa o nome do domínio para criar a estrutura de pastas utilizada para armazenar estes arquivos.

# cp -v /etc/letsencrypt/live/nts.remontti.com.br/privkey.pem /etc/ntpsec/key.pem
# cp -v /etc/letsencrypt/live/nts.remontti.com.br/fullchain.pem /etc/ntpsec/cert-chain.pem
# chown ntpsec:ntpsec /etc/ntpsec/key.pem
# chown ntpsec:ntpsec /etc/ntpsec/cert-chain.pem
# chmod 600 /etc/ntpsec/key.pem
# chmod 600 /etc/ntpsec/cert-chain.pem

Para ativar o servidor NTS no NTPsec, vamos editar o arquivo de configuração que criamos anteriormente

# vim /etc/ntpsec/ntp.conf

Ao final do arquivo /etc/ntpsec/ntp.conf por volta da linha 28 (ative o número de linhas no vim com o comando “:set nu”), adicione as configurações abaixo:

# Servidor NTS
nts enable
nts key /etc/ntpsec/key.pem
nts cert /etc/ntpsec/cert-chain.pem
nts cookie /var/lib/ntpsec/nts-keys

O conteúdo do arquivo ficará semelhante ao reproduzido abaixo:

# Configuraçao do drift file para o NTPsec computar os erros do relógio do seu computador
driftfile /var/lib/ntpsec/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list

# Configuracao do diretório de log
statsdir /var/log/ntpsec/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

# Lista dos servidores com suporte NTS, você pode adicionar mais servidores à lista
server nts.netnod.se:4460 nts iburst
server sth1.nts.netnod.se:4460 nts iburst
server sth2.nts.netnod.se:4460 nts iburst
server time.cloudflare.com:4460 nts

# Permite trocar informações de hora com qualquer computador mas não permite configuração
# Segundo o guia do netnod essa configuração atende 99% dos casos ;-)
restrict default kod limited nomodify nopeer noquery
restrict -6 default kod limited nomodify nopeer noquery

# Permite consultas locais
restrict 127.0.0.1
restrict -6 ::1

nts enable
nts key /etc/ntpsec/key.pem
nts cert /etc/ntpsec/cert-chain.pem
nts cookie /var/lib/ntpsec/nts-keys

Crie o arquivo utilizado pelo NTPsec para armazenar os cookies dos clientes e configure as permissões do mesmo:

# touch /var/lib/ntpsec/nts-keys
# chown ntpsec:ntpsec /var/lib/ntpsec/nts-keys
# chmod 600 /var/lib/ntpsec/nts-keys

Por fim, reinicie o NTPsec:

# systemctl restart ntpsec

Para verificar se tudo está correto, use o comando abaixo:

# systemctl status ntpsec

Verifique o campo “Active:” a informação “active (running)” indica que o NTPsec está em execução. Não se assuste com algumas linhas em vermelho, se sua saída for semelhante ao texto abaixo (principalmente a última linha “NTSs: Private Key OK”), tudo está bem:

jun 18 16:49:44 nts ntpd[54392]: NTSs: starting NTS-KE server listening on port 4460
jun 18 16:49:44 nts ntpd[54392]: NTSs: OpenSSL security level is 2
jun 18 16:49:44 nts ntpd[54392]: NTSs: starting NTS-KE server listening on port 4460
jun 18 16:49:44 nts ntpd[54392]: NTSs: listen4 worked
jun 18 16:49:44 nts ntpd[54392]: NTSs: listen6 worked
jun 18 16:49:44 nts ntpd[54392]: NTSc: Using system default root certificates.
jun 18 16:49:44 nts ntpd[54392]: NTSs: loaded certificate (chain) from /etc/ntpsec/cert-chain.pem
jun 18 16:49:44 nts ntpd[54392]: NTSs: loaded private key from /etc/ntpsec/key.pem
jun 18 16:49:44 nts ntpd[54392]: NTSs: Private Key OK

Caso não veja estas informações com o comando acima, você pode tentar usar o comando o

journalctl -u ntpsec.service

para verificar as informação de inicialização do NTPsec e rastrear possíveis erros.

Firewall com nftables

Nosso servidor está configurado e funcionando e apesar de o NTS ser muito mais seguro que o NTP, ainda assim não custa nada implementarmos um Firewall. Vamos utilizar o mesmo script do tutorial que o @Remontti preparou para o NTP.
Instale o nftables e o habilite para inciar com o sistema

# apt install -y nftables
# systemctl enable nftables

Crie o arquivo com as regras do nftables. Observe que temos duas listas chamadas acesso-ntp-local-v4 e acesso-ntp-local-v6 onde informamos todos os IPs que podem solicitar informação de hora na nossa rede (Informe os IPs de sua rede!).

# vim /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset
 
table inet filter {
 
    # Permite os ips da sua rede
    set acesso-ntp-v4 {
        type ipv4_addr
        flags interval
        elements = { 127.0.0.1, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 100.64.0.0/10, 200.200.200.0/22 }
    }
    set acesso-ntp-v6 {
        type ipv6_addr
        flags interval
        elements = { ::1,  2804:ff4:bebe::/48 }
    }
 
    chain input {
        type filter hook input priority 0;
 
        # NTP
        ip saddr  @acesso-ntp-v4 tcp dport 4460 counter accept
        ip saddr  @acesso-ntp-v4 udp dport 123 counter accept
        ip6 saddr @acesso-ntp-v6 tcp dport 4460 counter accept
        ip6 saddr @acesso-ntp-v6 udp dport 123 counter accept
        tcp dport 4460 counter drop
        udp dport 123 counter drop
    }
    chain forward {
        type filter hook forward priority 0;
    }
    chain output {
        type filter hook output priority 0;
    }
}

Reinicie o nftables em seguida verifique se as regras foram carregadas:

# systemctl restart nftables
# nft list ruleset

Script para renovação automática do certificado

O certificado digital oferecido gratuitamente pelo Let’s Encrypt tem validade de 90 dias. Para evitar que o nosso servidor NTS fique com um certificado expirado (vencido), vamos criar um script de renovação que será executado periodicamente pelo cron.

Crie o arquivo renovassl.sh

# vim /etc/letsencrypt/renovassl.sh

com o seguinte conteúdo:

#!/bin/bash

# Variaveis
CHAINFILE=$(cat /etc/letsencrypt/renewal/* | awk -F '=' '$1~/fullchain/{print $2;exit}')
KEYFILE=$(cat /etc/letsencrypt/renewal/* | awk -F '=' '$1~/privkey/{print $2;exit}')

# Para temporariamente o servidor web
# Precisamos da porta 80 e 443 livre para o certbot conseguir renovar o certificado
# - Remova o comentário (#) da linha correspondente ao seu servidor web
# /usr/bin/systemctl stop apache2
# /usr/bin/systemctl stop nginx

# Permite o certbot se conectar a porta 80 e 443 para renovar o certificado
nft add rule inet filter input tcp dport 80 counter accept
nft add rule inet filter input tcp dport 443 counter accept


# Aguarda 10 seg (tempo do apache parar) 
sleep 10

# Renova o certificado
/usr/bin/certbot -q renew

# Aguarda o certificado renovar
sleep 30

# Aguarda 2 seg
sleep 2
 
# Restarta o servidor web
# Caso você tenha um servidor web (Apache, Nginx, Lighttpd...), reinicie o serviço
# /usr/bin/systemctl restart apache2
# /usr/bin/systemctl restart nginx

# Para o serviço ntpsec
/usr/bin/systemctl stop ntpsec

# Copia cadeia de certificado e chave privada para o diretorio do NTPsec
/usr/bin/cp $CHAINFILE /etc/ntpsec/cert-chain.pem
/usr/bin/cp $KEYFILE /etc/ntpsec/key.pem

# Altera as permissoes para o usuário speedtest conseguir ler os certificados
/usr/bin/chown ntpsec:ntpsec /etc/ntpsec/cert-chain.pem
/usr/bin/chown ntpsec:ntpsec /etc/ntpsec/key.pem
/usr/bin/chmod 600 /etc/ntpsec/cert-chain.pem
/usr/bin/chmod 600 /etc/ntpsec/key.pem

# Reinicia o serviço NTPsec
/usr/bin/systemctl start ntpsec

# Reinicia o nftables para restaurar as regras
/usr/bin/systemctl restart nftables

Lembre-se de ajustar o script conforme sua necessidade. Você pode ajustar o caminho da chave privada e da cadeia de certificados atribuindo o caminho dos arquivos correspondentes às variávies CHAINFILE e KEYFILE.

Dê permissão de execução ao arquivo renovassl.sh

# chmod +x /etc/letsencrypt/renovassl.sh

E adicione o script ao cron para que a tarefa seja executada periodicamente:

# echo '00 00   1 * *   root    /etc/letsencrypt/renovassl.sh' | tee -a /etc/crontab

Dica, se desejar desativar o TLS1.0 e TLS1.1 após criar um certificado um arquivo é criado /etc/letsencrypt/options-ssl-apache.conf, então edite e inclua no SSLProtocol TLSv1 -TLSv1.1

# vim /etc/letsencrypt/options-ssl-apache.conf

Ficando

#SSLProtocol            all -SSLv2 -SSLv3
SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

Reinicie o Apache:

# systemctl restart apache2

Para testar acesse: https://www.cdn77.com/tls-test/

Gostou? Quer ajudar o blog? 🙂

Se quiser fazer uma doação para o café ficarei muito feliz pelo seu reconhecimento!

Se não puder doar pode deixar seu agradecimento nos comentário ficaremos felizes em saber que ajudamos. Se tiver qualquer pergunta deixe-a também. Se preferir entrar em Contato clique aqui.

Você pode gostar...

2 Resultados

  1. EDSON JOSE BUENO disse:

    Parabéns. Sempre com novas Tecnologias em software.
    Obrigado

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *