2025-10-31
md
Utilisation du serveur NTP local d'OPNsense
<-Installation de base du pare-feu OPNsense
<-Adding a Local Network Time Server in Linux

Nous devrions tous être de bons cybercitoyens en minimisant notre empreinte digitale sur les réseaux publics. Entre cet objectif louable, l'inertie et la paresse, j'ai bien peur que ce soient ces dernières qui gagnent le plus souvent. Or, depuis la seconde installation d'OPNsense, une étape dans la bonne direction a été franchie sans trop d'effort quant aux appareils branchés sur notre réseau qui coordonnent leur horloge depuis des serveurs de référence publics en utilisent le protocole de synchronisation de réseau NTP (Network Time Protocol).

Table des matières

  1. Gérer les demandes de synchronisation des appareils locaux
    1. Interfaces visées
  2. Configuration NTP d'OPNsense
  3. Vérification du fonctionnement du service ntpd
  4. Utilisation locale du serveur NTP d'OPNsense
  5. Fonctionnement de la règle NAT

Gérer les demandes de synchronisation des appareils locaux toc

Cela fait des années que j'espère réduire autant que possible les requêtes vers les serveurs NTP publics provenant de notre réseau local en installant un serveur de référence local. Je tergiversais, car des dizaines de dispositifs domotiques utilisant Wi-Fi, de nombreux ordinateurs personnels, des serveurs, des téléphones intelligents, deux imprimantes réseau, etc., cherchent tous à synchroniser leur horloge interne en consultant des serveurs de référence NTP qui sont différents selon le choix de l'auteur de leur logiciel. À titre d'exemples, voici quelques-uns des serveurs NTP de référence consultés depuis notre réseau local.

Je supposais qu'il serait nécessaire de reconfigurer tous ces appareils. Il est bien plus facile de les contraindre à recourir au serveur NTP local à leur insu avec une seule règle de routage qui redirige toute requête NTP destinée à un quelconque serveur externe vers au serveur NTP local qui est activé par défaut dans OPNsense. Il suffit de réacheminer tout datagramme provenant d'un réseau interne destiné au port 123 vers le serveur NTP local. Ceci fonctionnera qu'importe l'adresse du serveur de référence ciblé parce que le port 123 est affecté uniquement au protocole NTP selon l'organisme responsable : Internet Assigned Numbers Authority.

Une règle NAT pour tous toc

Comme le dit si bien Gabe Miles dans NTP Server in Opnsense ce n'est pas parce que le serveur NTP est actif que les ordinateurs du réseau l'utiliseront. Bien sûr, on peut reconfigurer chaque appareil pour qu'il utilise le serveur de référence local. On peut même le faire à l'aide du serveur DHCP des réseaux locaux, comme j'ai contemplé le faire auparavant. C'est tellement plus simple d'utiliser la règle de redirection de port proposée par G. Miles dont voici la définition complète.

Cette règle est activée pour toutes les interfaces où se trouvent des appareils qui utilisent NTP pour régler leur horloge. Dans notre réseau local, ces appareils sont connectés au réseau local LAN et au réseau virtuel IOT. En gros, NTP est encapsulé dans le protocole de transport UDP, mais TCP est préférable pour certaines fonctionnalités supplémentaires (voir Network Time Protocol: TCP Services) d'où la redirection des connexions TCP et UDP sur le port 123. La règle s'applique aux connexions établies vers toute destination autre que le pare-feu. Cette exception permet à ce dernier d'obtenir l'heure de serveurs de référence NTP externes. Pour les autres appareils, toute connexion sur le port 123 sera redirigée vers l'hôte local 127.0.0.1 qui est le pare-feu (l'adresse statique 192.168.1.1 aurait fonctionné aussi). On peut mettre le message qu'on veut dans le champ Description, mais aussi bien saisir une description évocatrice susceptible d'être comprise à l'avenir quand les détails auront tous été oubliés. Déjà, je ne me souviens plus si la valeur par défaut pour le dernier paramètre, Filter rule association, était acceptable. Chose certaine, la valeur Pass fonctionne actuellement.

