Inhaltsverzeichnis

TFTP-Server unter CentOS 7.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

TFTP-Server

Als erstes installieren wir uns die für den TFTP-Server notwendigen Pakete via yum.

 #  yum install syslinux tftp-server -y

Bei Bedarf informieren wir was bei der Installation der einzelnen Pakete im System installiert wurde.

syslinux

 # rpm -qil syslinux
Name        : syslinux
Version     : 4.05
Release     : 13.el7
Architecture: x86_64
Install Date: Mon 12 Dec 2016 02:42:35 PM CET
Group       : Applications/System
Size        : 2419109
License     : GPLv2+
Signature   : RSA/SHA256, Sun 20 Nov 2016 09:49:35 PM CET, Key ID 24c6a8a7f4a80eb5
Source RPM  : syslinux-4.05-13.el7.src.rpm
Build Date  : Sat 05 Nov 2016 06:42:05 PM CET
Build Host  : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project
Summary     : Simple kernel loader which boots from a FAT filesystem
Description :
SYSLINUX is a suite of bootloaders, currently supporting DOS FAT
filesystems, Linux ext2/ext3 filesystems (EXTLINUX), PXE network boots
(PXELINUX), or ISO 9660 CD-ROMs (ISOLINUX).
/usr/bin/gethostip
/usr/bin/isohybrid
/usr/bin/memdiskfind
/usr/bin/syslinux
/usr/share/doc/syslinux-4.05
/usr/share/doc/syslinux-4.05/COPYING
/usr/share/doc/syslinux-4.05/CodingStyle.txt
/usr/share/doc/syslinux-4.05/NEWS
/usr/share/doc/syslinux-4.05/README
/usr/share/doc/syslinux-4.05/SubmittingPatches.txt
/usr/share/doc/syslinux-4.05/comboot.txt
/usr/share/doc/syslinux-4.05/distrib.txt
/usr/share/doc/syslinux-4.05/extlinux.txt
/usr/share/doc/syslinux-4.05/gpt.txt
/usr/share/doc/syslinux-4.05/isolinux.txt
/usr/share/doc/syslinux-4.05/keytab-lilo.txt
/usr/share/doc/syslinux-4.05/logo
/usr/share/doc/syslinux-4.05/logo/syslinux-100.png
/usr/share/doc/syslinux-4.05/mboot.txt
/usr/share/doc/syslinux-4.05/memdisk.txt
/usr/share/doc/syslinux-4.05/menu.txt
/usr/share/doc/syslinux-4.05/pxelinux.txt
/usr/share/doc/syslinux-4.05/rfc5071.txt
/usr/share/doc/syslinux-4.05/sample
/usr/share/doc/syslinux-4.05/sample/Makefile
/usr/share/doc/syslinux-4.05/sample/m16-640x640-syslinux.jpg
/usr/share/doc/syslinux-4.05/sample/sample.msg
/usr/share/doc/syslinux-4.05/sample/syslinux_splash.jpg
/usr/share/doc/syslinux-4.05/sample/syslogo.lss
/usr/share/doc/syslinux-4.05/sample/syslogo.ppm.gz
/usr/share/doc/syslinux-4.05/sdi.txt
/usr/share/doc/syslinux-4.05/syslinux.txt
/usr/share/doc/syslinux-4.05/usbkey.txt
/usr/share/man/man1/gethostip.1.gz
/usr/share/man/man1/isohybrid.1.gz
/usr/share/man/man1/memdiskfind.1.gz
/usr/share/man/man1/syslinux.1.gz
/usr/share/man/man1/syslinux2ansi.1.gz
/usr/share/syslinux
/usr/share/syslinux/altmbr.bin
/usr/share/syslinux/altmbr_c.bin
/usr/share/syslinux/altmbr_f.bin
/usr/share/syslinux/cat.c32
/usr/share/syslinux/chain.c32
/usr/share/syslinux/cmd.c32
/usr/share/syslinux/config.c32
/usr/share/syslinux/cpuid.c32
/usr/share/syslinux/cpuidtest.c32
/usr/share/syslinux/diag
/usr/share/syslinux/diag/geodsp1s.img.xz
/usr/share/syslinux/diag/geodspms.img.xz
/usr/share/syslinux/diag/handoff.bin
/usr/share/syslinux/disk.c32
/usr/share/syslinux/dmitest.c32
/usr/share/syslinux/dosutil
/usr/share/syslinux/dosutil/copybs.com
/usr/share/syslinux/dosutil/eltorito.sys
/usr/share/syslinux/dosutil/mdiskchk.com
/usr/share/syslinux/elf.c32
/usr/share/syslinux/ethersel.c32
/usr/share/syslinux/gfxboot.c32
/usr/share/syslinux/gptmbr.bin
/usr/share/syslinux/gptmbr_c.bin
/usr/share/syslinux/gptmbr_f.bin
/usr/share/syslinux/gpxecmd.c32
/usr/share/syslinux/gpxelinux.0
/usr/share/syslinux/gpxelinuxk.0
/usr/share/syslinux/hdt.c32
/usr/share/syslinux/host.c32
/usr/share/syslinux/ifcpu.c32
/usr/share/syslinux/ifcpu64.c32
/usr/share/syslinux/ifplop.c32
/usr/share/syslinux/int18.com
/usr/share/syslinux/isohdpfx.bin
/usr/share/syslinux/isohdpfx_c.bin
/usr/share/syslinux/isohdpfx_f.bin
/usr/share/syslinux/isohdppx.bin
/usr/share/syslinux/isohdppx_c.bin
/usr/share/syslinux/isohdppx_f.bin
/usr/share/syslinux/isolinux-debug.bin
/usr/share/syslinux/isolinux.bin
/usr/share/syslinux/kbdmap.c32
/usr/share/syslinux/linux.c32
/usr/share/syslinux/ls.c32
/usr/share/syslinux/lua.c32
/usr/share/syslinux/mboot.c32
/usr/share/syslinux/mbr.bin
/usr/share/syslinux/mbr_c.bin
/usr/share/syslinux/mbr_f.bin
/usr/share/syslinux/memdisk
/usr/share/syslinux/memdump.com
/usr/share/syslinux/meminfo.c32
/usr/share/syslinux/menu.c32
/usr/share/syslinux/pcitest.c32
/usr/share/syslinux/pmload.c32
/usr/share/syslinux/poweroff.com
/usr/share/syslinux/pwd.c32
/usr/share/syslinux/pxechain.com
/usr/share/syslinux/pxelinux.0
/usr/share/syslinux/reboot.c32
/usr/share/syslinux/rosh.c32
/usr/share/syslinux/sanboot.c32
/usr/share/syslinux/sdi.c32
/usr/share/syslinux/sysdump.c32
/usr/share/syslinux/syslinux.com
/usr/share/syslinux/syslinux.exe
/usr/share/syslinux/syslinux64.exe
/usr/share/syslinux/ver.com
/usr/share/syslinux/vesainfo.c32
/usr/share/syslinux/vesamenu.c32
/usr/share/syslinux/vpdtest.c32
/usr/share/syslinux/whichsys.c32
/usr/share/syslinux/zzjson.c32

