4. TFTP 传输故障:文件路径错误、权限不足、防火墙阻断、超时与重传机制调优

TFTP 这玩意儿,看着简单,用起来坑不少。很多刚入行的兄弟觉得它不就是个传文件的小工具嘛,能出啥问题?嘿,我告诉你,恰恰因为它简单,所以一旦出故障,排查起来反而容易让人抓瞎。没有认证、没有复杂的握手,出了问题,日志就那么几行,全靠经验猜。

今天咱们就把 TFTP 传输故障的四个大头——文件路径、权限、防火墙、超时重传——掰开揉碎了讲。我这些年踩过的坑,都在这儿了。

4.1 文件路径错误:最常见的“找不到文件”

TFTP 服务端启动时,会指定一个根目录。客户端请求文件时,路径是相对于这个根目录的。很多人以为路径写对了,其实不然。

核心原则:TFTP 没有“..”回退,路径必须严格在根目录下。你给客户端传 /boot/vmlinuz,服务端实际找的是 /tftpboot/boot/vmlinuz(假设根目录是 /tftpboot)。

我遇到过最典型的案例:有人把 PXE 配置文件放在 /tftpboot/pxelinux.cfg/ 下,但客户端请求的是 pxelinux.cfg/default。服务端根目录是 /tftpboot,结果死活找不到。为什么?因为客户端请求路径里没有前导斜杠,而服务端拼接路径时,有的实现会多一个斜杠,有的不会。

排查路径问题,我建议你按这个顺序来:

  1. 确认服务端根目录:用 ps aux | grep tftp 看启动参数,比如 -s /tftpboot 就是根目录。
  2. 模拟客户端请求:在服务端本地用 tftp localhost 连进去,用 get 命令下载文件,看报错。
  3. 检查文件是否存在:在根目录下用 ls -la 确认文件路径完全匹配。
  4. 注意大小写:TFTP 协议本身不区分大小写,但底层文件系统区分。Linux 下 vmlinuz 和 VMLINUZ 是两个文件。

小技巧:开启 TFTP 服务的详细日志。比如在 dnsmasq 里加 --log-dhcp --log-tftp,或者在 tftp-hpa 里用 -v -v 参数。日志会告诉你客户端到底请求了什么路径,一对比就知道问题在哪。

4.2 权限不足:服务跑起来了,但读不了文件

路径对了,文件也在,但客户端还是报“Access violation”或“File not found”。这时候八成是权限问题。

TFTP 服务进程通常以 nobody 或 tftp 用户运行。这个用户对根目录和文件必须有读权限。注意,是目录的执行权限(x)和文件的读权限(r),缺一不可。

我记得有一次帮客户排查,他们把所有文件权限都设成了 777,但还是报错。我过去一看,好家伙,根目录 /tftpboot 的属主是 root,权限是 755,没问题。但里面有个子目录 /tftpboot/images,权限是 700,属主是另一个用户。TFTP 进程根本进不去这个子目录。

权限检查清单:

