TFTP 协议应用及原理

协议特点

  • TFTP(Trivial File Transfer Protocol)
  • 使用 UDP 作为传输协议,区别于 FTP 使用 TCP 端口21。
  • 可访问远程服务器,上传/下载文件及发送邮件,传输数据字节为8位。
  • 不支持
    • list 文件夹
    • 用户鉴权及加密功能。
  • 最大支持 4GB 大小文件

运用

  • 常部署于 PXE 环境传输文件。
    • 部署 tftp 服务完成 pxe 装机流程
    • 可配合 python pytftp 库动态生成 pxe 相关配置文件
  • 不推荐部署于公共网络,适用于私有网络小文件传输。

传输机制

  1. 以 Read/Write 报文发起传输请求,返回 Data/Ack 建立传输。
  2. Data 报文未填满 Data 字段最大长度时,则后续还有数据,反之则传输完成。
  3. 单次报文传输时,可能会在网络中丢失。报文接收方等待超时后,会重传上一份报文,以触发发送方重传。
  4. 发送完最后一个 Ack 报文时,发送端会等待一段时间,如果又收到 data,则会重发 Ack 以保证结束传输。(即使最后 data 发送方未收到 Ack,超时且重传结束后,依旧会判定传输成功,关闭连接)。
  5. 发送 Error 报文会提前结束传输,不会重传和等待响应。因此需要超时机制来触发 Error。
  6. 为什么不直接基于 tcp 协议呢

抓包

我们以抓包的方式,来展示一次成功的文件传输。

Tips:

  1. 69 端口为服务端用来监听 tftp 请求的固定端口。服务端确定操作合法后,会以一个新端口应答,避免影响其它请求的响应。
  2. tftp 中传输的端口被称为 TID(transfer identifiers)。
    成功传输小文件
# 在服务端抓取 udp 包,不能只抓 69 端口
sudo tshark -i bond0 -f 'udp'


# 抓包使用 -V 参数,还可见以下网络头部
# Ethernet layer2: 14 bytes+padding
# IP HEADER: 20 bytes
# UDP HEADER: 8 bytes
# TFTP

# 从 hosta 访问 hostb:69 下载文件
# hosta:10.0.0.94
# hostb:10.0.0.125
curl tftp:hostb/netboot.seed.yml

# 抓包结果
    # Read Request, 其中附带 option 额外参数
    # 10.0.0.94:50504 -> 10.0.0.125:69
    1 0.000000000    10.0.0.94 → 10.0.0.125   TFTP 97 Read Request, File: netboot.seed.yml, Transfer type: octet, tsize=0, blksize=512, timeout=6
    # 此处服务端用新的端口响应会话
    # 10.0.0.125:52483 -> 10.0.0.94:50504
    2 0.007549332   10.0.0.125 → 10.0.0.94    TFTP 67 Option Acknowledgement, blksize=512, tsize=5072
    # 10.0.0.94:50504 -> 10.0.0.125:52483
    3 0.007736889    10.0.0.94 → 10.0.0.125   TFTP 60 Acknowledgement, Block: 0
    # 开始传输文件(558bytes 去掉头, tftp 段总大小 516bytes,data 段大小为 512bytes)
    4 0.007877492   10.0.0.125 → 10.0.0.94    TFTP 558 Data Packet, Block: 1
    5 0.008066622    10.0.0.94 → 10.0.0.125   TFTP 60 Acknowledgement, Block: 1
    # 省略中间若干个 block
...........
    # 结束传输(data 段小于 512bytes)
   22 0.009778727   10.0.0.125 → 10.0.0.94    TFTP 510 Data Packet, Block: 10 (last)
   23 0.009928020    10.0.0.94 → 10.0.0.125   TFTP 60 Acknowledgement, Block: 10

协议报文

报文以操作码为标识,可分为以下五种数据报文:

  1. Read request (RRQ)
  2. Write request (WRQ)
  3. Data (DATA)
  4. Acknowledgment (ACK)
  5. Error (ERROR)

ACK & ERROR 响应 WRQ & DATA

DATA & ERROR 响应 RRQ & DATA

ERROR 响应任何其他类型

协议头

 ---------------------------------------------------
|  Local Medium  |  Internet  |  Datagram  |  TFTP  |
 ---------------------------------------------------

Read/Write Req

报文格式

2 bytes     string    1 byte     string   1 byte
------------------------------------------------
| Opcode |  Filename  |   0  |    Mode    |   0  |
------------------------------------------------

报文字段

  • Opcode: 操作码 1/2 为读写报文类型
  • Filename: 字符串类型,以 1byte 长度的 0 字节结尾。
  • Mode:
    • Netascii: ASCII 的一种制定格式,定义于 RFC764
    • Octet: 8位字节,传输文件字节数据
    • Mail: 以 Netascii 传输邮件内容,且 Filename 字段应标识接受者地址

Ps: 传输均以读写请求作为开端。

Data

报文格式

2 bytes     2 bytes      n bytes
----------------------------------
| Opcode |   Block #  |   Data    |
----------------------------------

报文字段

  • Opcode: 操作码 3 为数据报文类型
  • Block: 从 1 开始递增的数据块编码,用于识别新/旧数据块
  • Data:
    • 0~511bytes 则表示该数据块为最后一块,文件传输结束
    • 512bytes,则数据未传输结束
  • Data 总大小扩增:
    • RFC 1350 基础定义 Data 长度为 512
      • 512 bytes/block x 65535 blocks = 32 MB
    • RFC 2348 将 Data 长度扩增至 65535,以适应更大的文件
      • 65535 bytes/block x 65535 blocks = 4 GB
  • 响应 RRQ

Acknowledgment

报文格式

2 bytes     2 bytes
---------------------
| Opcode |   Block #  |
---------------------

报文字段

  • Opcode: 操作码 4 为响应报文类型
  • Block 响应块编号:
    • 响应WRQ: Block 0
    • 响应DATA: Block 编号

Error

报文格式

2 bytes     2 bytes       string    1 byte
----------------------------------------
| Opcode |  ErrorCode |   ErrMsg   |   0  |
----------------------------------------

报文字段

  • Opcode: 操作码 5 为响应报文类型
  • Error:
    • Value Meaning
    • 0 Not defined, see error message (if any).
    • 1 File not found.
    • 2 Access violation.
    • 3 Disk full or allocation exceeded.
    • 4 Illegal TFTP operation.
    • 5 Unknown transfer ID.
    • 6 File already exists.
    • 7 No such user.

你可能感兴趣的:(TFTP 协议应用及原理)