tftp-server

 # rpm -qil tftp-server
Name        : tftp-server
Version     : 5.2
Release     : 13.el7
Architecture: x86_64
Install Date: Mon 12 Dec 2016 02:42:02 PM CET
Group       : System Environment/Daemons
Size        : 65605
License     : BSD
Signature   : RSA/SHA256, Sun 20 Nov 2016 09:53:09 PM CET, Key ID 24c6a8a7f4a80eb5
Source RPM  : tftp-5.2-13.el7.src.rpm
Build Date  : Sat 05 Nov 2016 04:21:50 PM CET
Build Host  : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://www.kernel.org/pub/software/network/tftp/
Summary     : The server for the Trivial File Transfer Protocol (TFTP)
Description :
The Trivial File Transfer Protocol (TFTP) is normally used only for
booting diskless workstations.  The tftp-server package provides the
server for TFTP, which allows users to transfer files to and from a
remote machine. TFTP provides very little security, and should not be
enabled unless it is expressly needed.
/etc/xinetd.d/tftp
/usr/lib/systemd/system/tftp.service
/usr/lib/systemd/system/tftp.socket
/usr/sbin/in.tftpd
/usr/share/doc/tftp-server-5.2
/usr/share/doc/tftp-server-5.2/CHANGES
/usr/share/doc/tftp-server-5.2/README
/usr/share/doc/tftp-server-5.2/README.security
/usr/share/man/man8/in.tftpd.8.gz
/usr/share/man/man8/tftpd.8.gz
/var/lib/tftpboot

TFTP-Client

Zum Testen unserer Konfiguration greifen wir auf das Clientpaket TFTP zurück. So können wir mit einfachen Mitteln leicht überprüfen, ob der Zugriff auf den TFTP-Server und die auch die Datenübertragung funktioniert.

