8. TFTP (Trivial File Transfer Protocol)

El Trivial File Transfer Protocol fue diseñado para brindar un mecanismo de transferencia sumamente simple basado en UDP, ideal para dispositivos con recursos limitados o para etapas de arranque como PXE.

TFTP evita la complejidad de FTP: no requiere autenticación, usa bloques pequeños y confía en retransmisiones cuando se pierde un paquete. Su sencillez lo hace apropiado para routers, switches o sensores IoT que necesitan descargar firmware o respaldar configuraciones sin montar un sistema de archivos completo.

8.1 Características principales

Definido inicialmente en la RFC 1350, TFTP opera sobre el puerto 69/UDP y utiliza un intercambio muy breve de mensajes:

  • Operaciones básicas: lectura (RRQ) y escritura (WRQ) de archivos.
  • Tamaño de bloque configurable: por defecto 512 bytes, negociable mediante la extensión RFC 2348.
  • Control de errores: códigos simples (0 a 7) para indicar problemas de acceso, inexistencia del archivo o infracciones.

Cada bloque enviado exige una confirmación (ACK); si el cliente o el servidor no la reciben dentro del timeout, retransmiten el bloque completo.

8.2 Funcionamiento paso a paso

El flujo de TFTP se repite de forma determinista:

  1. El cliente envía un RRQ o WRQ al puerto 69 del servidor indicando el nombre del archivo y el modo (octet o netascii).
  2. El servidor responde desde un puerto efímero y usa ese nuevo par de puertos para el resto de la transferencia.
  3. Los bloques se numeran desde 1 hasta N; el último bloque tiene menos de 512 bytes o se acuerda un tamaño distinto mediante extensiones.
  4. Si se pierde un bloque, basta con retransmitir la numeración correspondiente sin reiniciar toda la sesión.

El modo octet transmite bytes sin conversión, recomendado para firmware y respaldos, mientras que netascii transforma saltos de línea al estilo ASCII para archivos de texto legibles.

8.3 Ventajas y limitaciones

Ventajas Limitaciones
Implementación pequeña, ideal para ROMs o bootloaders. No ofrece autenticación ni cifrado; cualquier host puede intentar leer o escribir.
Funciona en entornos sin sistema de archivos completo. Depende de IP de confianza y aislamiento de red para mantener la seguridad.
Configuración simple: solo un directorio de base y reglas de firewall. No soporta listados, permisos granulares ni control de versiones.

Por estas limitaciones se recomienda utilizar TFTP solo en redes internas o durante procesos de arranque donde no sea factible algo más complejo.

8.4 Uso en dispositivos embebidos y redes

Muchos fabricantes emplean TFTP para:

  • Actualizar firmware de routers, switches y puntos de acceso desde un servidor central.
  • Cargar configuraciones iniciales en equipos que arrancan por PXE.
  • Respaldar archivos de configuración antes de reemplazar hardware.

En estos escenarios TFTP suele acompañarse con DHCP (que indica el archivo de arranque) y con servidores de automatización que verifican checksums luego de cada transferencia.

8.5 Ejemplo práctico con la herramienta tftp

Windows mantiene el cliente tftp.exe, invocable desde PowerShell para descargar o subir archivos puntuales:

tftp.exe 192.168.10.5 GET config_router.cfg
tftp.exe 192.168.10.5 PUT firmware.bin

Antes de ejecutar, conviene habilitar el cliente TFTP desde las características opcionales del sistema y asegurarse de que el firewall permita el puerto 69/UDP y los puertos efímeros usados para la sesión.

8.6 Automatización básica con Python

Aunque la biblioteca estándar no incluye un cliente TFTP completo, es posible implementar uno sencillo con socket para tareas de laboratorio:

import socket

servidor = ("192.168.10.5", 69)
archivo = "boot.cfg"
modo = "octet"

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
mensaje = b"\x00\x01" + archivo.encode() + b"\x00" + modo.encode() + b"\x00"
sock.sendto(mensaje, servidor)

with open(archivo, "wb") as destino:
    bloque = 1
    while True:
        datos, addr = sock.recvfrom(516)
        op = datos[0:2]
        if op == b"\x00\x05":
            print("Error recibido:", datos[4:].decode())
            break
        numero = int.from_bytes(datos[2:4], "big")
        if numero != bloque:
            continue
        destino.write(datos[4:])
        ack = b"\x00\x04" + datos[2:4]
        sock.sendto(ack, addr)
        if len(datos) < 516:
            break
        bloque += 1
sock.close()

El script envía una solicitud RRQ y recibe bloques consecutivos hasta completar el archivo. Ideal para comprender la mecánica del protocolo en entornos controlados.

8.7 Consideraciones de seguridad y cierre

Dado que TFTP no verifica identidades, se aconseja:

  • Limitar el acceso al servidor a segmentos de red administrados.
  • Configurar directorios de solo lectura para archivos de firmware y separar los de escritura.
  • Registrar eventos y validar checksums de los archivos recibidos.

Cuando se necesita confidencialidad o trazabilidad, la alternativa es migrar a SFTP, FTPS o a mecanismos de aprovisionamiento seguros. TFTP permanece vigente gracias a su simplicidad y a que permite que dispositivos sin almacenamiento persistente descarguen los componentes necesarios para funcionar.