4、TFTP服务器搭建:tftp-hpa安装、目录结构设计、权限与防火墙配置、传输测试

TFTP,全称是Trivial File Transfer Protocol。说白了,就是个简化版的FTP。它没有认证,没有目录列表功能,只能上传下载文件。但正因为简单,它特别适合用在网络启动的早期阶段——那时候客户端连操作系统都没加载,你指望它跑什么复杂的协议?

我个人习惯把TFTP比作网络启动的“第一块敲门砖”。客户端从网卡启动后,首先通过DHCP拿到IP和TFTP服务器地址,然后就从TFTP下载引导程序。这一步要是挂了,后面全是白搭。所以,TFTP服务器虽然小,但必须稳。

4.1 为什么选择tftp-hpa

Linux下TFTP服务器软件有好几个,比如tftpd、atftpd、dnsmasq自带的TFTP模块。但我为什么推荐tftp-hpa?

原因有三:

  • 稳定:tftp-hpa是H. Peter Anvin维护的,就是那个写了SYSLINUX的大神。他的代码,你想想看,用在PXE场景下是最对口的。
  • 安全:它支持chroot,可以把TFTP根目录限制在某个子目录里,防止路径穿越攻击。
  • 轻量:没有多余的依赖,安装完就能跑,资源占用极低。
我的建议: 如果你在生产环境部署PXE服务器,优先选tftp-hpa。dnsmasq自带的TFTP虽然方便,但功能上还是差一点,特别是并发量上来之后,稳定性不如tftp-hpa。

4.2 安装tftp-hpa

安装过程很简单。以CentOS/RHEL系为例:

# 安装服务端和客户端(客户端用于测试)
yum install -y tftp-server tftp

# 如果是Ubuntu/Debian系
apt-get install -y tftpd-hpa tftp-hpa

安装完成后,你会看到两个关键文件:

  • 服务端程序:通常是 /usr/sbin/in.tftpd
  • 配置文件:CentOS下是 /etc/xinetd.d/tftp(如果通过xinetd管理),或者 /etc/default/tftpd-hpa(Ubuntu下)

我记得有一次在客户现场,装完tftp-hpa后发现服务死活起不来。查了半天,原来是xinetd没装。嗯,这里要注意:如果你用的是CentOS 7及以上,默认可能没有xinetd,需要单独安装:

yum install -y xinetd
systemctl enable xinetd
systemctl start xinetd

4.3 目录结构设计

目录结构设计得好不好,直接影响到后续维护的便利性。我见过不少新手把所有的引导文件、内核、镜像全扔在TFTP根目录下,时间一长,自己都分不清哪个文件是干什么的。

我个人习惯这样设计:

/var/lib/tftpboot/          # TFTP根目录
├── pxelinux.cfg/           # PXE配置文件目录
│   ├── default            # 默认启动配置
│   └── 01-00-1a-2b-3c-4d-5e  # 按MAC地址的个性化配置
├── images/                # 存放各种系统镜像
│   ├── centos7/
│   ├── ubuntu20/
│   └── winpe/
├── kernels/               # 存放内核文件
│   ├── vmlinuz-centos7
│   └── vmlinuz-ubuntu20
├── initrd/                # 存放initrd文件
│   ├── initrd-centos7.img
│   └── initrd-ubuntu20.img
├── boot/                  # 引导加载程序文件
│   ├── pxelinux.0
│   ├── menu.c32
│   ├── ldlinux.c32
│   └── libutil.c32
└── grub/                  # 如果使用GRUB2作为网络引导
    └── grubx64.efi
核心原则: 按功能分类,不要把所有文件平铺在根目录。这样后期添加新系统、排查问题时,一眼就能找到对应文件。

你可能会问:为什么要把pxelinux.0放在boot目录而不是根目录?因为很多BIOS/UEFI固件在PXE启动时,默认会从TFTP根目录请求pxelinux.0或bootx64.efi。如果你把它们放在子目录,需要在DHCP服务器中指定文件名路径。我个人习惯统一放在boot/下,然后在DHCP配置里写清楚路径,这样结构更清晰。

4.4 权限配置

权限配置是很多人容易忽略的点。TFTP服务通常以nobody用户运行,所以它必须对TFTP根目录及其子目录有读取权限。如果需要上传功能,还需要写入权限。

基本权限设置:

# 创建TFTP根目录
mkdir -p /var/lib/tftpboot

# 设置目录归属
chown -R nobody:nobody /var/lib/tftpboot

# 设置目录权限(755表示可读可执行,但不可写)
chmod -R 755 /var/lib/tftpboot