Il ne faut pas oublier de cliquer sur le bouton [Save] au bas de la page puis sur le bouton [Apply] pour activer la nouvelle règle ou toute modification postérieure de la règle. Voici le tableau des règles de redirection de port dans OPNsense après l'ajout de la règle.

Pour créer la règle il a suffi de cliquer sur le bouton [+] dans la page de configuration Firewall: NAT: Port Forward. Pour modifier une règle déjà créée, il suffit de cliquer sur l'icône d'édition dont l'image est un crayon à la droite parmi les autres icônes qui permettent de changer la priorité de la règle, de l'effacer ou de la copier.

Interfaces visées toc

Quand on choisi les interfaces visés par la règle, c'est WAN qui est sélectionné par défaut et l'aide indique que c'est probablement l'interface désirée.

Ce n'est pas le cas, mais heureusement, avec trois clics, LAN et IOT remplacent WAN.

Je n'ai pas trouvé de façon d'utiliser un alias pour un groupe de réseau pour identifier les interfaces visées. Alors ceci est un rappel qu'il faudra être attentif. Si jamais un autre réseau virtuel, dont les hôtes devraient utiliser le serveur NTP local, il sera nécessaire d'ajouter le nouveau réseau dans la liste des interfaces de la règle.

Configuration NTP d'OPNsense toc

Selon la documentation d'OPNsense :

A newly installed firewall comes with NTP enabled on all interfaces (firewall blocks all non LAN access in this case), forwarding queries to one of the X.opnsense.pool.ntp.org upstreams (X is any of 0,1,2,3).
Un pare-feu nouvellement installé est livré avec NTP activé sur toutes les interfaces (le pare-feu bloque alors tout accès hors réseau local), transférant les requêtes vers l'un des serveurs en amont X.opnsense.pool.ntp.org (X étant l'un des nombres suivants : 0, 1, 2 ou 3).

Cette configuration de base fonctionne, mais je préfère la modifier sur la page de configuration Services: Network Time: General.

Supposant que les serveurs NTP de référence sélectionnés par X.opnsense.pool.ntp.org sont situés de l'autre côté de l'océan Atlantique, j'ai opté pour les grappes de serveurs NTP X.ca.pool.ntp.org situées au Canada. Sachant que la connexion à [X.]pool.ntp.org se [fait] normalement à des serveurs de temps provenant de votre pays, ou d'un pays tout près du vôtre, il n'est pas clair que mon choix soit bien meilleur que la configuration suggérée par le projet qui gère les serveurs publics. Parce que chacune des grappes 0, 1, 2 et 3.[ca].pool.ntp.org [pointe] vers un ensemble aléatoire de serveurs qui change toutes les heures, il n'y a pas de raison d'en préférer une. Enfin l'option iburst n'est pas invoquée selon la recommandation suivante.

Soyez indulgent. Plusieurs serveurs sont fournis volontairement, et dans certains cas, ces serveurs sont en réalité des serveurs de fichiers, de courriel, ou web sur lesquels, peut se trouver un serveur ntp. Ceci dit, n'utilisez pas plus de trois [sic] serveurs de temps dans votre configuration et ne faites pas d'optimisations trop sévères tels que les attributs burst ou minpoll. Tout ce que ces attributs font est de créer de la charge inutile sur les serveurs fournis volontairement.
C'est moi qui souligne. Source

La traduction recommande de limiter à trois le nombre de grappes de serveurs consultés alors que la limite dans le texte en anglais est quatre et que la configuration suggérée au tout début du document contient quatre adresses aussi.

On note aussi que la journalisation est activée. Je ne me souviens plus si c'est le cas par défaut, mais il pourrait être utile d'avoir plus d'information pour s'assurer du bon fonctionnement du service pendant sa configuration.

Après modification de la configuration du service, j'ai redémarré ce dernier en cliquant sur l'icône appropriée dans le coin supérieur de la page de configuration.


Vérification du fonctionnement du service ntpd toc

