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根目录限制在某个子目录里,防止路径穿越攻击。
- 轻量:没有多余的依赖,安装完就能跑,资源占用极低。
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
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:*
接下来是最关键的一步——传输测试。我建议用两种方式测试:
- 本地测试:在TFTP服务器本机上测试,排除网络因素。
- 远程测试:用另一台机器测试,验证防火墙和网络连通性。
本地测试命令:
# 下载测试(从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即可。
4.7 知识体系结构图
下面这张图总结了TFTP服务器搭建的核心流程和关键节点:
4.8 常见问题速查
| 现象 | 可能原因 | 解决思路 |
|---|---|---|
| 连接超时 | 防火墙未放行UDP 69 | 检查防火墙规则,添加UDP 69端口 |
| 小文件正常,大文件失败 | 缺少连接跟踪模块 | 加载nf_conntrack_tftp模块 |
| 文件找不到(File not found) | 路径错误或权限不足 | 检查文件路径和目录权限 |
| Permission denied | SELinux阻止 | 检查SELinux上下文或临时关闭测试 |
| 上传失败 | 目录无写权限 | 设置目录为777或更改属主 |
好了,TFTP服务器搭建这部分就讲到这里。配置本身不复杂,但细节很多。你按照上面的步骤一步步来,应该不会出大问题。如果遇到奇怪的现象,先检查防火墙,再检查SELinux,这两个是最大的“隐形杀手”。