Correção de horario e implantação da geração de Romaneio
This commit is contained in:
135
deploy/ntp-seguro.sh
Executable file
135
deploy/ntp-seguro.sh
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Relógio do SERVIDOR sincronizado com NTP autenticado (NTS).
|
||||
# Rodar UMA VEZ no servidor, como root: sudo bash deploy/ntp-seguro.sh
|
||||
#
|
||||
# ─── POR QUE NO HOST E NÃO NO CONTAINER ──────────────────────────────────────
|
||||
# Container não tem relógio próprio: ele lê o clock do kernel do host. Rodar
|
||||
# chrony/ntpd dentro do container exigiria CAP_SYS_TIME e mudaria a hora do
|
||||
# SERVIDOR INTEIRO a partir de dentro de um processo da aplicação — por isso
|
||||
# não se faz. Dentro do container a gente fixa só o FUSO (TZ, no Dockerfile);
|
||||
# a HORA vem daqui.
|
||||
#
|
||||
# ─── POR QUE NTS E NÃO NTP COMUM ─────────────────────────────────────────────
|
||||
# NTP puro é UDP sem autenticação: qualquer um no caminho pode responder no
|
||||
# lugar do servidor e empurrar a hora da máquina. Isso não é teórico para este
|
||||
# sistema — hora errada muda o dia da consolidação, o recorte do período
|
||||
# financeiro e a validade de sessão/cookie. NTS (RFC 8915) faz uma troca de
|
||||
# chaves por TLS (porta TCP 4460) e assina os pacotes NTP, então uma resposta
|
||||
# forjada é descartada. O `chronyc authdata` no fim mostra se está valendo.
|
||||
#
|
||||
# ─── REDE ────────────────────────────────────────────────────────────────────
|
||||
# Precisa de saída para: UDP 123 (NTP) e TCP 4460 (NTS-KE).
|
||||
# Se o firewall bloquear a 4460, o NTS não fecha e o chrony fica sem fonte.
|
||||
set -euo pipefail
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || { echo "ERRO: rode com sudo."; exit 1; }
|
||||
command -v apt-get >/dev/null || { echo "ERRO: script escrito para Debian/Ubuntu."; exit 1; }
|
||||
|
||||
echo "==> Hora ANTES:"; date; echo
|
||||
|
||||
# ── 1. chrony ────────────────────────────────────────────────────────────────
|
||||
# NTS só existe no chrony >= 4.0 (Debian 11+ / Ubuntu 22.04+ já têm).
|
||||
if ! command -v chronyd >/dev/null; then
|
||||
echo "==> Instalando chrony"
|
||||
apt-get update -qq
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y chrony
|
||||
fi
|
||||
|
||||
versao="$(chronyd --version 2>&1 | grep -oE '[0-9]+\.[0-9]+' | head -1)"
|
||||
if [ "${versao%%.*}" -lt 4 ]; then
|
||||
echo "ERRO: chrony $versao não fala NTS (precisa >= 4.0). Atualize o sistema."
|
||||
exit 1
|
||||
fi
|
||||
echo "==> chrony $versao (NTS disponível)"
|
||||
|
||||
# ── 2. Fontes NTS ────────────────────────────────────────────────────────────
|
||||
# Três fontes independentes de propósito: com uma só, ela cai e o relógio fica
|
||||
# à deriva sem ninguém notar; com três, o chrony ainda descarta a que divergir.
|
||||
CONF_NTS="$(cat <<'CONF'
|
||||
# Gerado por deploy/ntp-seguro.sh — fontes de tempo AUTENTICADAS (NTS).
|
||||
# `iburst`: acerta rápido no boot, em vez de levar minutos.
|
||||
server time.cloudflare.com iburst nts
|
||||
server nts.netnod.se iburst nts
|
||||
server ptbtime1.ptb.de iburst nts
|
||||
|
||||
# Cache das chaves NTS: sem isto, todo restart refaz a troca TLS e o relógio
|
||||
# demora a fechar quando a internet ainda não subiu.
|
||||
ntsdumpdir /var/lib/chrony
|
||||
|
||||
# Sincroniza também o relógio de hardware (RTC), que é de onde a máquina lê a
|
||||
# hora ao ligar — é o que evita voltar errado depois de um reboot/queda de luz.
|
||||
rtcsync
|
||||
|
||||
# makestep: corrige de uma vez (em vez de "escorregar" devagar) quando o erro
|
||||
# é grande, mas só nas 3 primeiras medições. É a linha certa para servidor
|
||||
# físico. SE ESTE SERVIDOR FOR VM QUE HIBERNA/PAUSA e a hora só aparece errada
|
||||
# depois de uma pausa longa, troque pela linha comentada abaixo — ela permite
|
||||
# o salto a qualquer momento (inclusive para trás, então saiba o que ganha):
|
||||
makestep 1.0 3
|
||||
# makestep 1.0 -1
|
||||
CONF
|
||||
)"
|
||||
|
||||
CHRONY_CONF=/etc/chrony/chrony.conf
|
||||
[ -f "$CHRONY_CONF" ] || CHRONY_CONF=/etc/chrony.conf
|
||||
|
||||
cp -n "$CHRONY_CONF" "$CHRONY_CONF.bak-ntp-seguro" 2>/dev/null || true
|
||||
|
||||
# Onde escrever: o Debian/Ubuntu moderno lê o diretório conf.d. Se essa linha
|
||||
# não existir na config, escrever lá seria IGNORADO EM SILÊNCIO — nesse caso a
|
||||
# gente anexa no próprio chrony.conf, entre marcadores, para continuar sendo
|
||||
# possível rodar o script de novo sem duplicar.
|
||||
if grep -qE '^\s*confdir\s+.*conf\.d' "$CHRONY_CONF" 2>/dev/null; then
|
||||
mkdir -p /etc/chrony/conf.d
|
||||
printf '%s\n' "$CONF_NTS" > /etc/chrony/conf.d/nts-reem.conf
|
||||
echo "==> Fontes NTS em /etc/chrony/conf.d/nts-reem.conf"
|
||||
else
|
||||
sed -i '/# >>> nts-reem >>>/,/# <<< nts-reem <<</d' "$CHRONY_CONF"
|
||||
{ echo "# >>> nts-reem >>>"; printf '%s\n' "$CONF_NTS"; echo "# <<< nts-reem <<<"; } >> "$CHRONY_CONF"
|
||||
echo "==> Fontes NTS anexadas em $CHRONY_CONF"
|
||||
fi
|
||||
|
||||
# ── 3. Desligar as fontes NÃO autenticadas ───────────────────────────────────
|
||||
# Deixar o `pool` padrão junto anularia o ganho: o chrony poderia se decidir
|
||||
# por uma fonte sem assinatura. Só comentamos (o .bak fica ao lado).
|
||||
sed -i -E 's/^([[:space:]]*(pool|server)[[:space:]]+.*)$/# [nts-reem] \1/' "$CHRONY_CONF"
|
||||
sed -i -E '/# >>> nts-reem >>>/,/# <<< nts-reem <<</ s/^# \[nts-reem\] (.*)$/\1/' "$CHRONY_CONF"
|
||||
for f in /etc/chrony/sources.d/*.sources; do
|
||||
[ -e "$f" ] || continue
|
||||
mv "$f" "$f.desativado-ntp-seguro"
|
||||
done
|
||||
|
||||
# ── 4. Um serviço de hora só ─────────────────────────────────────────────────
|
||||
# systemd-timesyncd e chrony brigam pelo relógio; o timesyncd não fala NTS.
|
||||
systemctl disable --now systemd-timesyncd 2>/dev/null || true
|
||||
systemctl enable --now chrony 2>/dev/null || systemctl enable --now chronyd
|
||||
|
||||
echo "==> Reiniciando chrony"
|
||||
systemctl restart chrony 2>/dev/null || systemctl restart chronyd
|
||||
sleep 5
|
||||
chronyc makestep >/dev/null 2>&1 || true
|
||||
|
||||
# ── 5. Conferência ───────────────────────────────────────────────────────────
|
||||
echo
|
||||
echo "==> Fontes (o '^*' marca a que está valendo):"
|
||||
chronyc -N sources -v || true
|
||||
echo
|
||||
echo "==> NTS (queremos 'KeyID/Type/KLen' preenchido e Cook > 0 nas 3 linhas):"
|
||||
chronyc -N authdata || true
|
||||
echo
|
||||
echo "==> Estado:"; chronyc tracking || true
|
||||
timedatectl || true
|
||||
echo
|
||||
echo "==> Hora DEPOIS:"; date
|
||||
cat <<'FIM'
|
||||
|
||||
Pronto. O relógio agora se mantém sozinho, inclusive depois de reboot.
|
||||
|
||||
Se a hora tinha saltado, reinicie os containers para os processos longos
|
||||
pegarem o clock corrigido: docker compose restart
|
||||
|
||||
Para conferir depois, a qualquer momento:
|
||||
chronyc tracking # 'System time' deve ficar em milissegundos
|
||||
chronyc -N authdata # NTS ativo em cada fonte
|
||||
FIM
|
||||
Reference in New Issue
Block a user