Alors que la commande ps confirme que le processus ntpd est activé, la commande service (un peu l'équivalent de systemctl dans Linux/systemd) ne peut pas afficher l'état du service.

michel@routeur:~ $ ps aux | grep -i ntp root 19088 0.0 0.0 24120 8244 - Ss 15:49 0:00.07 /usr/local/sbin/ntpd -g -c /var/etc/ntpd.conf michel@routeur:~ $ sudo service ntpd status ntpd does not exist in /etc/rc.d or the local startup directories (/usr/local/etc/rc.d), or is not executable

Il ne faut pas oublier qu'OPNsense roule sur une version passablement modifiée de FreeBSD. En outre, la commande service ne contrôle pas les composants d'OPNsense.

On sait que le service a été démarré, et si on examine le journal, on peut voir qu'il fonctionnait toujours quarante minutes plus tard.

michel@routeur:~ $ sudo cat /var/log/ntpd/ntpd_20251029.log Password: ******* <101>1 2025-10-29T00:00:20-03:00 routeur.home.arpa ntpd 61883 - [meta sequenceId="1"] 54.39.196.172 101a 8a sys_peer <101>1 2025-10-29T00:00:20-03:00 routeur.home.arpa ntpd 61883 - [meta sequenceId="2"] 0.0.0.0 c615 05 clock_sync <101>1 2025-10-29T00:00:29-03:00 routeur.home.arpa ntpd 61883 - [meta sequenceId="3"] 167.160.187.179 101a 8a sys_peer <101>1 2025-10-29T00:00:29-03:00 routeur.home.arpa ntpd 61883 - [meta sequenceId="4"] 23.133.168.246 0014 84 reachable ... <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="25"] ntpd 4.2.8p18@1.4062-o Mon Sep 8 02:03:22 UTC 2025 (1): Starting <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="26"] Command line: /usr/local/sbin/ntpd -g -c /var/etc/ntpd.conf <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="27"] ---------------------------------------------------- <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="28"] ntp-4 is maintained by Network Time Foundation, <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="29"] Inc. (NTF), a non-profit 501(c)(3) public-benefit <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="30"] corporation. Support and training for ntp-4 are <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="31"] available at https://www.nwtime.org/support <101>1 2025-10-29T15:49:05-03:00 routeur.home.arpa ntpd 19063 - [meta sequenceId="32"] ---------------------------------------------------- ... <101>1 2025-10-29T16:29:23-03:00 routeur.home.arpa ntpd 27404 - [meta sequenceId="107"] 172.97.210.214 0014 84 reachable <101>1 2025-10-29T16:29:24-03:00 routeur.home.arpa ntpd 27404 - [meta sequenceId="108"] 54.39.17.239 0014 84 reachable <101>1 2025-10-29T16:29:25-03:00 routeur.home.arpa ntpd 27404 - [meta sequenceId="109"] 23.133.168.244 0014 84 reachable <101>1 2025-10-29T16:29:26-03:00 routeur.home.arpa ntpd 27404 - [meta sequenceId="110"] 23.133.168.246 0014 84 reachable <101>1 2025-10-29T16:29:27-03:00 routeur.home.arpa ntpd 27404 - [meta sequenceId="111"] 199.182.221.110 0014 84 reachable

Il n'était pas nécessaire d'ouvrir une session SSH pour voir le journal, car il est accessible depuis l'interface Web d'OPNsense à Services: Network Time: Log File.

Le statut du service peut aussi être affiché par OPNsense (Services: Network Time: Status).

Il semble que c'est une représentation un peu plus digeste de ce qu'affiche l'utilitaire ntpq.