Falls das Paket tftp noch nicht installiert wurde, können wir dies mittels yum ins System einbinden.

 # yum install tftp -y

Clientpaket tftp

Auch hier können wir uns wie immer vergewissern, was genau installiert wurde.

 # rpm -qil tftp
Name        : tftp
Version     : 5.2
Release     : 13.el7
Architecture: x86_64
Install Date: Mon 12 Dec 2016 02:42:44 PM CET
Group       : Applications/Internet
Size        : 49294
License     : BSD
Signature   : RSA/SHA256, Sun 20 Nov 2016 09:53:05 PM CET, Key ID 24c6a8a7f4a80eb5
Source RPM  : tftp-5.2-13.el7.src.rpm
Build Date  : Sat 05 Nov 2016 04:21:50 PM CET
Build Host  : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : http://www.kernel.org/pub/software/network/tftp/
Summary     : The client for the Trivial File Transfer Protocol (TFTP)
Description :
The Trivial File Transfer Protocol (TFTP) is normally used only for
booting diskless workstations.  The tftp package provides the user
interface for TFTP, which allows users to transfer files to and from a
remote machine.  This program and TFTP provide very little security,
and should not be enabled unless it is expressly needed.
/usr/bin/tftp
/usr/share/doc/tftp-5.2
/usr/share/doc/tftp-5.2/CHANGES
/usr/share/doc/tftp-5.2/README
/usr/share/doc/tftp-5.2/README.security
/usr/share/man/man1/tftp.1.gz

Konfiguration

xinet-Daemon

Die Auslieferung des Bootmenüs und der hierzu notwendigen Dateien erfolgt mit Unterstützung des TFTP-Servers, der mit Hilfe des xinetd-Daemon gestartet wird. Hierzu passen wir die Konfigurationsdatei des xinetd-Daemon wie folgt an.

 # vim /etc/xinetd.d/tftp
/etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
#       protocol.  The tftp protocol is often used to boot diskless \
#       workstations, download configuration files to network-aware printers, \
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /var/lib/tftpboot
        # Django : 2016-01-08 TFTP-Server aktiviert
        # default: disable      = yes
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

Damit der xinetd bei jedem Systemstart automatisch gestartet werden kann, aktivieren wir diesen mit folgendem Befehl.

 # systemctl enable xinetd.service

Die Überprüfung de Autostart vom xinetd können wir bei Bedarf wie folgt prüfen.

 # systemctl is-enabled xinetd.service
enabled

Alternativ dazu können wir auf folgenden Aufruf verwenden:

 # systemctl list-unit-files | grep xinetd.service
xinetd.service                                enabled

Ob der xinted beim Systemstart gestartet wird und dieser den tftp-Server auch anstartet können wir mittels folgendem Aufruf überprüfen.

 # chkconfig --list | tail -n 14
Note: This output shows SysV services only and does not include native
      systemd services. SysV configuration data might be overridden by native
      systemd configuration.

      If you want to list systemd services use 'systemctl list-unit-files'.
      To see services enabled on particular target use
      'systemctl list-dependencies [target]'.

	chargen-dgram: 	off
	chargen-stream:	off
	daytime-dgram: 	off
	daytime-stream:	off
	discard-dgram: 	off
	discard-stream:	off
	echo-dgram:    	off
	echo-stream:   	off
	tcpmux-server: 	off
	tftp:          	on
	time-dgram:    	off
	time-stream:   	off

Paketfilter/Firewall

Damit die Clients später Verbindungsanfragen zu dem geöffneten Port tftp/6980unseres TFTP-Servers stellen können, müssen wir für diese noch Änderungen am Paketfilter firewalld vornehmen.

Unter CentOS 7 wird als Standard-Firewall 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
tftp dhcpv6-client http ssh

Genauso können wir natürlich mit mit dem Befehl iptables abfragen, ob die Erweiterung unseres Paketfilter aktiv ist.

 # iptables -nvL IN_public_allow
