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.
Parabéns. Sempre com novas Tecnologias em software.
Obrigado
Valeu Edson!