michel@routeur:~ $ ntpq -pn remote refid st t when poll reach delay offset jitter ============================================================================== 0.ca.pool.ntp.o .POOL. 16 p - 64 0 0.000 +0.000 0.000 1.ca.pool.ntp.o .POOL. 16 p - 64 0 0.000 +0.000 0.000 2.ca.pool.ntp.o .POOL. 16 p - 64 0 0.000 +0.000 0.000 3.ca.pool.ntp.o .POOL. 16 p - 64 0 0.000 +0.000 0.000 -162.159.200.1 10.192.8.4 3 u 44 64 77 34.356 -0.460 1.268 +198.181.199.82 .PPS. 1 u 44 64 77 44.128 -2.233 1.830 *216.197.228.230 .PPS. 1 u 47 64 77 52.621 -1.668 1.973 #54.39.196.172 206.126.112.211 2 u 43 64 77 36.289 +8.384 1.185 #54.39.23.64 149.56.19.163 3 u 39 64 77 35.227 +8.254 1.467 +198.181.199.86 .PPS. 1 u 38 64 77 45.667 -1.503 1.049 #50.43.156.177 .GPS. 1 u 41 64 77 55.377 +1.648 7.551 -23.133.168.247 162.159.200.1 4 u 38 64 77 52.891 -6.853 0.920 -23.133.168.246 162.159.200.123 4 u 33 64 77 51.260 -6.919 0.927 -167.160.187.12 167.160.187.179 3 u 32 64 77 29.811 -4.229 1.356 #51.222.111.13 15.254.136.119 2 u 37 64 77 29.803 +5.267 1.155 -216.128.178.20 224.250.214.181 2 u 35 64 77 32.612 -5.152 1.116 -23.133.168.245 162.159.200.1 4 u 30 64 77 50.396 -6.819 1.062 -206.108.0.131 .PTP0. 1 u 35 64 77 24.029 +0.539 1.082 208.81.1.244 132.163.97.1 2 u 36 64 17 52.340 +4.314 1.306 192.95.27.155 15.254.136.119 2 u 40 64 17 32.278 +6.348 1.426 172.97.210.214 .GPS. 1 u 36 64 17 30.868 -1.008 1.280

Utilisation locale du serveur NTP d'OPNsense toc

Paraphrasons ce que disait Gable Miles : que le serveur NTP d'OPNsense soit actif est essentiel, mais pas suffisant pour que tous les hôtes branchés sur le réseau domestique s'en servent pour régler leur horloge. Un test avec un petit script Python, ntpc.py disponible ici, confirme que le serveur était utilisé.

En premier, on suspend la règle NAT de réacheminement du port 123 créée ci-dessus. On fait cela en cliquant sur la flèche verte à deux têtes de la règle dans la page de configuration Firewall: NAT: Port Forward. La flèche devient grise indiquant que la règle sera désactivée quand le bouton [Apply changes] sera activé.

Voici le tableau des règles d'acheminement de ports après ce changement.

Maintenant, des requêtes NTP sont transmises aux serveurs 172.97.210.214 et 1.1.1.1 avec l'utilitaire. Or 172.97.210.214 était le serveur de référence (Active Peer) utilisé par OPNsense auparavant et 1.1.1.1 est le serveur DNS de Cloudflare.

michel@M7:~$ python3 utils.py 172.97.210.214 NTP server '172.97.210.214' will be queried Received 48 bytes from ('172.97.210.214', 123): Time = Wed Oct 29 20:09:48 2025 michel@M7:~$ python3 utils/ntpc.py 1.1.1.1 NTP server '1.1.1.1' will be queried Traceback (most recent call last): File "/home/michel/Documents/PlatformIO/GitHubs/GNATS/utils/ntpc.py", line 40, in <module> sntp_client() File "/home/michel/Documents/PlatformIO/GitHubs/GNATS/utils/ntpc.py", line 30, in sntp_client data, address = client.recvfrom(1024) ^^^^^^^^^^^^^^^^^^^^^ TimeoutError: timed out

Les résultats sont logiques. L'utilitaire fonctionne puisque l'heure courante est obtenue du serveur NTP de référence 172.98.210.214. En revanche la deuxième requête ne fonctionne pas puisque le serveur DNS de Cloudflare n'est évidemment pas un serveur NTP. Pour la seconde partie du test, la règle de réacheminement du port 123 doit être réactivée. Cela se fait comme elle a été suspendue, sauf que la flèche à deux têtes passera de gris à vert.

On utilise l'utilitaire ntpc à nouveau auprès du serveur DNS de Cloudflare.

michel@M7:~$ python3 utils/ntpc.py 1.1.1.1 NTP server '1.1.1.1' will be queried Received 48 bytes from ('1.1.1.1', 123): Time = Wed Oct 29 20:53:22 2025