# 如果某些目录需要允许上传(比如存放客户端日志),单独设置
mkdir -p /var/lib/tftpboot/upload
chmod 777 /var/lib/tftpboot/upload
注意: 千万不要把整个TFTP根目录设为777。我曾经在一个项目中看到有人图省事,直接chmod -R 777 /var/lib/tftpboot,结果被攻击者上传了恶意文件。安全无小事,权限能小就小。

另外,SELinux也是个坑。如果你开启了SELinux,需要给TFTP目录打上正确的上下文标签:

# 查看当前标签
ls -Z /var/lib/tftpboot

# 设置标签
semanage fcontext -a -t tftpdir_t "/var/lib/tftpboot(/.*)?"
restorecon -Rv /var/lib/tftpboot

如果不做这一步,你会发现客户端能连接TFTP服务器,但下载文件时一直超时。我在排障课上会专门讲这个,这里先提个醒。

4.5 防火墙配置

TFTP使用UDP端口69。注意,是UDP,不是TCP。很多新手配防火墙时只开了TCP端口,结果TFTP死活不通。

防火墙配置示例:

# firewalld(CentOS 7+)
firewall-cmd --add-port=69/udp --permanent
firewall-cmd --reload

# iptables(CentOS 6及以下)
iptables -A INPUT -p udp --dport 69 -j ACCEPT
service iptables save

# ufw(Ubuntu)
ufw allow 69/udp

这里有个细节:TFTP在传输大文件时,会动态协商一个临时端口(通常是随机高位端口)用于数据传输。如果你在严格防火墙环境下,可能需要开启TFTP连接跟踪模块,让防火墙自动识别并放行这些动态端口。

# 加载nf_conntrack_tftp模块
modprobe nf_conntrack_tftp

# 永久生效(写入配置文件)
echo "nf_conntrack_tftp" >> /etc/modules-load.d/tftp.conf

如果不加载这个模块,客户端下载超过512字节的文件时,会卡在“数据传输中”状态,然后超时。嗯,这个问题我排查过不下十次,每次都是这个原因。

4.6 启动服务与传输测试

配置完成后,启动服务:

# 如果通过xinetd管理
systemctl restart xinetd
systemctl enable xinetd

# 如果作为独立服务(Ubuntu下)
systemctl restart tftpd-hpa
systemctl enable tftpd-hpa

验证服务是否在监听:

netstat -tuln | grep 69
# 输出示例:udp 0 0 0.0.0.0:69 0.0.0.0:*

接下来是最关键的一步——传输测试。我建议用两种方式测试:

  1. 本地测试:在TFTP服务器本机上测试,排除网络因素。
  2. 远程测试:用另一台机器测试,验证防火墙和网络连通性。

本地测试命令:

# 下载测试(从TFTP服务器下载一个文件)
tftp 127.0.0.1
tftp> get boot/pxelinux.0
tftp> quit

# 上传测试(需要上传目录有写权限)
tftp 127.0.0.1
tftp> put test.txt upload/
tftp> quit

远程测试类似,把IP换成服务器实际IP即可。

我的测试习惯: 先下载一个很小的文件(比如pxelinux.0,约40KB),确认基本连通性。然后下载一个稍大的文件(比如内核vmlinuz,几MB),验证大文件传输是否稳定。如果大文件传输失败,十有八九是防火墙没配连接跟踪模块。

4.7 知识体系结构图

下面这张图总结了TFTP服务器搭建的核心流程和关键节点:

TFTP服务器搭建核心流程 安装tftp-hpa 目录结构设计(按功能分类) 权限配置(用户+SELinux) 防火墙配置(UDP 69 + 连接跟踪) 启动服务并验证监听 传输测试(本地+远程) 常见踩坑点 • 防火墙未开UDP 69 • 缺少连接跟踪模块 • SELinux上下文未设置 验证清单 ✓ netstat检查监听 ✓ 小文件下载测试 ✓ 大文件传输测试

4.8 常见问题速查

现象 可能原因 解决思路
连接超时 防火墙未放行UDP 69 检查防火墙规则,添加UDP 69端口
小文件正常,大文件失败 缺少连接跟踪模块 加载nf_conntrack_tftp模块
文件找不到(File not found) 路径错误或权限不足 检查文件路径和目录权限
Permission denied SELinux阻止 检查SELinux上下文或临时关闭测试
上传失败 目录无写权限 设置目录为777或更改属主

好了,TFTP服务器搭建这部分就讲到这里。配置本身不复杂,但细节很多。你按照上面的步骤一步步来,应该不会出大问题。如果遇到奇怪的现象,先检查防火墙,再检查SELinux,这两个是最大的“隐形杀手”。