TFTP サーバーを使う前に
ルータの設定ファイルの保存や OS イメージの転送など、機器が TFTP しか話せない場面で使います。この記事ではサーバーに tftpd-hpa、クライアントに tftp-hpa を使います。
| 編集するファイル | 用途 |
|---|---|
/etc/default/tftpd-hpa | 公開ディレクトリ、待ち受けアドレス、動作オプション |
/etc/hosts.deny | 接続元の制限(TCP Wrappers) |
TFTP(RFC 1350)の要点は次のとおりです。
| 項目 | 内容 |
|---|---|
| トランスポート | UDP。最初の要求はサーバーの 69 番に送り、転送はサーバーが新しく選んだポートから行う |
| パケット | RRQ(読み出し要求)/ WRQ(書き込み要求)/ DATA / ACK / ERROR |
| 転送モード | netascii(テキスト。改行は CR LF で送る)/ octet(バイト列をそのまま送る) |
導入状況を確認する
サーバーもクライアントも入っていません。 設定ファイルも公開ディレクトリもまだありません。
kazulog@sv1:~$ apt-cache policy tftpd-hpa | head -3
tftpd-hpa:
Installed: (none)
Candidate: 5.3+20251209-2
kazulog@sv1:~$ ls -l /etc/default/tftpd-hpa /srv/tftp 2>&1
ls: cannot access '/etc/default/tftpd-hpa': No such file or directory
ls: cannot access '/srv/tftp': No such file or directory
kazulog@sv1:~$ sudo ss -ulnp 'sport = :69'; echo "ss rc=$?"
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ss rc=0kazulog@sv2:~$ which tftp; echo "which rc=$?"
which rc=1
kazulog@sv2:~$ apt-cache policy tftp-hpa | head -3
tftp-hpa:
Installed: (none)
Candidate: 5.3+20251209-2TFTP サーバーを導入する
sudo apt install -y tftpd-hpainetd などのスーパーサーバーは使わず、tftpd-hpa.service が単独で UDP 69 番を待ち受けます。スーパーサーバーの仕組みはinetd(スーパーサーバー)設定で解説しています。
導入すると /etc/default/tftpd-hpa が作られます。設定はこの4行だけです。
kazulog@sv1:~$ sudo apt install -y tftpd-hpa | cat
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Solving dependencies...
Installing:
tftpd-hpa
Suggested packages:
pxelinux
Summary:
Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 96
Download size: 44.5 kB
Space needed: 128 kB / 63.1 GB available
Get:1 http://archive.ubuntu.com/ubuntu resolute/main amd64 tftpd-hpa amd64 5.3+20251209-2 [44.5 kB]
Preconfiguring packages ...
Fetched 44.5 kB in 1s (40.5 kB/s)
Selecting previously unselected package tftpd-hpa.
(Reading database ... 91400 files and directories currently installed.)
Preparing to unpack .../tftpd-hpa_5.3+20251209-2_amd64.deb ...
Unpacking tftpd-hpa (5.3+20251209-2) ...
Setting up tftpd-hpa (5.3+20251209-2) ...
Created symlink '/etc/systemd/system/multi-user.target.wants/tftpd-hpa.service' → '/usr/lib/systemd/system/tftpd-hpa.service'.
Processing triggers for man-db (2.13.1-1build1) ...
Scanning processes...
Scanning linux images...
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
kazulog@sv1:~$ cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"
kazulog@sv1:~$ ls -ld /srv/tftp
drwxr-xr-x 2 root nogroup 4096 Sep 12 10:01 /srv/tftp
kazulog@sv1:~$ systemctl status tftpd-hpa --no-pager | head -7 | cat
● tftpd-hpa.service - tftpd-hpa TFTP Server
Loaded: loaded (/usr/lib/systemd/system/tftpd-hpa.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-09-12 10:01:24 JST; 6s ago
Invocation: 4d07df8db779481dbcc25f5fda912011
Docs: man:in.tftpd
Process: 2706 ExecStart=/usr/sbin/in.tftpd --listen --user $TFTP_USERNAME --address $TFTP_ADDRESS $TFTP_OPTIONS $TFTP_DIRECTORY (code=exited, status=0/SUCCESS)
Main PID: 2707 (in.tftpd)
kazulog@sv1:~$ sudo ss -ulnp 'sport = :69'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
UNCONN 0 0 0.0.0.0:69 0.0.0.0:* users:(("in.tftpd",pid=2707,fd=4))
UNCONN 0 0 [::]:69 [::]:* users:(("in.tftpd",pid=2707,fd=5)) | 変数 | 既定値 | 意味 |
|---|---|---|
TFTP_USERNAME | tftp | in.tftpd を動かす利用者 |
TFTP_DIRECTORY | /srv/tftp | 公開するディレクトリ |
TFTP_ADDRESS | :69 | 待ち受けるアドレスとポート。アドレスを省くと全アドレス |
TFTP_OPTIONS | --secure | 追加のオプション |
--secure は起動時にルートディレクトリを TFTP_DIRECTORY へ移すオプション(chroot)で、クライアントはディレクトリを付けずにファイル名だけを指定します。/srv/tftp は root の持ち物なので、既定のままではアップロードできません。
設定を変えたら sudo systemctl restart tftpd-hpa で反映します。
ファイルを取得する
サーバーの /srv/tftp にファイルを置きます。
kazulog@sv1:~$ echo "hello from tftp server sv1" | sudo tee /srv/tftp/hello.txt
hello from tftp server sv1
kazulog@sv1:~$ sudo ls -l /srv/tftp/
total 4
-rw-r--r-- 1 root root 27 Sep 12 10:01 hello.txtクライアントを導入して取得します。-c はコマンドを1つだけ実行して終了し、-v は転送の詳細を表示します。
kazulog@sv2:~$ sudo apt install -y tftp-hpa | cat
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Solving dependencies...
Installing:
tftp-hpa
Summary:
Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 96
Download size: 19.8 kB
Space needed: 55.3 kB / 63.1 GB available
Get:1 http://archive.ubuntu.com/ubuntu resolute/main amd64 tftp-hpa amd64 5.3+20251209-2 [19.8 kB]
Fetched 19.8 kB in 1s (24.6 kB/s)
Selecting previously unselected package tftp-hpa.
(Reading database ... 91448 files and directories currently installed.)
Preparing to unpack .../tftp-hpa_5.3+20251209-2_amd64.deb ...
Unpacking tftp-hpa (5.3+20251209-2) ...
Setting up tftp-hpa (5.3+20251209-2) ...
Processing triggers for man-db (2.13.1-1build1) ...
Scanning processes...
Scanning linux images...
Running kernel seems to be up-to-date.
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
kazulog@sv2:~$ cd /tmp && tftp -v 192.168.100.10 -c get hello.txt
Connected to 192.168.100.10 (192.168.100.10), port 69
getting from 192.168.100.10:hello.txt to hello.txt [netascii]
Received 28 bytes in 0.1 seconds [2524 bit/s]
kazulog@sv2:/tmp$ cat /tmp/hello.txt
hello from tftp server sv1tftp-hpa クライアントの既定の転送モードは netascii です。 27 バイトのファイルが 28 バイトで届いているのは、改行(LF)を CR LF にして送るためです。受け取った側で LF に戻すので、保存されたファイルは元と同じです。
アップロードを許可する(/etc/default/tftpd-hpa)
既定では、サーバーに既にあるファイルへの上書きしか許可されていません。
kazulog@sv2:~$ echo "uploaded from sv2" > /tmp/upload.txt
kazulog@sv2:~$ cd /tmp && tftp -v 192.168.100.10 -c put upload.txt
Connected to 192.168.100.10 (192.168.100.10), port 69
putting upload.txt to 192.168.100.10:upload.txt [netascii]
Error code 1: File not found/etc/default/tftpd-hpa を編集し、TFTP_OPTIONS に --create を足します。
sudo vi /etc/default/tftpd-hpa# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"kazulog@sv1:~$ cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"
kazulog@sv1:~$ sudo systemctl restart tftpd-hpa
kazulog@sv1:~$ ls -ld /srv/tftp
drwxr-xr-x 2 root nogroup 4096 Sep 12 10:01 /srv/tftpこれだけではまだ失敗します。 公開ディレクトリが root の持ち物のままだからです。
kazulog@sv2:~$ echo "uploaded from sv2" > /tmp/upload.txt
kazulog@sv2:~$ cd /tmp && tftp -v 192.168.100.10 -c put upload.txt
Connected to 192.168.100.10 (192.168.100.10), port 69
putting upload.txt to 192.168.100.10:upload.txt [netascii]
Error code 0: Request failedディレクトリの所有者を tftp(TFTP_USERNAME の利用者)にすると、アップロードできます。
kazulog@sv1:~$ sudo chown tftp:tftp /srv/tftp
kazulog@sv1:~$ ls -ld /srv/tftp
drwxr-xr-x 2 tftp tftp 4096 Sep 12 10:01 /srv/tftpkazulog@sv2:~$ echo "uploaded from sv2" > /tmp/upload.txt
kazulog@sv2:~$ cd /tmp && tftp -v 192.168.100.10 -c put upload.txt
Connected to 192.168.100.10 (192.168.100.10), port 69
putting upload.txt to 192.168.100.10:upload.txt [netascii]
Sent 19 bytes in 0.1 seconds [1441 bit/s]待ち受けアドレスを限定する(/etc/default/tftpd-hpa)
TFTP_ADDRESS にアドレスを書くと、そのアドレスだけで待ち受けます。IPv6 アドレスは [2001:db8:100::10]:69 のように角括弧で囲みます。
sudo vi /etc/default/tftpd-hpa# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.10:69"
TFTP_OPTIONS="--secure --create"アップロードされたファイルは誰でも読み書きできる権限(666)で作られ、待ち受けは1行だけになります。
kazulog@sv1:~$ sudo ls -l /srv/tftp/
total 8
-rw-r--r-- 1 root root 27 Sep 12 10:01 hello.txt
-rw-rw-rw- 1 tftp tftp 18 Sep 12 10:02 upload.txt
kazulog@sv1:~$ cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.10:69"接続元を制限する(/etc/hosts.deny)
in.tftpd は TCP Wrappers(libwrap)を組み込んでいるので、/etc/hosts.deny で接続元を拒否できます。デーモン名は in.tftpd です。
sudo vi /etc/hosts.deny# TFTP は 192.168.100.20 からの接続を拒否する
in.tftpd: 192.168.100.20kazulog@sv1:~$ ldd /usr/sbin/in.tftpd | grep libwrap
libwrap.so.0 => /usr/lib/x86_64-linux-gnu/libwrap.so.0 (0x00007cfa15a18000)
kazulog@sv1:~$ cat /etc/hosts.deny
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID
# TFTP は 192.168.100.20 からの接続を拒否する
in.tftpd: 192.168.100.20拒否した要求には ERROR を返さず、黙って捨てます。 クライアントは要求を再送し続け、最後に Transfer timed out. で終わります。
kazulog@sv2:~$ cd /tmp && timeout 40 tftp -v 192.168.100.10 -c get hello.txt hello-denied.txt; echo "rc=$?"
Connected to 192.168.100.10 (192.168.100.10), port 69
getting from 192.168.100.10:hello.txt to hello-denied.txt [netascii]
Transfer timed out.
rc=69拒否はログに残ります。ただし from の後ろに出るのは接続元ではなく、サーバー自身のアドレス(192.168.100.10)です。 tftp-hpa 5.3 の in.tftpd は、判定には接続元のアドレスを使い、ログにはサーバー側のアドレスを書くためです。
kazulog@sv1:~$ sudo journalctl -u tftpd-hpa --no-pager -n 3
Sep 12 10:02:55 sv1 in.tftpd[5396]: connection refused from 192.168.100.10設定ファイルの最終状態
ここまでの設定が入った状態です。触ったファイルは /etc/default/tftpd-hpa と /etc/hosts.deny の2つだけです。
kazulog@sv1:~$ cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.10:69"
TFTP_OPTIONS="--secure --create"
kazulog@sv1:~$ cat /etc/hosts.deny
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID
# TFTP は 192.168.100.20 からの接続を拒否する
in.tftpd: 192.168.100.20
kazulog@sv1:~$ sudo ls -l /srv/tftp/
total 8
-rw-r--r-- 1 root root 27 Sep 12 10:01 hello.txt
-rw-rw-rw- 1 tftp tftp 18 Sep 12 10:02 upload.txt
kazulog@sv1:~$ systemctl is-enabled tftpd-hpa; systemctl is-active tftpd-hpa
enabled
active
kazulog@sv1:~$ sudo ss -ulnp 'sport = :69'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
UNCONN 0 0 192.168.100.10:69 0.0.0.0:* users:(("in.tftpd",pid=4631,fd=4)) | ファイル | 変更内容 |
|---|---|
/etc/default/tftpd-hpa | TFTP_OPTIONS に --create を追加、TFTP_ADDRESS を 192.168.100.10:69 に変更 |
/etc/hosts.deny | 末尾に in.tftpd: 192.168.100.20 を追記 |
/srv/tftp | 所有者を tftp:tftp に変更(アップロードを受けるため) |
ルータの設定を保存する
IOS XE のルータ R1 から、copy コマンドで running-config をアップロードします。確認の問い合わせを省くため、file prompt quiet を設定した状態で実行しています。
--secure はサーバーを /srv/tftp に chroot するので、URL のパスはファイル名だけにします。 ディレクトリ名を付けると %Error opening ... (No such file or directory) になります。
R1#copy running-config tftp://192.168.100.10/r1-confg
!!
4964 bytes copied in 0.597 secs (8315 bytes/sec)kazulog@sv1:~$ sudo ls -l /srv/tftp/
total 16
-rw-r--r-- 1 root root 27 Sep 12 10:01 hello.txt
-rw-rw-rw- 1 tftp tftp 4964 Sep 12 10:05 r1-confg
-rw-rw-rw- 1 tftp tftp 18 Sep 12 10:02 upload.txt
kazulog@sv1:~$ sudo head -3 /srv/tftp/r1-confg
!
! Last configuration change at 01:04:58 UTC Sat Sep 12 2026削除する
削除すると /etc/default/tftpd-hpa は消えますが、/srv/tftp と中のファイル、tftp 利用者は残ります。
kazulog@sv1:~$ sudo apt purge -y tftpd-hpa | cat
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Solving dependencies...
REMOVING:
tftpd-hpa*
Summary:
Upgrading: 0, Installing: 0, Removing: 1, Not Upgrading: 96
Freed space: 128 kB
(Reading database ... 91411 files and directories currently installed.)
Removing tftpd-hpa (5.3+20251209-2) ...
Processing triggers for man-db (2.13.1-1build1) ...
(Reading database ... 91399 files and directories currently installed.)
Purging configuration files for tftpd-hpa (5.3+20251209-2) ...
kazulog@sv1:~$ dpkg -l tftpd-hpa 2>&1 | tail -1
dpkg-query: no packages found matching tftpd-hpa
kazulog@sv1:~$ ls -l /etc/default/tftpd-hpa 2>&1
ls: cannot access '/etc/default/tftpd-hpa': No such file or directory
kazulog@sv1:~$ sudo ls -ld /srv/tftp 2>&1
drwxr-xr-x 2 tftp tftp 4096 Sep 12 10:05 /srv/tftp
kazulog@sv1:~$ getent passwd tftp
tftp:x:103:109:tftp daemon:/srv/tftp:/usr/sbin/nologin
kazulog@sv1:~$ sudo ss -ulnp 'sport = :69'; echo "ss rc=$?"
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ss rc=0キャプチャーで中身を見る
sv1 とスイッチの間のリンクで、sv2 との UDP をキャプチャーしました。取得・失敗した2回のアップロード・成功したアップロード・拒否されたときの再送が1本に入っています。
$ tshark -r ubuntu-tftp.pcap -n -t ad
1 2026-09-12 10:01:45.203039 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
2 2026-09-12 10:01:45.209098 192.168.100.10 → 192.168.100.20 TFTP 74 Data Packet, Block: 1 (last)
3 2026-09-12 10:01:45.209729 192.168.100.20 → 192.168.100.10 UDP 46 54144 → 55822 Len=4
4 2026-09-12 10:02:07.874218 192.168.100.20 → 192.168.100.10 TFTP 64 Write Request, File: upload.txt, Transfer type: netascii
5 2026-09-12 10:02:07.880190 192.168.100.10 → 192.168.100.20 TFTP 61 Error Code, Code: File not found, Message: File not found
6 2026-09-12 10:02:13.525002 192.168.100.20 → 192.168.100.10 TFTP 64 Write Request, File: upload.txt, Transfer type: netascii
7 2026-09-12 10:02:13.532589 192.168.100.10 → 192.168.100.20 TFTP 61 Error Code, Code: Not defined, Message: Request failed
8 2026-09-12 10:02:19.359314 192.168.100.20 → 192.168.100.10 TFTP 64 Write Request, File: upload.txt, Transfer type: netascii
9 2026-09-12 10:02:19.367159 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 0
10 2026-09-12 10:02:19.367998 192.168.100.20 → 192.168.100.10 UDP 65 52988 → 54084 Len=23
11 2026-09-12 10:02:19.369136 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 1
12 2026-09-12 10:02:50.855073 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
13 2026-09-12 10:02:55.856019 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
14 2026-09-12 10:03:00.856469 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
15 2026-09-12 10:03:05.856777 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
16 2026-09-12 10:03:10.858100 192.168.100.20 → 192.168.100.10 TFTP 63 Read Request, File: hello.txt, Transfer type: netascii
$ tshark -r ubuntu-tftp.pcap -n -V -O tftp -Y 'frame.number == 2'
Frame 2: Packet, 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: 52:54:00:b7:4d:fd, Dst: 52:54:00:ba:01:74
Internet Protocol Version 4, Src: 192.168.100.10, Dst: 192.168.100.20
User Datagram Protocol, Src Port: 55822, Dst Port: 54144
Trivial File Transfer Protocol
Opcode: Data Packet (3)
[Destination File: hello.txt]
[Read Request in frame 1]
Block: 1
[Full Block Number: 1]
Data (28 bytes)
$ tshark -r ubuntu-tftp-no2.pcap -n -x
0000 52 54 00 ba 01 74 52 54 00 b7 4d fd 08 00 45 00 RT...tRT..M...E.
0010 00 3c 53 dc 00 00 40 11 dd 65 c0 a8 64 0a c0 a8 .<S...@..e..d...
0020 64 14 da 0e d3 80 00 28 08 c3 00 03 00 01 68 65 d......(......he
0030 6c 6c 6f 20 66 72 6f 6d 20 74 66 74 70 20 73 65 llo from tftp se
0040 72 76 65 72 20 73 76 31 0d 0a rver sv1..
$ tshark -r ubuntu-tftp.pcap -n -Y 'tftp.opcode == 5' -T fields -e frame.number -e tftp.error.code -e tftp.error.message
5 1 File not found
7 0 Request failed
$ tshark -r ubuntu-tftp.pcap -n -t ad -Y 'frame.number >= 8 && frame.number <= 11'
8 2026-09-12 10:02:19.359314 192.168.100.20 → 192.168.100.10 TFTP 64 Write Request, File: upload.txt, Transfer type: netascii
9 2026-09-12 10:02:19.367159 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 0
10 2026-09-12 10:02:19.367998 192.168.100.20 → 192.168.100.10 UDP 65 52988 → 54084 Len=23
11 2026-09-12 10:02:19.369136 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 1
$ tshark -r ubuntu-tftp.pcap -n -Y 'frame.number >= 12' -T fields -e frame.number -e frame.time_delta_displayed -e udp.srcport -e udp.dstport -e tftp.source_file
12 45348 69 hello.txt要求はサーバーの 69 番宛てですが、応答はサーバーが選んだ別のポートから返ります(No.1 は 69 番宛て、No.2 は 55822 番から)。
$ tshark -r ubuntu-tftp.pcap -n -V -O tftp -Y 'frame.number == 2'
Frame 2: Packet, 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: 52:54:00:b7:4d:fd, Dst: 52:54:00:ba:01:74
Internet Protocol Version 4, Src: 192.168.100.10, Dst: 192.168.100.20
User Datagram Protocol, Src Port: 55822, Dst Port: 54144
Trivial File Transfer Protocol
Opcode: Data Packet (3)
[Destination File: hello.txt]
[Read Request in frame 1]
Block: 1
[Full Block Number: 1]
Data (28 bytes)netascii なので、データの末尾が 0d 0a(CR LF)になっています。
$ tshark -r ubuntu-tftp-no2.pcap -n -x
0000 52 54 00 ba 01 74 52 54 00 b7 4d fd 08 00 45 00 RT...tRT..M...E.
0010 00 3c 53 dc 00 00 40 11 dd 65 c0 a8 64 0a c0 a8 .<S...@..e..d...
0020 64 14 da 0e d3 80 00 28 08 c3 00 03 00 01 68 65 d......(......he
0030 6c 6c 6f 20 66 72 6f 6d 20 74 66 74 70 20 73 65 llo from tftp se
0040 72 76 65 72 20 73 76 31 0d 0a rver sv1..失敗した2回は、エラー番号が違います。
$ tshark -r ubuntu-tftp.pcap -n -Y 'tftp.opcode == 5' -T fields -e frame.number -e tftp.error.code -e tftp.error.message
5 1 File not found
7 0 Request failed成功したアップロードは WRQ → ACK(Block 0)→ DATA → ACK(Block 1)と進みます。
$ tshark -r ubuntu-tftp.pcap -n -t ad -Y 'frame.number >= 8 && frame.number <= 11'
8 2026-09-12 10:02:19.359314 192.168.100.20 → 192.168.100.10 TFTP 64 Write Request, File: upload.txt, Transfer type: netascii
9 2026-09-12 10:02:19.367159 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 0
10 2026-09-12 10:02:19.367998 192.168.100.20 → 192.168.100.10 UDP 65 52988 → 54084 Len=23
11 2026-09-12 10:02:19.369136 192.168.100.10 → 192.168.100.20 TFTP 46 Acknowledgement, Block: 1拒否されたときは、同じ送信元ポートからの要求が5秒おきに5回並び、サーバーからは何も返りません。
$ tshark -r ubuntu-tftp.pcap -n -Y 'frame.number >= 12' -T fields -e frame.number -e frame.time_delta_displayed -e udp.srcport -e udp.dstport -e tftp.source_file
12 45348 69 hello.txt
13 5.000946000 45348 69 hello.txt
14 5.000450000 45348 69 hello.txt
15 5.000308000 45348 69 hello.txt
16 5.001323000 45348 69 hello.txt検証環境と実行ログ
CML 上に Ubuntu 26.04 LTS Server 2台と IOS XE のルータ1台を置いて採取しました。Ubuntu のディスクは wipe した直後の状態から始めています(前の検証で入れたパッケージが残っていると手順が再現しないため)。
sv1 sv2 R1
ens3 192.168.100.10/24 ens3 192.168.100.20/24 Gi2 192.168.100.1/24
tftpd-hpa (UDP 69) tftp-hpa IOS XE 17.03.08a
| | |
+--------- LAB-SW ----------+---------------------------+
^ このリンクでキャプチャー(sv2 との UDP のみ)キャプチャー全体のファイルです。
TFTP 通信のキャプチャー(ubuntu-tftp.pcap)| 手順 | sv1 | sv2 | R1 |
|---|---|---|---|
| 初期状態(wipe 直後) | show / conf / log | show / conf / log | — |
| 導入と設定ファイルの確認 | show / conf / log | — | — |
| ファイルを置いて取得 | show / conf / log | show / conf / log | — |
| 既定の設定でアップロード | — | show / conf / log | — |
| –create を足す | show / conf / log | show / conf / log | — |
| 所有者を変える | show / conf / log | show / conf / log | — |
| 待ち受けアドレスの限定 | show / conf / log | — | — |
| 接続元の制限 | show / conf / log | show / conf / log | — |
| 拒否のログ | show / conf / log | — | — |
| 設定ファイルの最終状態 | show / conf / log | — | — |
| ルータからの保存 | show / conf / log | — | show |
| 削除(最終状態) | show / conf / log | — | — |
| キャプチャーの解析 | tshark | — | — |
参考リンク
RFC 1350 - The TFTP Protocol (Revision 2)
関連記事
- Ubuntu 26.04 LTS Server のホスト名の変更(hostnamectl)
- Ubuntu 26.04 LTS Server のパッケージ更新(apt update / upgrade)
- Ubuntu 26.04 LTS Server のタイムゾーン設定と時刻同期
- Ubuntu 26.04 LTS Server のユーザー作成と sudo 権限の設定
- Ubuntu 26.04 LTS Server の SSH サーバー設定(公開鍵認証)
- Ubuntu 26.04 LTS Server の telnet サーバー設定
- Ubuntu 26.04 LTS Server の inetd(スーパーサーバー)設定
- Ubuntu 26.04 LTS Server の TFTP サーバー設定(tftpd-hpa)
- Ubuntu 26.04 LTS Server の FTP サーバー設定(vsftpd)
- Ubuntu 26.04 LTS Server の syslog サーバー設定(rsyslog)
- Ubuntu 26.04 LTS Server のサービス管理(systemctl)とログ確認(journalctl)
- Ubuntu 26.04 LTS Server の自動更新設定(unattended-upgrades)
- Ubuntu 26.04 LTS Server の初期設定を自動化する(cloud-init)
- Ubuntu 26.04 LTS Server のカーネルパラメータ設定(sysctl)
- Ubuntu 26.04 LTS Server のネットワーク設定(Netplan)
- Ubuntu 26.04 LTS Server の名前解決設定(systemd-resolved)
- Ubuntu 26.04 LTS Server の NTP 同期先の変更(chrony)
- Ubuntu 26.04 LTS Server のスタティックルート設定(Netplan)
- neovim 公式サイトから最新バージョンをインストールする手順 Ubuntu 26.04 LTS Server