Cette fois-ci, ntpc obtient l'heure juste, mais on sait déjà que celle-ci ne peut venir de 1.1.1.1. C'est donc qu'en vertu de la règle de redirection la requête a été acheminée au port 123 du pare-feu. C'est le serveur NTP d'OPNsense qui a fourni la bonne réponse. M7 est un ordinateur sur le réseau LAN. Les mêmes résultats sont obtenus avec un ordinateur connecté au réseau virtuel IOT.

Je suppose qu'on pourrait faire ce test sans utiliser mon petit script Python en remplaçant l'adresse du serveur NTP utilisé par un ordinateur branché au réseau avec 1.1.1.1 ou tout autre site qui bloque le port 123. Si l'ordinateur utilise le service systemd-timesyncd pour synchroniser son heure (dans Ubuntu ou ses dérivés comme Mint par example), cela se fait en éditant les paramètres NTP et FallbackNTP dans le fichier /etc/systemd/timesyncd.conf. Puis on pourra s'amuser à suspendre temporairement la règle NAT d'acheminement du port 123 pour voir si une erreur en découle ou non, comme on a fait avec le script. On peut voir quel est le serveur NTP de référence avec la command timedatectl show-timesync. On peut forcer le service à entamer un synchronisation en le redémarrant: sudo systemctl restart systemd-timesyncd.service. Je n'ai pas testé cette façon de procéder, mais j'anticipe qu'il pourrait être plus difficile de constater qu'il y a une erreur quand l'ordinateur essaie d'obtenir l'heure du serveur 1.1.1.1 car en cas d'échec il devrait recourir à l'heure de l'horloge physique du système. Il faut peut être examiné le journal pour déceler qu'une erreur NTP s'est produite et ne pas s'en remettre à un simple examen de l'heure du système avec la commande date.

Fonctionnement de la règle NAT toc

Pour terminer, voici comment observer le réacheminement des connexions sur le port 123 dans la vue en direct du journal du pare-feu Firewall: Log Files: Live View. Pour réduire le nombre d'entrées à quelque chose de gérable, j'ai défini un filtre: [ port ] [ is ] [ 123 ]. Pour l'activer il faut cliquer sur le bouton [+] à sa droite. Un cartouche (badge) contenant la règle __port__=123 indiquant que le filtre est activé. Si on clique sur le cartouche, le filtre sera éliminé. On peut ajouter plusieurs filtres.

En vert, on peut voir que les requêtes vers des serveurs NTP de référence publics provenant du pare-feu leur sont acheminées via l'interface WAN. C'est ce qui est nécessaire pour que le service ntpd puisse synchroniser l'heure. En bleu, on peut voir des paquets NTP (port 123) encapsulés dans des datagrammes UDP redirigés. C'est que veut dire rdr rule qui représente redirection rule. On sait que ces requêtes étaient véritablement envoyées à 1.1.1.1:123) le serveur DNS de Cloudlare les bloquerait et l'heure ne serait pas synchronisée. En fait le client (ici ntpc) obtient en réalité une réponse correcte qui nécessairement provient du serveur NTP local.

michel@M7:~$ utils/ntpc.py 1.1.1.1 NTP server '1.1.1.1' will be queried Received 48 bytes from ('1.1.1.1', 123): Time = Fri Oct 31 17:51:05 2025

Si l'on clique sur l'icône d'information (i) à la droite de l'entrée, on peut voir plus de détails.

On a la confirmation que l'action du pare-feu est de rediriger la requête, mais malheureusement, il n'est pas indiqué vers quelle adresse la redirection se fait. Il est amusant (serait-il plus exact de dire consternant ?) de voir qu'un site externe a tenté de se connecter au service NTP du pare-feu en utilisant le protocole TCP sur le port 123. En voici les détails.

Cela ne me dit pas grand-chose autre que le pare-feu a accompli sa tâche principale en bloquant cette communication potentiellement malveillante.

<-Installation de base du pare-feu OPNsense
<-Adding a Local Network Time Server in Linux