Skip to main content

You are here

tftpd-hpa

Monitoring TFTPd server

So I just spent the last two hours of my life trying to figure why PXE booting was not working in my home network. Turned out the root cause was my fault completely since, I forgot to add a firewall rule on my dhcp/PXE server to allow incoming UDP connections on port 69.

Fix:

iptables -A INPUT -p udp -m udp --dport 69 -j ACCEPT

As with just about any other service, this service can be monitored using Nagios. Originally, I had problems using the check_tftp.pl and check_tftp plugins that are available from on Nagios Exchange repo, mainly because of the way I have setup my machines.

check_tftp This plugin was useless in my environment because this plugin all it does is send out an status command to the TFTP server. Since I'm using the BSD tftp client, all status commands sent to any host will always show up as being connected regardless.
http://exchange.nagios.org/directory/Plugins/Network-Protocols/TFTP/chec...

check_tftp.pl This plugin was not opted to work in my environment. Mainly because it uses Net::TFTP, unlike the tftp client application, Net::TFTP does not support specifying a custom reverse connection port (or port ranges). By default, when connecting to a TFTP server, the TFTP server will dynamically choose a random non-standard port to connect back to the client machine and proceed with the TFTP download. My Nagios machine (like all of my machines) are set to drop all incoming packets except for specific ports and related/established connections.
http://exchange.nagios.org/directory/Plugins/Network-Protocols/TFTP/chec...

I wrote a simple Nagios plugin that monitors TFTP. All it simply does, is download a non-empty file called test.txt.

#!/usr/bin/perl -w

# Tony Baltazar. root[@]rubyninja.org

use strict;
use Getopt::Long;




my %options;
GetOptions(\%options, "host|H:s", "port|p:i", "rport|R:s", "file|f:s", "help");


if ($options{help}) {
	usage();
	exit 0;
} elsif ($options{host} && $options{port} && $options{file}) {
	chdir('/tmp');

	my $cmd_str = ( $options{rport} ?  "/usr/bin/tftp -R $options{rport}:$options{rport} $options{host} $options{port} -c get $options{file}" : "/usr/bin/tftp $options{host} $options{port} -c get $options{file}");

	my $cmd = `$cmd_str`;
	if ($? != 0) {
		print "CRITICAL: $cmd";
		system("rm -f /tmp/$options{file}");
		exit 2;
	} else {
		if (! -z "/tmp/$options{file}" ) {
			print "TFTP is ok.\n$cmd";
			system("rm -f /tmp/$options{file}");
			exit 0;
		} else {
			print "WARNING: $cmd";
			system("rm -f /tmp/$options{file}");
			exit 1;
		}
	}

} else {
	usage();
}



sub usage {
print < --port= --file=]

   --host | -H  : TFTP server.
   --port | -p  : TFTP Port.
   --file | -m  : Test file that will be downloaded.
   --help | -h  : This help message.

Optionally,
   --rport | -R : Explicitly force the reverse originating connection's port.

EOF
}

https://github.com/alpha01/SysAdmin-Scripts/blob/master/nagios-plugins/c...

Seeing the plugin in action:
Assuming, we're using port udp 1069 to allow the TFTP server (192.168.1.2) to connect to the Nagios monitoring machine.

[[email protected] libexec]# iptables -L -n |grep "Chain INPUT"
Chain INPUT (policy DROP)
[[email protected] libexec]# iptables-save|grep 1069
-A INPUT -s 192.168.1.2/32 -p udp -m udp --dport 1069 -j ACCEPT

Firewall not allowing TFTP to connect back using port 1066.

[[email protected] libexec]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1066 -f test.txt'
CRITICAL: Transfer timed out.

Downloading a non-existing file from the TFTP server.

[[email protected] tmp]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1069 -f test.txtFAKESHIT'
WARNING: Error code 1: File not found

Successful connection and transfer.

[[email protected] tmp]# su - nagios -c '/usr/local/nagios/libexec/check_tftp.pl -H 192.168.1.2 -p 69 -R 1069 -f test.txt'
TFTP is ok.

Programming: 

Awesome Applications: 

FreeBSD diskless PXE booting

After a couple of trial and error tests and lots of caffeine ingested, I finally managed to install FreeBSD 9.1 over my network completely diskless using ISC's DHCP, PXE, tftpd-hpa, and NFS.

Download iso image and copy over all files.

wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/9.0/Fr...
mount -o loop FreeBSD-9.0-RELEASE-amd64-disc1.iso /mnt
mkdir -p /srv/tftp/freebsd/amd64
cp -a /mnt/* /srv/tftp/freebsd/amd64
cp -a /mnt/.cshrc /srv/tftp/freebsd/amd64
cp -a /mnt/.profile /srv/tftp/freebsd/amd64
cp -a /mnt/.rr_moved /srv/tftp/freebsd/amd64

Create the following directories:

mkdir /srv/tftp/freebsd/amd64/jails
mkdir -p /srv/tftp/freebsd/amd64/conf/base/jails
mkdir /srv/tftp/freebsd/amd64/conf/default
chmod -R 777 /srv/tftp/freebsd/amd64/conf
chmod -R 777 /srv/tftp/freebsd/amd64/jails

Edit /srv/tftp/freebsd/amd64/etc/fstab, comment out the entry in the file:

#/dev/iso9660/FREEBSD_INSTALL / cd9660 ro 0 0

Add the following entry to /srv/tftp/freebsd/amd64/etc/rc.conf:

root_rw_mount="NO"

NFS configuration:

/srv/tftp/freebsd/amd64		192.168.1.1/24(ro,sync,no_root_squash,no_subtree_check)

dhcpd configuration (of course, IP may differ depending on your environment):
192.168.1.128 will be the IP that wil be assigned to the new FreeBSD system.
192.168.1.2 is the IP of the NFS server where the installation files are stored in.
The filename path is relative to what path you configured with tftpd-hpa.

host freebsdboot {
  hardware ethernet 08:00:27:2b:f9:f8;
  fixed-address 192.168.1.128;
  filename "freebsd/amd64/boot/pxeboot";
  option root-path "192.168.1.2:/srv/tftp/freebsd/amd64";
}

FreeBSD Diskless PXE

References:
http://forums.freebsd.org/showthread.php?t=30069
http://lists.freebsd.org/pipermail/freebsd-questions/2012-March/238969.html
http://box.matto.nl/disklessfreebsd.html

Awesome Applications: 

Unix: 

Premium Drupal Themes by Adaptivethemes