强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 对比

维度TFTPFTPHTTP
端口69/UDP20-21/TCP80/TCP
认证
加密FTPSHTTPS
复杂度极低中等中等
速度慢(小文件)
防火墙友好
适用场景网络引导文件管理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 小结

功能关键配置项说明
启用 TFTPenable-tftp激活 TFTP 服务
根目录tftp-root=TFTP 文件存放路径
BIOS 引导dhcp-boot=pxelinux.0PXELINUX 引导
UEFI 引导dhcp-boot=grubx64.efiGRUB EFI 引导
安全tftp-secure限制根目录访问
多引导dhcp-match + dhcp-boot区分 BIOS/UEFI

5.11 扩展阅读