Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
linux:ntp [21.02.2024 19:08. ] – [Installation und Chrony-Server-Konfiguration] django | linux:ntp [03.07.2024 19:56. ] (aktuell) – [Rolle] django | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | {{htmlmetatags> | ||
+ | metatag-keywords=(Ansible, | ||
+ | metatag-description=(NTP-Zeitserver mit chrony unter Arch Linux einrichten und nutzen) | ||
+ | }} | ||
====== NTP-Zeitserver mit chrony unter Linux einrichten und nutzen ====== | ====== NTP-Zeitserver mit chrony unter Linux einrichten und nutzen ====== | ||
{{: | {{: | ||
Zeile 26: | Zeile 30: | ||
==== Chrony unter Arch Linux installieren ==== | ==== Chrony unter Arch Linux installieren ==== | ||
Bei der Installation des chrony-Paketes verwenden wir unter **[[https:// | Bei der Installation des chrony-Paketes verwenden wir unter **[[https:// | ||
- | - Als User: < | + | - Als User: < |
- | - Als Nutzer mit Root-Rechten entsprechend: | + | - Als Nutzer mit Root-Rechten entsprechend: |
===== Paketinhalt ===== | ===== Paketinhalt ===== | ||
Zeile 1774: | Zeile 1778: | ||
++++ | ++++ | ||
===== Dokumentation ===== | ===== Dokumentation ===== | ||
- | Eine ausführliche Onlinedokumentation des Chrony Projekts findet sich auf der entsprechnden | + | Eine ausführliche Onlinedokumentation des Chrony Projekts findet sich auf der entsprechenden |
# tree / | # tree / | ||
< | < | ||
Zeile 4584: | Zeile 4588: | ||
# Django : 2024-02-18 | # Django : 2024-02-18 | ||
- | server | + | pool pool.ntp.org iburst |
####################################################################### | ####################################################################### | ||
Zeile 4907: | Zeile 4911: | ||
Die relevanten KOnfigurationsoptionen können wir mit Hilfe von **'' | Die relevanten KOnfigurationsoptionen können wir mit Hilfe von **'' | ||
# grep -Ev ' | # grep -Ev ' | ||
- | < | + | < |
driftfile / | driftfile / | ||
ntsdumpdir / | ntsdumpdir / | ||
Zeile 5184: | Zeile 5188: | ||
MS Name/IP address | MS Name/IP address | ||
=============================================================================== | =============================================================================== | ||
- | ^* defiant.tlercher.de | + | ^+ time.cnetm.de |
+ | ^- frank.askja.de | ||
+ | ^* ntp1.noris.net | ||
+ | ^+ sv1.ggsrv.de | ||
+ | </ | ||
Dieses Beispiel zeigt die Abfrage auf unserem zentralen NTP-Server, den wir gerade eingerichtet haben. Nachfolgendes Beispiel zeigt einen Host, der wiederum unseren eigenen zentralen NTP-Server als Quelle benutzt. | Dieses Beispiel zeigt die Abfrage auf unserem zentralen NTP-Server, den wir gerade eingerichtet haben. Nachfolgendes Beispiel zeigt einen Host, der wiederum unseren eigenen zentralen NTP-Server als Quelle benutzt. | ||
Zeile 5238: | Zeile 5246: | ||
| | ||
- | < | + | < |
+ | .-- Source mode ' | ||
/ .- Source state ' | / .- Source state ' | ||
| / ' | | / ' | ||
Zeile 5248: | Zeile 5257: | ||
MS Name/IP address | MS Name/IP address | ||
=============================================================================== | =============================================================================== | ||
- | ^* defiant.tlercher.de | + | ^+ time.cnetm.de |
+ | ^- frank.askja.de | ||
+ | ^* ntp1.noris.net | ||
+ | ^+ sv1.ggsrv.de | ||
</ | </ | ||
Zeile 5257: | Zeile 5269: | ||
< | < | ||
============================================================================== | ============================================================================== | ||
- | defiant.tlercher.de 6 | + | time.cnetm.de |
+ | frank.askja.de | ||
+ | ntp1.noris.net | ||
+ | sv1.ggsrv.de | ||
Mit der Option **'' | Mit der Option **'' | ||
Zeile 5272: | Zeile 5287: | ||
Name/IP Address | Name/IP Address | ||
============================================================================== | ============================================================================== | ||
- | defiant.tlercher.de 6 | + | time.cnetm.de |
+ | frank.askja.de | ||
+ | ntp1.noris.net | ||
+ | sv1.ggsrv.de | ||
</ | </ | ||
Zeile 5318: | Zeile 5336: | ||
# chronyc tracking | # chronyc tracking | ||
- | < | + | < |
Stratum | Stratum | ||
- | Ref time (UTC) : Wed Feb 21 17:44:33 2024 | + | Ref time (UTC) : Thu Feb 22 12:24:14 2024 |
- | System time : 0.000000083 | + | System time : 0.000030264 |
- | Last offset | + | Last offset |
- | RMS offset | + | RMS offset |
- | Frequency | + | Frequency |
- | Residual freq : +0.279 ppm | + | Residual freq : +0.017 ppm |
- | Skew : 0.179 ppm | + | Skew : 0.322 ppm |
- | Root delay : 0.019519085 | + | Root delay : 0.016084936 |
- | Root dispersion : 0.001197367 | + | Root dispersion : 0.002525240 |
- | Update interval : 1025.2 seconds | + | Update interval : 64.5 seconds |
Leap status | Leap status | ||
Zeile 5388: | Zeile 5406: | ||
===== Orchestrierung - Installation und Konfiguration des chronyd mit Hilfe von Ansible ===== | ===== Orchestrierung - Installation und Konfiguration des chronyd mit Hilfe von Ansible ===== | ||
- | Natürlich wird man im Jahr 2024 nicht mehr ernsthaft, manuell Server aufsetzen und betreiben wollen. Vielmehr wird amn auf ein Orchestrierungswerkzeug wie z.B. **[[linux: | + | Natürlich wird man im Jahr 2024 nicht mehr ernsthaft, manuell Server aufsetzen und betreiben wollen. Vielmehr wird man auf ein Orchestrierungswerkzeug wie z.B. **[[linux: |
Wir werden uns nun nachfolgend sowohl die Client- wie auch die Server-Installation und -konfiguration genauer betrachten. | Wir werden uns nun nachfolgend sowohl die Client- wie auch die Server-Installation und -konfiguration genauer betrachten. | ||
==== Installation und Client-Konfiguration ==== | ==== Installation und Client-Konfiguration ==== | ||
- | Setzen wir einen neue virtuellen Host unter Arch Linux neu auf, oder wollen wir bei einem bestehenden Host die Konfiguration aktualisieren, | + | Setzen wir einen neue virtuellen Host unter Arch Linux neu auf, oder wollen wir bei einem bestehenden Host die Konfiguration aktualisieren, |
=== Rolle === | === Rolle === | ||
Zeile 5412: | Zeile 5430: | ||
└── vars</ | └── vars</ | ||
- | Wie wir sehen ist die Rolle durchaus überschaubar, | + | Wie wir sehen ist die Rolle durchaus überschaubar, |
$ vim ~/ | $ vim ~/ | ||
<file yaml roles/ | <file yaml roles/ | ||
Zeile 5486: | Zeile 5504: | ||
- from: 'pool 2.arch.pool.ntp.org iburst' | - from: 'pool 2.arch.pool.ntp.org iburst' | ||
to : | | to : | | ||
- | pool fd00:: | + | server |
- | pool 2003: | + | server |
- | pool 10.0.0.110 | + | server |
- from: '! mailonchange wibble@example.net 0.5' | - from: '! mailonchange wibble@example.net 0.5' | ||
to : mailonchange django@nausch.org 0.5 | to : mailonchange django@nausch.org 0.5 | ||
Zeile 5526: | Zeile 5544: | ||
<font style=" | <font style=" | ||
<font style=" | <font style=" | ||
+ | <font style=" | ||
<font style=" | <font style=" | ||
<font style=" | <font style=" | ||
Zeile 5540: | Zeile 5559: | ||
==== Installation und Chrony-Server-Konfiguration ==== | ==== Installation und Chrony-Server-Konfiguration ==== | ||
- | Damit unsere eigenen neue virtuellen Host unter Arch Linux die Zeit von unserem eigenen NTP-Server holen können werden wir nun im nächsten Konfigurationsbeispiel mit Hilfe von **[[https:// | + | Damit unsere eigenen neue virtuellen Host unter Arch Linux die Zeit von unserem eigenen NTP-Server holen können werden wir nun im nächsten Konfigurationsbeispiel mit Hilfe von **[[https:// |
=== Rollen === | === Rollen === | ||
Zeile 5546: | Zeile 5565: | ||
Da sich die Installation und Konfiguration unseres **chrony** im Daemon-Modus lediglich bei den Konfigurationsparametern unterscheidet, | Da sich die Installation und Konfiguration unseres **chrony** im Daemon-Modus lediglich bei den Konfigurationsparametern unterscheidet, | ||
$ tree roles/ | $ tree roles/ | ||
- | ++++ | test | + | ++++ roles/ |
< | < | ||
├── defaults | ├── defaults | ||
Zeile 5564: | Zeile 5583: | ||
Wie wir sehen ist die Rolle durchaus überschaubar, | Wie wir sehen ist die Rolle durchaus überschaubar, | ||
$ vim ~/ | $ vim ~/ | ||
+ | ++++ roles/ | ||
<file yaml roles/ | <file yaml roles/ | ||
- include_tasks: | - include_tasks: | ||
tags: chrony | tags: chrony | ||
... # YML Ende</ | ... # YML Ende</ | ||
+ | ++++ | ||
Die eigentliche Installation und Konfiguration erfolgt dann im Task **'' | Die eigentliche Installation und Konfiguration erfolgt dann im Task **'' | ||
$ vim ~/ | $ vim ~/ | ||
+ | ++++ roles/ | ||
<file yaml roles/ | <file yaml roles/ | ||
# Chrony Daemon installieren und als Client konfigurieren. | # Chrony Daemon installieren und als Client konfigurieren. | ||
Zeile 5628: | Zeile 5650: | ||
... # YML Ende</ | ... # YML Ende</ | ||
+ | ++++ | ||
+ | |||
+ | == Firewalld - Paketfilter == | ||
+ | Der eigentliche " | ||
+ | |||
+ | Diese Konfiguration lagern wir in einer eigenen Rolle aus, da diese ja bei Hosts, die den chronyd lediglich als Client nutzen nicht benötigt wird. | ||
+ | |||
+ | Da sich die Installation und Konfiguration unseres **chrony** im Daemon-Modus lediglich bei den Konfigurationsparametern unterscheidet, | ||
+ | |||
+ | Für die Konfiguration der Paketfilterregeln unseres NTP-Serversverwenden wir eine eigene Rolle **chrony_firewalld**, | ||
+ | |||
+ | $ tree roles/ | ||
+ | |||
+ | < | ||
+ | ├── defaults | ||
+ | ├── files | ||
+ | ├── handlers | ||
+ | ├── library | ||
+ | ├── lookup_plugins | ||
+ | ├── meta | ||
+ | ├── module_utils | ||
+ | ├── tasks | ||
+ | │ ├── config.yml | ||
+ | │ └── main.yml | ||
+ | ├── templates | ||
+ | └── vars</ | ||
+ | |||
+ | Wie wir sehen ist die Rolle durchaus überschaubar, | ||
+ | $ vim ~/ | ||
+ | |||
+ | <file yaml roles/ | ||
+ | - include_tasks: | ||
+ | tags: config | ||
+ | ... # YML Ende | ||
+ | </ | ||
+ | |||
+ | Die eigentliche Konfiguration unserer notwendigen Firewall-Regeln erfolgt dann im Task **'' | ||
+ | $ vim ~/ | ||
+ | |||
+ | <file yaml roles/ | ||
+ | # Firewall Daemon Regeln für chrony im Daemon-Mode konfigurieren. | ||
+ | |||
+ | - name: "Port 123/UDP für IPv4 in der Zone IDMZ freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv4 | ||
+ | source address={{ guest_ip4_net_1 }}{{ guest_mask4_1 }} | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip4_1 }}/32 | ||
+ | accept | ||
+ | zone: '{{ guest_zone_1 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: "Port 123/UDP für IPv6 (ULA) in der Zone IDMZ freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv6 | ||
+ | source address=fd00::/ | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip6_ls_1 }}{{ guest_mask6_1 }} | ||
+ | accept | ||
+ | zone: '{{ guest_zone_1 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: "Port 123/UDP für IPv6 (Global-Scope) in der Zone IDMZ freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv6 | ||
+ | source address={{ guest_ip6_net_1 }}{{ guest_mask6_1 }} | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip6_gs_1 }}{{ guest_mask6_1 }} | ||
+ | accept | ||
+ | zone: '{{ guest_zone_1 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: "Port 123/UDP für IPv4 in der Zone INTRA freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv4 | ||
+ | source address={{ guest_ip4_net_2 }}{{ guest_mask4_2 }} | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip4_2 }}/32 | ||
+ | accept | ||
+ | zone: '{{ guest_zone_2 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: "Port 123/UDP für IPv6 (ULA) in der Zone INTRA freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv6 | ||
+ | source address=fd00::/ | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip6_ls_2 }}{{ guest_mask6_2 }} | ||
+ | accept | ||
+ | zone: '{{ guest_zone_2 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: "Port 123/UDP für IPv6 (Global-Scope) in der Zone INTRA freischalten." | ||
+ | ansible.posix.firewalld: | ||
+ | rich_rule: > | ||
+ | rule family=ipv6 | ||
+ | source address={{ guest_ip6_net_2 }}{{ guest_mask6_2 }} | ||
+ | port protocol=" | ||
+ | destination address={{ guest_ip6_gs_2 }}{{ guest_mask6_2 }} | ||
+ | accept | ||
+ | zone: '{{ guest_zone_2 }}' | ||
+ | immediate: true | ||
+ | permanent: true | ||
+ | state: enabled | ||
+ | |||
+ | - name: " | ||
+ | ansible.builtin.service: | ||
+ | name: firewalld | ||
+ | state: reloaded | ||
+ | |||
+ | ... # YML Ende</ | ||
+ | |||
+ | === Inventory -Variablendefinition === | ||
+ | == chronyd== | ||
+ | Über die Variable **'' | ||
+ | |||
+ | $ vim inventories/ | ||
+ | <file yaml inventories/ | ||
+ | - from: 'pool 2.arch.pool.ntp.org iburst' | ||
+ | to : pool pool.ntp.org | ||
+ | - from: '! dumpdir / | ||
+ | to : dumpdir / | ||
+ | - from: '# is unimportant.' | ||
+ | to : | | ||
+ | # is unimportant. | ||
+ | # | ||
+ | # nausch.org : | ||
+ | allow fd00::/10 | ||
+ | allow 10.0.0.0/24 | ||
+ | allow 2003: | ||
+ | allow 192.168.0.0/ | ||
+ | allow 2003: | ||
+ | - from: '! local stratum 10' | ||
+ | to : local stratum 3 | ||
+ | - from: '! logchange 0.5' | ||
+ | to : logchange 0.5 | ||
+ | - from: '! mailonchange wibble@example.net 0.5' | ||
+ | to : mailonchange django@nausch.org 0.5 | ||
+ | - from: '! lock_all' | ||
+ | to : lock_all | ||
+ | </ | ||
+ | |||
+ | == firewalld== | ||
+ | Die Netzwerkspezifischen Definitionen für den Paketfilter holen wir uns aus den Netzwerk-Variablen unseres Hosts selbst. | ||
+ | |||
+ | $ vim inventories/ | ||
+ | <file yaml inventories/ | ||
+ | host_dev: | ||
+ | host_ip: | ||
+ | guest_name: | ||
+ | guest_zone: | ||
+ | guest_domain: | ||
+ | guest_desc: | ||
+ | guest_mate: | ||
+ | guest_ram: | ||
+ | guest_cpu: | ||
+ | guest_imagesize: | ||
+ | guest_imagetype: | ||
+ | guest_imagemode: | ||
+ | guest_source: | ||
+ | guest_zone_1: | ||
+ | guest_bridge_1: | ||
+ | guest_nic_1: | ||
+ | guest_direction_1: | ||
+ | guest_mac_1: | ||
+ | guest_ip4_net_1: | ||
+ | guest_ip4_1: | ||
+ | guest_mask4_1: | ||
+ | guest_gw4_1: | ||
+ | guest_dns4_1: | ||
+ | guest_ip6_ll_1: | ||
+ | guest_ip6_ls_1: | ||
+ | guest_ip6_gs_1: | ||
+ | guest_ip6_net_1: | ||
+ | guest_mask6_1: | ||
+ | guest_gw6_1: | ||
+ | guest_dns6_1: | ||
+ | guest_zone_2: | ||
+ | guest_bridge_2: | ||
+ | guest_nic_2: | ||
+ | guest_direction_2: | ||
+ | guest_mac_2: | ||
+ | guest_ip4_net_2: | ||
+ | guest_ip4_2: | ||
+ | guest_mask4_2: | ||
+ | guest_gw4_2: | ||
+ | guest_dns4_2: | ||
+ | guest_ip6_ll_2: | ||
+ | guest_ip6_ls_2: | ||
+ | guest_ip6_gs_2: | ||
+ | guest_ip6_net_2: | ||
+ | guest_mask6_2: | ||
+ | guest_gw6_2: | ||
+ | guest_dns6_2: | ||
+ | </ | ||
+ | |||
+ | === Playbook === | ||
+ | Die definierte Rollen **chrony_client** und **chrony_firewalld** binden wird dann z.B. in das Playbook für die Installation und Konfiguration des **chrony**-Daemon im **Server-Mode** ein. | ||
+ | # vim playbooks/ | ||
+ | <file yaml playbooks/ | ||
+ | # Ansible Playbook zum Konfigurieren des Chrony-Daemon im Server-Modus unter Arch-Linux. | ||
+ | # Aufruf via $ ansible-playbook playbooks/ | ||
+ | # $ ansible-playbook playbooks/ | ||
+ | # für einen Host aus der Hostgruppe DMZ. | ||
+ | |||
+ | - name: arch_chrony_server.yml | ||
+ | hosts: vml010110 | ||
+ | |||
+ | roles: | ||
+ | - role: chrony_client | ||
+ | tags: chrony_client | ||
+ | - role: chrony_firewalld | ||
+ | tags: chrony_firewalld | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | === Playbooklauf === | ||
+ | Die orchestrierte Variante der Installation und Konfiguration unseres **chrony**-Daemon im **Server-Mode** gestaltet sich ab sofort sehr einfach, brauchen wir doch lediglich die Konfigurationswerte im Inventory zu hinterlegen und zu pflegen und letztendlich das Playbook entsprechend aufzurufen: | ||
+ | $ ansible-playbook playbooks/ | ||
+ | |||
+ | < | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | <font style=" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====== Links ====== | ||
+ | * Zurück zu **[[wiki: | ||
+ | * Zurück zu **[[centos: | ||
+ | * Zurück zu **[[linux: | ||
+ | * Zurück zur **[[http:// | ||