Chain IN_public_allow (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:69 ctstate NEW
    6   360 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 ctstate NEW
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW

Systemstart

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.

Jan  5 14:16:24 vml000057 xinetd[22639]: xinetd Version 2.3.15 started with libwrap loadavg labeled-networking options compiled in.
Jan  5 14:16:24 vml000057 xinetd[22639]: Started working: 1 available service

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 xinetd
 udp        0      0 0.0.0.0:69                  0.0.0.0:*                               0          75579      6177/xinetd

Den automatischen Start unseres Serverdienstes haben wir bereits im Absatz xinet-Daemon eingestellt.

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

Testdatei transferieren

Anschließend wechseln wir ins Homeverzeichnis unseres Benutzers.

 # cd ~

Dann bauen wir mit dem TFTP-Clientprogramm eine Verbiundung zu unserem Server auf und holen uns die zuvor angelegte Datei test mit dem Befehl get. Nach dem Herunterladen verlassen wir das Programm mit dem Befehl quit.

 # tftp -v 10.0.0.57
 Connected to 10.0.0.57 (10.0.0.57), port 69
 tftp> get test
 getting from 10.0.0.57:test to test [netascii]
 Received 69 bytes in 0.1 seconds [8714 bit/s]
 tftp> quit

Das Ganze geht natürlich auch schneller als „Einzeiler“:

 # tftp 10.0.0.57 -c get test

Fehlerbehandlung

Klappt der Download von unserem Clientrechners nicht, trotz funktionierendem Zugriff nicht, liegt es an den Paketfilterregelungen auf dem Clientrechner! Wie man in folgendem Beispiel sieht laufen wir hier in einen timeout:

 # tftp -v 10.0.0.57 -c get test
 Connected to 10.0.0.57 (10.0.0.57), port 69
 getting from 10.0.0.57:test to test [netascii]
 Transfer timed out.

Was ist nun passiert? Auf dem Client gibt es doch keine iptables-Regel, die den Datentransfer beschneidet:

 # iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Auf unserem TFTP-Server haben wir doch auch Port 69 freigeschaltet:

 # firewall-cmd --zone=public --list-services
tftp dhcpv6-client http ssh

Im Syslog des TFTP-Servers sehen wir nur die Folgende Fehlermeldung:

 Jan 8 07:49:14 vml000057 in.tftpd[10031]: tftpd: read(ack): No route to host

Die Ursache ist ganz einfach erklärt. TFTP nutzt für die Steuerung Port 69, für die Datenübertragung werden dann aber beliebige highports genutzt. Damit diese nun unseren Paketfilter passieren können, müssen wir an dem betreffenden (Test-)Clientsystem, oder einem internen Paketfilter der unterschiedliche Sicherheitszonen trennt, die folgenden iptables-Module laden.

  • ip_conntrack_tftp
  • ip_nat_tftp

Auf einem CentOS 7 System benutzen wir zur Aktivierung der beiden Module die Datei /etc/modules-load.d/iptables.conf.

 # vim /etc/modules-load.d/iptables.conf
/etc/modules-load.d/iptables.conf
# Django : 2016-01-08 - Zum Testen des TFTP-Servers nötige Änderungen
# default: none
ip_nat_tftp
ip_conntrack_tftp

Zum Aktivieren starten wir den betreffenden Host einmal durch.

 # systemctl reboot

Auf einem CentOS 6 System geschieht dies über die Konfigurationsdatei iptables-config des Paketfilter-Regelwerkes iptables. Dort tragen wir bei den nat helpers die beiden Module nach:

 # vim /etc/sysconfig/iptables-config
# Django 2011-11-24 Freischaltungen für TFTP-Transfers
# default : IPTABLES_MODULES=""
IPTABLES_MODULES="ip_conntrack_tftp ip_nat_tftp"

Anschließend starten wir unseren iptables-Paketfilter einmal durch.

 # service iptables restart
 iptables: Flushing firewall rules:                         [  OK  ]
 iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
 iptables: Unloading modules:                               [  OK  ]
 iptables: Applying firewall rules:                         [  OK  ]
 iptables: Loading additional modules: ip_conntrack_tftp ip_[  OK  ]

Nun versuchen wir erneut unsere Testdatei vom TFTP-Server herunterzuladen , was natürlich Dank unserer Anpassungen nun erfolgreich funktioniert.

 $ tftp 10.0.0.57 -v -c get test
 Connected to 10.0.0.57 (10.0.0.57), port 69
 getting from 10.0.0.57:test to test [netascii]
 Received 69 bytes in 0.1 seconds [6073 bit/s]

Im Syslog unseres TFTP-Servers wird der erfolgreiche Dateitransfer entsprechend protokolliert.

Nov 24 09:14:30 vml000057 xinetd[7708]: START: tftp pid=10145 from=10.0.0.107
Nov 24 09:14:30 vml000057 in.tftpd[10146]: RRQ from 10.0.0.107 filename test

Links