Sincronicemos relojes con NTP
En el artículo Configurar NTP en GNU/Linux se explicó como instalar y configurar NTP en una máquina cliente, pero faltaron detalles concernientes al protocolo y la instalación de servidores. El protocolo NTP es el más conocido y utilizado para sincronización de relojes, por lo cual es importante conocer las bases del mismo antes de instalar el servicio.

De la teoría de sistemas distribuidos sabemos que existen varios algoritmos para esta tarea. NTP emplea el algoritmo de Marzullo para la estimación, y usa un sistema jerárquico de niveles de fuentes horarias. Cada nivel se denomina stratum, y comienzan en el valor 0. Este valor se utiliza para indicar la distancia desde la fuente horaria, y no es un indicador de calidad o confiabilidad, dado que hay fuentes de stratum 3 de mejor calidad que algunos stratum 2.
Los stratum se definen de la siguiente manera:
  - stratum 0 son dispositivos como relojes atómicos (por ejemplo de cesio), GPS, u otros relojes de radio. En general, estos dispositivos no están conectados a la red, sino conectados a computadoras (por ej, por RS-232).
  - stratum 1 son computadoras conectadas a dispositivos stratum 0. Normalmente actúan de servidores NTP para servidores de stratum 2.
  - stratum 2 son computadoras que envían solicitudes a servidores stratum 1. Estas computadoras suelen utilizar varias fuentes stratum 1 y utilizan el algoritmo NTP para obtener la mejor muestra. Las computadoras de este stratum se comunican entre sí en modalidad peer-to-peer para proveer tiempos más estables y robustos.
  - stratum 3 son computadoras que emplean las mismas funciones que las de stratum 2, y pueden actuar de servidores de capas inferiores. NTP soporta hasta el stratum 256.
De esta organización jerárquica, tenemos que un cliente NTP puede operar en modelo cliente-servidor (donde el stratum del cliente es 1 más que el del servidor), o peer-to-peer (clientes con el mismo stratum). Además de estas dos, un servidor NTP puede funcionar enviando la hora en forma broadcast o multicast, y los clientes se configuran para sincronizarse con estas señales.

El proceso comienza cuendo un cliente NTP envía un paquete conteniendo su timestamp a un servidor. Cuando el servidor recibe el paquete, este almacena su propio timestamp y un timestamp de transmisión en el paquete, y lo envía de regreso al cliente. Una vez que el cliente recibe la respuesta, logguea la hora a la que lo recibió para estimar el tiempo de transmisión del paquete.
Teniendo varias fuentes horarias, el algoritmo de Marzullo selecciona las fuentes que se consideren confiables (en base a ciertos parámetros) para encontrar la hora precisa. De los intervalos retornados por las fuentes, se calcula el menor intervalo que sea consistente con el mayor número de fuentes (intersección). Si por ejemplo, los intervalos son [8,12], [11,13] y [10,12], la intersección de todos da [11,12]. Si en cambio, los intervalos son [8,12], [11,13] y [14,15], no existe un intervalo consistente con todos los valores, pero [11,12] es consistente con el mayor número de fuentes.
En el algoritmo original de Marzullo, el mejor valor se toma como el centro del intervalo. Un acercamiento más sofisticado (y utilizado en NTP) es reconocer que esto puede desperdiciar información valiosa de los intervalos confiables, y por ello es mejor utilizar un modelo probabilístico, que puede retornar un valor distinto al centro.

En GNU/Linux se instala un demonio que puede actuar como servidor y cliente, permitiendo sincronizar relojes con servidores de stratums superiores o entre pares del mismo nivel. La diferencia entre un servidor y un cliente está dada por los comandos de control de acceso.

En una configuración estándar, un host que trabaje de servidor puede configurarse teniendo en cuenta lo siguiente:
  - debe contener al menos una fuente horaria superior (por ejemplo relojes stratum 2 o 1), o bien deben existir otros servidores del mismo nivel (peers) para calcular la hora, o ambos.
  - debe utilizar una fuente horaria local, para el caso en que no se pueda conectar con otros servidores.
  - debe permitir que hosts de la red consulten la hora, pero que no participen en el cálculo de la hora, o modifiquen la configuración.
Por su parte, un host cliente debera configurarse teniendo en cuenta que:
  - debe sincronizar su hora con uno o más servidores NTP superiores
  - no debe permitir que otros hosts consulten su hora, ni alteren la configuración.

Como se vió en el artículo anterior, la instalación del demonio NTP es tan simple como:
  # apt-get install ntpd

Los comandos más utilizados dentro de la configuración (/etc/ntp.conf) son:
  * server define servidor superior con el cual conectarse para obtener información horaria
    + iburst envía una ráfaga de ocho paquetes en lugar de uno en caso que el servidor esté inalcanzable
  * peer define un servidor NTP que se encuentra al mismo nivel
  * fudge permite establecer el stratum de un servidor
  * restrict establece el control de acceso para una dada red o host:
    + kod envía un paquete "kiss of death" si el flag limited está presente y un paquete viola el límite de rate establecido
    + notrap niega el uso del servicio trap
    + nomodify niega consultas que intenten modificar el estado del servidor
    + nopeer evita que el host sea utilizado como servidor de hora
    + noquery previene consultas por el estado del ntpd
 
Teniendo en cuenta lo descripto líneas atrás, la configuración (/etc/ntp.conf) debe contener lo siguiente:
  - En servidores NTP:
    # servidores default debian, cambiar por los deseados
    server 0.debian.pool.ntp.org iburst
    server 1.debian.pool.ntp.org iburst
    server 2.debian.pool.ntp.org iburst
    server 3.debian.pool.ntp.org iburst

    # configurar un servidor del mismo nivel (opcional)
    # peer 192.168.1.10
 
    # reloj local como fuente en caso que la conexión a internet se corte (esto lo asegura el stratum 10)
    server 127.127.1.0
    fudge  127.127.1.0 stratum 10
 
    # acceso completo para localhost
    restrict 127.0.0.1
 
    # permitir a los hosts de la red 192.168.1.0/24 realizar consultas, pero no modificar nada
    restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
 
    # restringir el acceso a todo el resto
    restrict default kod notrap nomodify nopeer noquery

  - Los hosts clientes, por su parte, deberán contar con las líneas:
    # direccion del servidor configurado anteriormente (ej 192.168.1.56)
    server 192.168.1.56
 
    # restringir consultas para que otros hosts no lo utilicen como servidor
    restrict default kod notrap nomodify nopeer noquery

Una vez terminada la configuración, reiniciar el demonio en clientes y servidores:
  # /etc/init.d/ntp restart

Para testear la configuración, se puede ejecutar:
  # ntpq -p
  # ntpdc -p


Referencias

- Network Time Protocol wiki
- Marzullo's algorithm wiki
- Introduction to NTP
- Network Time Protocol daemon
- Access Control Commands and Options
- 6.5. ntpd access restrictions

0 comentarios:

Publicar un comentario