TFTP over UDP is surprisingly resilient, but its simplicity is also its Achilles’ heel when it comes to security and reliability.
Imagine you’re trying to send a file across a network, but you don’t want to bother with the handshake and overhead of TCP. That’s TFTP. It uses UDP, which means it’s fast and lightweight, but it doesn’t guarantee delivery. It’s like sending a postcard – you hope it gets there, but there’s no tracking number.
Let’s see TFTP in action. Suppose we have a TFTP server running on a Linux machine at 192.168.1.100 and we want to download a configuration file named router.cfg from it to our local machine.
First, on the server, ensure the TFTP service is running. On many Linux systems, this involves starting in.tftpd or tftpd-hpa. The configuration typically lives in /etc/xinetd.d/tftp or /etc/default/tftpd-hpa. A common configuration might look like this:
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftpd"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -s -c"
The TFTP_DIRECTORY is crucial; it’s where the server looks for files to send and where it places files being received.
Now, from your client machine, you can use the tftp command. To download router.cfg:
tftp 192.168.1.100
tftp> get router.cfg
tftp> quit
This will transfer router.cfg to your current directory. If you wanted to upload a file named new_config.txt to the server, you’d use:
tftp 192.168.1.100
tftp> put new_config.txt
tftp> quit
The server will place new_config.txt in its configured TFTP directory.
The core problem TFTP solves is simple file transfer without the complexity of TCP’s connection establishment, flow control, and error correction. It’s ideal for situations where you might not have a full TCP stack available, like booting network devices (PXE boot) or retrieving configuration files from embedded systems.
Internally, TFTP operates on a few simple UDP port pairs. The client initiates a request on UDP port 69. The server, upon receiving a request, acknowledges it and then establishes a new UDP port for subsequent data transfer. This is a key detail: the server doesn’t use port 69 for the data itself. The client also picks an ephemeral port for its side of the data transfer. The server sends data packets (UDP segments) to the client’s ephemeral port, and the client sends acknowledgments back to the server’s ephemeral port. The transfer continues until the entire file is sent, indicated by a data packet smaller than the block size (typically 512 bytes).
The exact levers you control are primarily the server’s configuration and the client’s commands. On the server, you define the directory TFTP operates in, the IP address and port it listens on, and various options like -l (log file transfers) and -s (run in standalone mode, not via xinetd). On the client, you specify the server address, the file to get or put, and sometimes the transfer mode (octet for binary, netascii for text). The block size can sometimes be negotiated or set, impacting performance.
A common point of confusion is that TFTP does have a form of error detection and retransmission, but it’s entirely manual. If a data packet is lost, the client won’t send an acknowledgment for it. The server, after a timeout, will retransmit the last packet it sent. Similarly, if an acknowledgment is lost, the server will retransmit the data packet. This is managed by the TFTP protocol itself, not by the underlying UDP.
The one thing most people don’t realize is how TFTP handles port assignments for the actual data transfer. While the initial request is always on UDP port 69, the subsequent data packets fly between ephemeral ports chosen by both the client and server. This is often a source of firewall issues; simply opening port 69 isn’t enough. You need to allow UDP traffic between the client and server on any high-numbered port that the TFTP server and client dynamically select for the data stream. This dynamic port assignment is what allows multiple TFTP transfers to happen concurrently without interfering with each other on the server’s well-known port 69.
The next hurdle you’ll likely face is dealing with firewalls that block these ephemeral UDP ports used for data transfer.