Configuring a TFTP server on Ubuntu for switch upgrades and maintenance

Note: Community TFTP documentation is on the Ubuntu Wiki but this short guide adds extra steps to help secure and safeguard your TFTP server.

Every Data Centre Engineer should have a TFTP server somewhere on their network whether it be running on a production host or running on their own notebook for disaster recovery. And since TFTP is lightweight without any user authentication care should be taken to prevent access to or overwriting of critical files.

The following example is similar to the configuration I run on my personal Ubuntu notebook and home Ubuntu servers. This allows me to do switch firmware upgrades and backup configuration files regardless of environment since my notebook is always with me.

Step 1: Install TFTP and TFTP server

$ sudo apt update; sudo apt install tftp-hpa tftpd-hpa

Step 2: Configure TFTP server

The default configuration below allows switches and other devices to download files but, if you have predictable filenames, then anyone can download those files if you configure TFTP Server on your notebook. This can lead to dissemination of copyrighted firmware images or config files that may contain passwords and other sensitive information.

# /etc/default/tftpd-hpa


Instead of keeping any files directly in the /var/lib/tftpboot base directory I’ll use mktemp to create incoming and outgoing directories with hard-to-guess names. This prevents guessing common filenames.

First create an outgoing directory owned by root mode 755. Files in this directory should be owned by root to prevent unauthorized or accidental overwriting. You wouldn’t want your expensive Cisco IOS firmware image accidentally or maliciously overwritten.

$ cd /var/lib/tftpboot
$ sudo chmod 755 $(sudo mktemp -d XXXXXXXXXX --suffix=-outgoing)

Next create incoming directory owned by tftp mode 700 . This allows tftpd-hpa to create files in this directory if configured to do so.

$ sudo chown tftp:tftp $(sudo mktemp -d XXXXXXXXXX --suffix=-incoming)
$ ls -1

Configure tftpd-hpa to allow creation of new files. Simply add –create to TFTP_OPTIONS in /etc/default/tftpd-hpa.

# /etc/default/tftpd-hpa

TFTP_OPTIONS="--secure --create"

And lastly restart tftpd-hpa.

$ sudo /etc/init.d/tftpd-hpa restart
[ ok ] Restarting tftpd-hpa (via systemctl): tftpd-hpa.service.

Step 3: Firewall rules

If you have a software firewall enabled you’ll need to allow access to port 69/udp. Either add this rule to your firewall scripts if you manually configure iptables or run the following UFW command:

$ sudo ufw allow tftp

Step 4: Transfer files

Before doing a firmware upgrade or other possibly destructive maintenance I always backup my switch config and firmware.

cisco-switch#copy running-config tftp://
Address or name of remote host []? 
Destination filename [UHiI443eTG-incoming/config-cisco-switch]? 
3554 bytes copied in 0.388 secs (9160 bytes/sec)
cisco-switch#copy flash:?
flash:c1900-universalk9-mz.SPA.156-3.M2.bin flash:ccpexp flash:cpconfig-19xx.cfg flash:home.shtml

cisco-switch#copy flash:c1900-universalk9-mz.SPA.156-3.M2.bin tftp:// 
Address or name of remote host []? 
Destination filename [UHiI443eTG-incoming/c1900-universalk9-mz.SPA.156-3.M2.bin]? 
85258084 bytes copied in 172.692 secs (493700 bytes/sec)

Files in incoming will be owned by tftp mode 666 (world writable) by default. Remember to move those files to your outgoing directory and change ownership to root mode 644 for safe keeping.

Once you’re sure your switch config and firmware is safely backed up it’s safe to copy new firmware to flash or do any other required destructive maintenance.

Step 5: Prevent TFTP access

It’s good practice on a notebook to deny services when not actively in-use. Assuming you have a software firewall be sure to deny access to your TFTP server when on the road or when connected to hostile networks.

$ sudo ufw deny tftp
Rule updated
Rule updated (v6)
$ sudo ufw status
Status: active

To Action From
-- ------ ----
CUPS ALLOW Anywhere 
OpenSSH DENY Anywhere 
69/udp DENY Anywhere 
CUPS (v6) ALLOW Anywhere (v6) 
OpenSSH (v6) DENY Anywhere (v6) 
69/udp (v6) DENY Anywhere (v6)

Leave a Reply