检查项 命令/方法 正确状态
服务运行用户 ps -eo user,comm | grep tftp 通常是 nobody 或 tftp
根目录权限 ls -ld /tftpboot 至少 755,属主不重要,但 other 要有 r-x
子目录权限 ls -ld /tftpboot/*/ 每一级目录都要有 r-x 权限
文件权限 ls -la /tftpboot/boot/vmlinuz 至少 644,other 要有 r--
SELinux/AppArmor getenforce / aa-status 检查是否拦截了 tftp 的读操作

注意:如果你用了 SELinux,光改文件权限没用。需要检查 tftp_t 上下文,或者直接 setsebool -P tftp_home_dir on。我曾经在这个坑里浪费了半天,后来发现是 SELinux 把 TFTP 的读操作给 block 了。

4.3 防火墙阻断:数据包有去无回

TFTP 使用 UDP 69 端口做控制连接。但数据传输时,会使用动态端口(通常是 1024 以上)。这就麻烦了——防火墙如果只开了 69 端口,数据包根本回不来。

为什么会这样?TFTP 有两种传输模式:

  • 标准模式:服务端从随机端口(比如 34567)向客户端的随机端口发数据。防火墙必须允许来自服务端高端口的 UDP 包进入客户端。
  • TSIZE 选项:部分实现支持,但本质不变。

我建议你在防火墙上做这几件事:

  1. 开启 UDP 69 端口:这是基础,允许客户端连接。
  2. 开启临时端口范围:允许来自服务端 1024-65535 的 UDP 包进入客户端。或者更严格一点,只允许来自 TFTP 服务端 IP 的包。
  3. 考虑使用 TFTP 中继或代理:如果跨网段传输,防火墙规则会变得很复杂。用 atftp 或 tftp-hpa 的 -m 选项指定端口范围,可以缩小防火墙开放范围。

实战命令:在 Linux 上用 iptables 开放 TFTP:

# 开放 69 端口
iptables -A INPUT -p udp --dport 69 -j ACCEPT

# 开放临时端口范围(假设服务端 IP 是 192.168.1.100)
iptables -A INPUT -p udp -s 192.168.1.100 --sport 1024:65535 -j ACCEPT

嗯,这里要注意,如果你用 systemd 的 tftp.socket,它会自动监听 69 端口并启动服务。但防火墙规则还是要手动配。

4.4 超时与重传机制调优:传输慢得像蜗牛

TFTP 的可靠性全靠超时重传。它发一个数据块,等 ACK,等不到就重传。默认超时时间通常是 5 秒,重传次数 5 次。你想想看,如果网络延迟稍微大一点,或者丢包率 1%,整个传输过程会慢到什么程度?

我调优过的最极端案例:一个客户在跨国链路上用 TFTP 传 100MB 的固件,默认参数下传了 40 分钟还没完。我一看抓包,好家伙,每次超时都等 5 秒,重传 5 次,然后放弃。实际上链路延迟只有 300ms,丢包率 2%。

调优的核心参数:

参数 默认值 调优建议 说明
超时时间 (timeout) 5 秒 1-3 秒 根据 RTT 设置,RTT 的 3-5 倍即可
重传次数 (retries) 5 次 3-8 次 丢包率高就加大,但别超过 10 次
块大小 (blksize) 512 字节 1024-1468 字节 加大块大小减少交互次数,但别超过 MTU
窗口大小 (windowsize) 1 4-16 允许连续发多个块再等 ACK,大幅提升吞吐

怎么调?用 atftp 客户端,它支持这些选项:

# 设置超时 2 秒,重传 3 次,块大小 1024,窗口大小 8
atftp --option "timeout 2" --option "retries 3" \
      --option "blksize 1024" --option "windowsize 8" \
      -g -r firmware.bin 192.168.1.100

服务端也要支持这些选项。比如 tftp-hpa 的 tftpd,启动时加 -B 1024 -w 8 来设置块大小和窗口大小。

我的经验:调优前先抓包看 RTT 和丢包率。用 tcpdump -i eth0 port 69 or portrange 1024-65535 抓个 30 秒,然后用 Wireshark 分析。如果 RTT 稳定在 10ms 以内,超时设 1 秒就够了。如果丢包率超过 5%,先修网络,别指望重传能解决一切。

4.5 知识体系:一张图看懂 TFTP 故障排查

说了这么多,我把整个排查逻辑画成了一张流程图。你照着这个走,90% 的 TFTP 问题都能定位到。

TFTP 传输故障排查流程图 TFTP 传输故障排查流程 TFTP 传输失败 1. 检查文件路径是否正确 2. 检查文件/目录权限 3. 检查防火墙是否阻断 4. 检查超时与重传参数 定位并解决故障 排查要点 • 用 tftp localhost 模拟 • 查看服务端详细日志 • 检查 SELinux 上下文 • 抓包分析 RTT 和丢包 • 调整 blksize/windowsize • 确认防火墙临时端口 • 检查文件系统大小写 • 确认服务运行用户 • 测试不同 TFTP 客户端

这张图从左到右,从上到下,就是标准的排查顺序。别跳步,一步步来。我见过太多人一上来就调超时参数,结果发现是路径写错了——白忙活。

4.6 避坑指南:我曾经踩过的雷

最后分享几个我亲身经历过的坑,你遇到了能少走弯路:

  • 坑一:符号链接。TFTP 服务默认不跟随符号链接。你在 /tftpboot 下建个软链接指向 /boot,客户端访问这个链接会报错。解决办法:用 mount --bind 替代软链接。
  • 坑二:文件大小限制。老版本的 TFTP 最大只支持 32MB 文件(因为块号用 16 位表示)。现在大部分实现支持大文件,但如果你用的嵌入式设备上的 TFTP 客户端,可能还有这个限制。传大文件前先确认。
  • 坑三:多客户端并发。默认的 tftp-hpa 是单线程的,一个客户端传输时,其他客户端会排队。高并发场景下,用 dnsmasq 或 atftpd 的多线程模式。
  • 坑四:Windows 防火墙。Windows 自带的 TFTP 客户端和服务端,防火墙规则经常漏配。我建议直接用 tftp 命令行工具测试,别依赖图形界面。

好了,TFTP 传输故障这块,核心就是路径、权限、防火墙、超时重传这四个维度。你把这四个点吃透了,以后遇到 TFTP 问题,心里就有底了。