3、TFTP服务器搭建:安装与配置TFTP服务、传输模式与权限、常见故障排查

TFTP,全称Trivial File Transfer Protocol。说白了,就是个简化版的FTP。它没有认证,没有目录列表,甚至没有删除功能。那为什么我们在网络启动里离不开它?因为简单、轻量、容易嵌入固件。PXE启动时,BIOS/UEFI从DHCP拿到IP后,下一步就是通过TFTP去下载引导文件。这一步要是卡住了,后面全白搭。

我个人习惯,在搭建PXE环境时,先把TFTP调通,再搞别的。因为TFTP是整条链路里最脆弱的一环——它基于UDP,没有重传机制,丢包就完蛋。所以,配置要稳,权限要对,路径不能错。

3.1 安装与配置TFTP服务

Linux下最常用的是tftp-hpa和atftpd。我推荐tftp-hpa,因为它更接近PXE规范里的实现。安装很简单:

# Debian/Ubuntu
sudo apt install tftpd-hpa

# RHEL/CentOS
sudo yum install tftp-server

装完后,配置文件在/etc/default/tftpd-hpa(Debian系)或/etc/xinetd.d/tftp(RHEL系)。我个人习惯用独立服务模式,不依赖xinetd,省得多个进程抢端口。

看一个典型的配置:

# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --create --verbose"

这里有几个关键点:

  • --secure:限制TFTP只能访问指定目录,不能往上翻。这个必须开,否则就是安全漏洞。
  • --create:允许客户端上传文件。调试时有用,生产环境建议关掉。
  • --verbose:打印详细日志。排查问题时,这个选项能救命。

配置完重启服务:

sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa
我的小技巧: 启动后,用netstat -uln | grep :69确认服务在监听。如果没看到,八成是端口被占用了——我遇到过某款安全软件把69端口当后门给封了。

3.2 传输模式与权限

TFTP支持两种传输模式:netascii和octet。netascii是文本模式,会做换行符转换;octet是二进制模式,原样传输。网络启动用的文件——pxelinux.0、vmlinuz、initrd——全是二进制文件,所以必须用octet模式。

客户端默认用octet,但有些老旧的BIOS实现会发netascii请求。这时候服务器端要能正确处理。我遇到过一台2008年的服务器,它的PXE ROM只支持netascii,结果传内核文件时数据被截断了。排查了半天,最后在TFTP选项里强制指定了--blocksize 1468才解决。

权限问题更常见。TFTP服务通常以tftp用户运行,这个用户对/srv/tftp目录要有读权限。如果文件权限是600,tftp用户读不了,客户端就会报File not found。嗯,这里要注意:

sudo chown -R tftp:tftp /srv/tftp
sudo chmod -R 755 /srv/tftp

还有一个坑:SELinux。RHEL/CentOS上,即使文件权限对了,SELinux策略也可能阻止TFTP读取文件。检查一下:

sudo getsebool tftp_home_dir
sudo setsebool -P tftp_home_dir on
问题现象 可能原因 排查命令
客户端报"File not found" 文件权限不足或路径错误 ls -l /srv/tftp/
传输到99%卡住 blocksize太小或网络丢包 tcpdump -i eth0 port 69
服务启动但连不上 防火墙拦截UDP 69 sudo ufw status

3.3 常见故障排查

TFTP出问题,症状很直接:客户端卡在Downloading pxelinux.0...或者直接报PXE-T01: File not found。别慌,按顺序查。

第一步:确认服务在跑

sudo systemctl status tftpd-hpa

如果显示active (running),继续。如果没跑,看日志:

sudo journalctl -u tftpd-hpa -n 20

第二步:检查防火墙

UDP 69端口必须开放。我习惯用nc模拟一个TFTP请求来测试:

# 从另一台机器
echo "test" | nc -u -w 2 TFTP_SERVER_IP 69

如果没反应,防火墙大概率在作祟。我曾经在客户现场折腾了半小时,最后发现是云平台的安全组规则没放行UDP 69。

第三步:验证文件路径

TFTP的根目录是/srv/tftp,客户端请求pxelinux.0时,实际访问的是/srv/tftp/pxelinux.0。很多新手把文件放到了/srv/tftp/pxe/下面,然后客户端请求pxelinux.0,当然找不到。

我自己的做法:在根目录下放一个test.txt文件,内容随便写点东西。然后用客户端去get这个文件:

tftp TFTP_SERVER_IP
tftp> get test.txt
tftp> quit

如果能下载下来,说明TFTP基本通了。如果不行,检查--secure选项是否限制了路径。

注意: TFTP没有目录列表功能。你不能用ls或dir命令查看服务器上有哪些文件。所有文件路径必须提前知道,或者通过DHCP的next-server和filename选项指定。我曾经见过有人把文件名拼错了,结果排查了一整天。

第四步:抓包分析

如果以上都正常,但客户端还是失败,那就上tcpdump:

sudo tcpdump -i eth0 -nn port 69 -X

看客户端发过来的RRQ(读请求)包里,请求的文件名是什么。有时候客户端会发一个带路径的请求,比如/boot/pxelinux.0,而你的TFTP根目录下没有boot子目录,自然就404了。

我记得有一次,客户报修说新部署的PXE环境无法启动。我抓包一看,客户端请求的是EFI/BOOT/BOOTX64.EFI,但服务器上文件实际在/srv/tftp/efi/boot/bootx64.efi。大小写不匹配,TFTP是区分大小写的。改过来就好了。

核心要点: TFTP故障排查,本质上是确认「服务在跑、端口通、文件在、路径对、权限够」。按这个顺序查,90%的问题都能解决。剩下的10%,多半是网络层面的MTU或丢包问题,调小blocksize试试。

最后说一句,TFTP虽然简单,但它是整个网络启动的基石。把这个环节搞扎实了,后面的NFS、HTTP启动才能顺风顺水。嗯,今天就先聊到这儿。