Dnsmasq 服务搭建完全教程 / 第 05 章:TFTP 配置
第 05 章:TFTP 配置
5.1 TFTP 基础概念
5.1.1 什么是 TFTP
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种轻量级文件传输协议,主要用于网络设备的引导和配置文件分发。
| 特性 | 说明 |
|---|---|
| 传输层 | UDP 端口 69 |
| 认证 | 无 |
| 目录列表 | 不支持 |
| 文件写入 | 协议支持但 Dnsmasq 仅提供只读 |
| 块大小 | 默认 512 字节 |
| 最大文件 | 无限制(协议层面) |
| 典型用途 | PXE 引导、路由器固件升级、配置分发 |
5.1.2 TFTP 与 FTP/HTTP 对比
| 维度 | TFTP | FTP | HTTP |
|---|---|---|---|
| 端口 | 69/UDP | 20-21/TCP | 80/TCP |
| 认证 | 无 | 有 | 有 |
| 加密 | 无 | FTPS | HTTPS |
| 复杂度 | 极低 | 中等 | 中等 |
| 速度 | 慢(小文件) | 快 | 快 |
| 防火墙友好 | 差 | 差 | 好 |
| 适用场景 | 网络引导 | 文件管理 | Web 服务 |
5.2 Dnsmasq TFTP 基本配置
5.2.1 启用 TFTP 服务
# /etc/dnsmasq.d/20-tftp.conf
# 启用 TFTP
enable-tftp
# TFTP 根目录
tftp-root=/var/lib/tftpboot
# 安全设置:只允许访问根目录下的文件
tftp-secure
# 设置 TFTP 文件权限(创建时的 umask)
tftp-unique-root=ip # 为每个客户端创建唯一文件名
5.2.2 创建 TFTP 目录
# 创建目录
sudo mkdir -p /var/lib/tftpboot/{pxelinux.cfg,images,grub}
# 设置权限
sudo chmod -R 755 /var/lib/tftpboot
sudo chown -R nobody:nogroup /var/lib/tftpboot
# 验证目录
ls -la /var/lib/tftpboot/
5.2.3 测试 TFTP 服务
# 安装 TFTP 客户端
sudo apt install tftp-hpa # Debian/Ubuntu
sudo yum install tftp # CentOS/RHEL
# 测试上传/下载
echo "test file" > /tmp/test.txt
tftp 192.168.1.1 -c put test.txt
tftp 192.168.1.1 -c get test.txt
# 或使用 curl 测试下载
curl tftp://192.168.1.1/test.txt
5.3 PXE 网络引导
5.3.1 PXE 引导流程
1. 客户端发送 DHCP Discover
2. Dnsmasq 回复 DHCP Offer(包含 IP + TFTP 服务器地址 + 启动文件名)
3. 客户端通过 TFTP 下载启动文件(pxelinux.0 / grubx64.efi)
4. 启动加载器读取配置文件
5. 加载内核(vmlinuz)和初始内存盘(initrd)
6. 启动操作系统安装/运行
┌──────────┐ DHCP/TFTP ┌──────────┐
│ 客户端 │←──────────────────→│ Dnsmasq │
│ (PXE ROM)│ │ DHCP+TFTP│
└────┬─────┘ └──────────┘
│
│ 1. DHCP Discover
│←── DHCP Offer (IP + TFTP地址 + 启动文件)
│ 2. TFTP: 读取 pxelinux.0
│ 3. TFTP: 读取 pxelinux.cfg/default
│ 4. TFTP: 读取 vmlinuz + initrd
│ 5. 引导 Linux
5.3.2 Syslinux/PXELINUX 引导配置
步骤 1:准备引导文件
# 安装 syslinux(提供 PXE 引导文件)
sudo apt install syslinux syslinux-common pxelinux
# 复制引导文件到 TFTP 目录
sudo cp /usr/lib/PXELINUX/pxelinux.0 /var/lib/tftpboot/
sudo cp /usr/lib/syslinux/modules/bios/{ldlinux.c32,libutil.c32,menu.c32,libcom32.c32} /var/lib/tftpboot/
# 验证文件
ls -la /var/lib/tftpboot/
步骤 2:创建 PXE 菜单配置
sudo mkdir -p /var/lib/tftpboot/pxelinux.cfg
sudo tee /var/lib/tftpboot/pxelinux.cfg/default <<'EOF'
DEFAULT menu.c32
MENU TITLE PXE Network Boot Menu
PROMPT 0
TIMEOUT 100
LABEL ubuntu2204
MENU LABEL Install Ubuntu 22.04 LTS
KERNEL images/ubuntu2204/vmlinuz
INITRD images/ubuntu2204/initrd
APPEND ip=dhcp url=http://192.168.1.1/ubuntu-22.04-live-server-amd64.iso autoinstall ds=nocloud-net
LABEL debian12
MENU LABEL Install Debian 12
KERNEL images/debian12/vmlinuz
INITRD images/debian12/initrd
APPEND priority=critical url=http://192.168.1.1/debian-preseed.cfg
LABEL centos9
MENU LABEL Install CentOS Stream 9
KERNEL images/centos9/vmlinuz
INITRD images/centos9/initrd
APPEND inst.repo=http://192.168.1.1/centos9/ inst.ks=http://192.168.1.1/centos9-ks.cfg
LABEL memtest
MENU LABEL Memory Test (memtest86+)
KERNEL images/memtest86+
LABEL local
MENU LABEL Boot from local disk
LOCALBOOT 0
EOF
步骤 3:下载安装文件
# Ubuntu 22.04
sudo mkdir -p /var/lib/tftpboot/images/ubuntu2204
cd /tmp
wget https://releases.ubuntu.com/22.04/ubuntu-22.04.4-live-server-amd64.iso
sudo mount -o loop ubuntu-22.04.4-live-server-amd64.iso /mnt
sudo cp /mnt/casper/vmlinuz /var/lib/tftpboot/images/ubuntu2204/
sudo cp /mnt/casper/initrd /var/lib/tftpboot/images/ubuntu2204/
sudo umount /mnt
# Debian 12
sudo mkdir -p /var/lib/tftpboot/images/debian12
cd /tmp
wget https://deb.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux
wget https://deb.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz
sudo cp linux /var/lib/tftpboot/images/debian12/vmlinuz
sudo cp initrd.gz /var/lib/tftpboot/images/debian12/initrd
步骤 4:配置 Dnsmasq 支持 PXE
sudo tee /etc/dnsmasq.d/20-pxe.conf <<'EOF'
# DHCP 接口
interface=eth1
bind-interfaces
# DHCP 地址池
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,12h
# 启用 TFTP
enable-tftp
tftp-root=/var/lib/tftpboot
tftp-secure
# BIOS PXE 引导
dhcp-boot=pxelinux.0,,192.168.1.1
# 权威 DHCP
dhcp-authoritative
log-dhcp
EOF
步骤 5:测试
# 重启 Dnsmasq
sudo systemctl restart dnsmasq
# 用 QEMU 测试 PXE 引动(无需物理机器)
sudo apt install qemu-system-x86
qemu-system-x86_64 -m 2048 -net nic -net user -boot n
5.3.3 UEFI 引导配置
现代计算机使用 UEFI 引导,需要不同的启动文件:
# 安装 GRUB EFI 引导文件
sudo apt install grub-efi-amd64-signed shim-signed
# 复制 EFI 引导文件
sudo cp /usr/lib/shim/shimx64.efi.signed.latest /var/lib/tftpboot/shimx64.efi
sudo cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /var/lib/tftpboot/grubx64.efi
# 创建 GRUB 配置
sudo tee /var/lib/tftpboot/grub/grub.cfg <<'EOF'
set timeout=5
set default=0
menuentry "Install Ubuntu 22.04" {
linux images/ubuntu2204/vmlinuz ip=dhcp url=http://192.168.1.1/ubuntu-22.04-live-server-amd64.iso autoinstall
initrd images/ubuntu2204/initrd
}
menuentry "Install Debian 12" {
linux images/debian12/vmlinuz priority=critical
initrd images/debian12/initrd
}
menuentry "Boot from local disk" {
exit
}
EOF
更新 Dnsmasq 配置,区分 BIOS 和 UEFI:
sudo tee /etc/dnsmasq.d/21-pxe-uefi.conf <<'EOF'
# 区分 BIOS 和 UEFI 客户端
dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:efi32,option:client-arch,6
dhcp-match=set:efi64,option:client-arch,7
dhcp-match=set:efi64,option:client-arch,9
dhcp-match=set:efiarm,option:client-arch,11
# BIOS 引导
dhcp-boot=tag:bios,pxelinux.0,,192.168.1.1
# UEFI x86-64 引导
dhcp-boot=tag:efi64,grubx64.efi,,192.168.1.1
# UEFI ARM64 引导
dhcp-boot=tag:efiarm,grubaa64.efi,,192.168.1.1
# 启用 TFTP
enable-tftp
tftp-root=/var/lib/tftpboot
tftp-secure
EOF
5.4 网络操作系统安装
5.4.1 Ubuntu 自动化安装(Autoinstall)
# 创建 autoinstall 配置
sudo mkdir -p /var/www/html/autoinstall
sudo tee /var/www/html/autoinstall/user-data <<'EOF'
#cloud-config
autoinstall:
version: 1
locale: zh_CN.UTF-8
keyboard:
layout: cn
network:
version: 2
ethernets:
ens33:
dhcp4: true
identity:
hostname: ubuntu-server
username: admin
password: "$6$rounds=4096$..." # mkpasswd --method=sha-512
ssh:
install-server: true
storage:
layout:
name: lvm
packages:
- vim
- htop
- net-tools
EOF
sudo touch /var/www/html/autoinstall/meta-data
更新 PXE 菜单:
LABEL ubuntu-auto
MENU LABEL Auto Install Ubuntu 22.04
KERNEL images/ubuntu2204/vmlinuz
INITRD images/ubuntu2204/initrd
APPEND ip=dhcp autoinstall ds=nocloud-net\;s=http://192.168.1.1/autoinstall/
5.4.2 Debian 预置安装(Preseed)
sudo tee /var/www/html/debian-preseed.cfg <<'EOF'
# 语言和地区
d-i debian-installer/locale string zh_CN.UTF-8
d-i keyboard-configuration/xkb-keymap select cn
# 网络
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string debian-server
# 磁盘分区
d-i partman-auto/method string lvm
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-auto-lvm/guided_size string max
# 用户
d-i passwd/root-login boolean false
d-i passwd/user-fullname string Admin
d-i passwd/username string admin
d-i passwd/user-password-crypted password $6$rounds=4096$...
# 软件包
tasksel tasksel/first multiselect ssh-server
d-i pkgsel/include string vim htop net-tools
# GRUB
d-i grub-installer/only_debian boolean true
d-i grub-installer/bootdev string /dev/sda
EOF
5.4.3 CentOS Kickstart
sudo tee /var/www/html/centos9-ks.cfg <<'EOF'
# 安装选项
install
url --url="http://192.168.1.1/centos9/"
lang zh_CN.UTF-8
keyboard cn
network --bootproto=dhcp --device=eth0 --onboot=yes
rootpw --iscrypted $6$rounds=4096$...
firewall --disabled
selinux --permissive
timezone Asia/Shanghai --utc
# 磁盘分区
clearpart --all --initlabel
autopart --type=lvm
# 软件包
%packages
@core
vim-enhanced
htop
net-tools
%end
# 安装后脚本
%post
echo "Installation completed" > /root/install.log
%end
# 引导加载器
bootloader --location=mbr
EOF
5.5 无盘工作站
5.5.1 无盘工作站架构
┌────────────┐ PXE/TFTP/NFS ┌────────────────┐
│ 无盘客户端 │←──────────────→│ Dnsmasq 服务器 │
│ │ │ DHCP + TFTP │
└────────────┘ │ + NFS Root │
└────────────────┘
5.5.2 配置 NFS 根文件系统
# 安装 NFS 服务器
sudo apt install nfs-kernel-server
# 创建根文件系统
sudo mkdir -p /export/diskless/rootfs
sudo debootstrap --arch=amd64 jammy /export/diskless/rootfs http://mirrors.aliyun.com/ubuntu
# 配置 NFS 导出
echo "/export/diskless/rootfs *(rw,no_root_squash,async,no_subtree_check)" | sudo tee -a /etc/exports
sudo exportfs -rv
# 配置无盘引导内核参数
# 在 PXE 菜单中添加:
LABEL diskless
MENU LABEL Diskless Workstation
KERNEL images/ubuntu2204/vmlinuz
INITRD images/ubuntu2204/initrd
APPEND root=/dev/nfs nfsroot=192.168.1.1:/export/diskless/rootfs ip=dhcp rw
5.5.3 为无盘客户端配置独立 hosts
# 为每个无盘客户端分配固定 IP 和主机名
sudo tee /etc/dnsmasq.d/22-diskless.conf <<'EOF'
dhcp-host=00:0c:29:aa:bb:01,192.168.1.201,diskless-01,infinite
dhcp-host=00:0c:29:aa:bb:02,192.168.1.202,diskless-02,infinite
dhcp-host=00:0c:29:aa:bb:03,192.168.1.203,diskless-03,infinite
EOF
5.6 固件升级
5.6.1 路由器固件升级
# 部分嵌入式设备支持通过 TFTP 恢复/升级固件
# 将固件放入 TFTP 根目录
sudo cp firmware.bin /var/lib/tftpboot/
# 设备通常在启动时尝试从 TFTP 下载固定名称的文件
# 例如 OpenWrt 路由器会查找:
# - tp_recovery.bin (TP-Link)
# - openwrt.bin
5.7 TFTP 安全配置
# /etc/dnsmasq.d/23-tftp-security.conf
# 限制 TFTP 只读访问
tftp-secure
# 限制 TFTP 只在特定接口可用
# (通过 bind-interfaces 和 interface 控制)
# 为不同客户端提供不同的文件
tftp-unique-root=mac # 基于 MAC 地址
# tftp-unique-root=ip # 基于 IP 地址
# 使用 tftp-lowercase 兼容大小写不敏感的客户端
tftp-lowercase
# 限制最大文件大小(Dnsmasq 2.85+)
# tftp-max=50M
警告:TFTP 不提供认证和加密,不应用于传输敏感文件。在生产环境中,TFTP 应仅在内网使用,并通过防火墙限制访问。
5.8 TFTP 性能调优
5.8.1 提高传输速度
# Dnsmasq 的 TFTP 实现较简单,不支持 blocksize 扩展
# 对于大型文件,建议使用 HTTP 替代 TFTP
# 方案 1:混合方案 - 小文件用 TFTP,大文件用 HTTP
# PXE 引导文件(pxelinux.0, vmlinuz, initrd)通过 TFTP
# 安装镜像通过 HTTP
# 方案 2:使用 atftpd 替代 Dnsmasq 的 TFTP
# sudo apt install atftpd
# 支持更大的 blocksize,传输速度更快
5.8.2 HTTP 引导替代方案
UEFI HTTP Boot 是 TFTP 的现代替代方案:
# 配置 Dnsmasq 为 UEFI 客户端提供 HTTP 引导
dhcp-match=set:httpclient,option:client-arch,9
dhcp-boot=tag:httpclient,http://192.168.1.1/grub/grubx64.efi,,192.168.1.1
# 在 HTTP 服务器上托管引导文件
# nginx 或 apache 的文档根目录指向 /var/lib/tftpboot/
5.9 完整 TFTP + PXE 配置示例
# /etc/dnsmasq.d/20-pxe-full.conf
# === DHCP 基础 ===
interface=eth1
bind-interfaces
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,12h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,192.168.1.1
dhcp-authoritative
# === TFTP 配置 ===
enable-tftp
tftp-root=/var/lib/tftpboot
tftp-secure
# === PXE 引导 - BIOS ===
dhcp-match=set:bios,option:client-arch,0
dhcp-boot=tag:bios,pxelinux.0,,192.168.1.1
# === PXE 引导 - UEFI 64位 ===
dhcp-match=set:efi64,option:client-arch,7
dhcp-match=set:efi64,option:client-arch,9
dhcp-boot=tag:efi64,grubx64.efi,,192.168.1.1
# === 日志 ===
log-dhcp
log-queries
log-facility=/var/log/dnsmasq/dnsmasq.log
5.10 小结
| 功能 | 关键配置项 | 说明 |
|---|---|---|
| 启用 TFTP | enable-tftp | 激活 TFTP 服务 |
| 根目录 | tftp-root= | TFTP 文件存放路径 |
| BIOS 引导 | dhcp-boot=pxelinux.0 | PXELINUX 引导 |
| UEFI 引导 | dhcp-boot=grubx64.efi | GRUB EFI 引导 |
| 安全 | tftp-secure | 限制根目录访问 |
| 多引导 | dhcp-match + dhcp-boot | 区分 BIOS/UEFI |