Dies ist eine alte Version des Dokuments!
TFTP-Server unter CentOS 8.x einrichten
Ein wesentlicher Baustein für unseren Installationsserver ist der TFTP-Server, der die Auslieferung der nötigen Dateien für den PXE-Bootvorgang bereitstellt und ausliefert. Eine genaue Beschreibung zu TFTP findet man auf der gut beschriebenen Wikipedia-Seite.
Installation und Konfiguration
manuelle Weg
TFTP-Server installieren
Als erstes installieren wir uns die für den TFTP-Server notwendigen Pakete via dnf
.
# dnf install syslinux tftp-server xinetd -y
Bei Bedarf informieren wir was bei der Installation der einzelnen Pakete im System installiert wurde.
# rpm -qil syslinux # rpm -qil tftp-server # rpm -qil xinetd
Firewall-Daemon anpassen
Damit die Clients später Verbindungsanfragen zu dem geöffneten Port tftp/69unseres TFTP-Servers stellen können, müssen wir für diese noch Änderungen am Paketfilter firewalld vornehmen.
Unter CentOS 8 wird als Standard-Firewall, wie auch schon bereits unter CentOS 7 eingeführt wurde, die dynamische firewalld verwendet. Ein großer Vorteil der dynamischen Paketfilterregeln ist unter anderem, dass zur Aktivierung der neuen Firewall-Regel(n) nicht der Daemon durchgestartet werden muss und somit alle aktiven Verbiundungen kurz getrennt werden. Sondern unsere Änderungen können on-the-fly aktiviert oder auch wieder deaktiviert werden.
Mit Hilfe des Programms firewall-cmd legen wir nun eine permanente Regel in der Zone public für den Service *TFTP für Port 69 an.
# firewall-cmd --permanent --zone=public --add-service=tftp
success
Anschliessend können wir den Firewall-Daemon einmal durchstarten und überprüfen, ob die Regeln auch entsprechend unserer Definition, gezogen haben.
# firewall-cmd --reload
success
Zu guter letzt fragen wir ab, welche Dienste in der Zone public geöffnet sind.
# firewall-cmd --zone=public --list-services
cockpit dhcpv6-client http ssh tftp
xinetd starten
Nun ist es an der Zeit unseren TFTP Server das erste mal über den xinetd zu starten.
# systemctl start xinetd
Im Syslog wird uns der Start des Daemon entsprechend protokolliert.
Jul 4 12:34:26 vml000190 systemd[1]: Starting Xinetd A Powerful Replacement For Inetd... Jul 4 12:34:26 vml000190 xinetd[7993]: xinetd Version 2.3.15 started with loadavg labeled-networking options compiled in. Jul 4 12:34:26 vml000190 xinetd[7993]: Started working: 0 available services Jul 4 12:34:26 vml000190 systemd[1]: Started Xinetd A Powerful Replacement For Inetd.
Ob auf unserem Server nun der TFTP Server läuft und auf Port 69 horcht können wir bei Bedarf auch noch überprüfen.
# netstat -tulpen | grep 69
udp6 0 0 :::69 :::* 0 78244 1/systemd
Den automatischen Start unseres TFTP-Serverdienstes aktivieren wir für den Systemstart nun noch mit:
# Created symlink /etc/systemd/system/multi-user.target.wants/xinetd.service → /usr/lib/systemd/system/xinetd.service.
Ob der Dxinetd-Service gestartet wird können wir bei Bedarf wie folgt abfragen:
# systemctl is-enabled xinetd
enabled
automatisierter Weg mit Hilfe von Ansible
Da wir aber in unserer Produktiven Umgebung alle Server, Dienste und Services mit Hilfe von Ansible werden wir natürlich auch für unseren TFTP-Dienst dies über eine entsprechende Ansible-Rolle ansible-role-tftp.tar.gz1) erledigen lassen.
Wir holen uns also das Verzeichnis mit der role auf unseren Rechner.
$ wget https://dokuwiki.nausch.org/lib/exe/fetch.php/centos:pxe_c8:ansible-role-tftp.tar.gz -O ansible-role-tftp.tar.gz
Da wir bei der Installation und Konfiguration von Ansible bereits das Ansible Directory Layout
erzeugt hatten, brauchen wir nur noch das heruntergeladene Archiv an Ort und Stelle entpacken.
$ tar -xvf ansible-role-tftp.tar.gz -C ~/ansible/roles/
Jetzt brauchen wir nur noch die Rolle unserem Server tftp-server zuordnen.
$ vim ~/ansible/tftp.yml
- ~/ansible/tftp.yml
--- # Start des Playbooks für den TFTP-Server - hosts: tftp-server roles: #- base # Basiskonfiguration (User anlegen) #- chrony # Installation und Konfiguration NTP-Client - tftp # Installation und Konfiguration TFTP-Server ... # Start des Playbooks für den TFTP-Server
Nun brauchen wir nur noch das Playbook ausführen und unser TFTP-Server steht bereit.
$ ansible-playbook -v ~/ansible/tftp.yml
Using /home/ansible/.ansible.cfg as config file BECOME password: PLAY [tftp-server] ************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************* ok: [tftp-server]
TASK [tftp : ***TFTP*** : Installation der TFTP-Server relevanten Pakete (in der aktuellsten Version)] ****************************** changed: [tftp-server] => {"changed": true, "msg": "", "rc": 0, "results": ["Installed: xinetd-2:2.3.15-24.el8.x86_64", "Installed: mtools-4.0.18-14.el8.x86_64", "Installed: tftp-server-5.2-24.el8.x86_64", "Installed: syslinux-6.04-4.el8.x86_64", "Installed: syslinux-nonlinux-6.04-4.el8.noarch"]}
TASK [tftp : ***TFTP*** : Firewall-Daemon für den TFTP-Server anpassen] ************************************************************* changed: [tftp-server] => {"changed": true, "msg": "Permanent operation, Changed service tftp to enabled"}
TASK [tftp : ***TFTP*** : Sicherstellen dass der Daemon 'xinetd', über dem der TFTP-Service gemanaged wird, gestartet wird und läuft] changed: [tftp-server] => {"changed": true, "enabled": true, "name": "xinetd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "syslog.target network.target system.slice basic.target systemd-journald.socket sysinit.target", "AllowIsolate": "no", "AllowedCPUs": "", "AllowedMemoryNodes": "", "AmbientCapabilities": "", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "multi-user.target shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "[not set]", "CPUAccounting": "no", "CPUAffinity": "", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "[not set]", "CPUUsageNSec": "[not set]", "CPUWeight": "[not set]", "CacheDirectoryMode": "0755", "CanIsolate": "no", "CanReload": "yes", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend", "CollectMode": "inactive", "ConditionResult": "no", "ConditionTimestampMonotonic": "0", "ConfigurationDirectoryMode": "0755", "Conflicts": "shutdown.target", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "Xinetd A Powerful Replacement For Inetd", "DevicePolicy": "auto", "Documentation": "man:xinetd man:xinetd.conf man:xinetd.log", "DynamicUser": "no", "EffectiveCPUs": "", "EffectiveMemoryNodes": "", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/bin/kill ; argv[]=/usr/bin/kill -HUP $MAINPID ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/xinetd ; argv[]=/usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/xinetd.service", "GID": "[not set]", "GuessMainPID": "yes", "IOAccounting": "no", "IOSchedulingClass": "0", "IOSchedulingPriority": "0", "IOWeight": "[not set]", "IPAccounting": "no", "IPEgressBytes": "18446744073709551615", "IPEgressPackets": "18446744073709551615", "IPIngressBytes": "18446744073709551615", "IPIngressPackets": "18446744073709551615", "Id": "xinetd.service", "IgnoreOnIsolate": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobRunningTimeoutUSec": "infinity", "JobTimeoutAction": "none", "JobTimeoutUSec": "infinity", "KeyringMode": "private", "KillMode": "control-group", "KillSignal": "15", "LimitAS": "infinity", "LimitASSoft": "infinity", "LimitCORE": "infinity", "LimitCORESoft": "infinity", "LimitCPU": "infinity", "LimitCPUSoft": "infinity", "LimitDATA": "infinity", "LimitDATASoft": "infinity", "LimitFSIZE": "infinity", "LimitFSIZESoft": "infinity", "LimitLOCKS": "infinity", "LimitLOCKSSoft": "infinity", "LimitMEMLOCK": "65536", "LimitMEMLOCKSoft": "65536", "LimitMSGQUEUE": "819200", "LimitMSGQUEUESoft": "819200", "LimitNICE": "0", "LimitNICESoft": "0", "LimitNOFILE": "262144", "LimitNOFILESoft": "1024", "LimitNPROC": "7809", "LimitNPROCSoft": "7809", "LimitRSS": "infinity", "LimitRSSSoft": "infinity", "LimitRTPRIO": "0", "LimitRTPRIOSoft": "0", "LimitRTTIME": "infinity", "LimitRTTIMESoft": "infinity", "LimitSIGPENDING": "7809", "LimitSIGPENDINGSoft": "7809", "LimitSTACK": "infinity", "LimitSTACKSoft": "8388608", "LoadState": "loaded", "LockPersonality": "no", "LogLevelMax": "-1", "LogRateLimitBurst": "0", "LogRateLimitIntervalUSec": "0", "LogsDirectoryMode": "0755", "MainPID": "0", "MemoryAccounting": "yes", "MemoryCurrent": "[not set]", "MemoryDenyWriteExecute": "no", "MemoryHigh": "infinity", "MemoryLimit": "infinity", "MemoryLow": "0", "MemoryMax": "infinity", "MemorySwapMax": "infinity", "MountAPIVFS": "no", "MountFlags": "", "NFileDescriptorStore": "0", "NRestarts": "0", "NUMAMask": "", "NUMAPolicy": "n/a", "Names": "xinetd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "none", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PIDFile": "/var/run/xinetd.pid", "PermissionsStartOnly": "no", "Perpetual": "no", "PrivateDevices": "no", "PrivateMounts": "no", "PrivateNetwork": "no", "PrivateTmp": "no", "PrivateUsers": "no", "ProtectControlGroups": "no", "ProtectHome": "no", "ProtectKernelModules": "no", "ProtectKernelTunables": "no", "ProtectSystem": "no", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "RemoveIPC": "no", "Requires": "sysinit.target system.slice", "Restart": "no", "RestartUSec": "100ms", "RestrictNamespaces": "no", "RestrictRealtime": "no", "RestrictSUIDSGID": "no", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "RuntimeDirectoryPreserve": "no", "RuntimeMaxUSec": "infinity", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardInputData": "", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitIntervalUSec": "10s", "StartupBlockIOWeight": "[not set]", "StartupCPUShares": "[not set]", "StartupCPUWeight": "[not set]", "StartupIOWeight": "[not set]", "StateChangeTimestampMonotonic": "0", "StateDirectoryMode": "0755", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SuccessAction": "none", "SyslogFacility": "3", "SyslogLevel": "6", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "yes", "TasksCurrent": "[not set]", "TasksMax": "12494", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "forking", "UID": "[not set]", "UMask": "0022", "UnitFilePreset": "enabled", "UnitFileState": "enabled", "UtmpMode": "init", "WantedBy": "multi-user.target", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
PLAY RECAP ************************************************************************************************************************************* tftp-server : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Systemtest
Testdatei für die Übertragung anlegen
Für unseren Test legen wir uns einfach eine kleine Textdatei im Arbeitsverzeichnis /var/lib/tftpboot/ an, die wir uns dann vom TFTP-Server herunterladen werden.
# echo "Dies ist ein ganz einfacher Text für den Test unseres TFTP-Servers" > /var/lib/tftpboot/test