CentOS 7マシンでPXEブートサーバーをセットアップしているときに、TFTPで奇妙な問題が発生しました。タイムアウトの問題が発生しない限り、TFTPサーバーからファイルを取得できません。起動プロセスは、DHCPサーバーからIPアドレスとファイル名を正しく取得するまでに完了しました。ただし、ブートファイルをTFTPサーバーから取得する場合は、「TFTPオープンタイムアウト」メッセージが表示されます。ローカルコンピューターからPXEサーバーへのTFTP接続を手動で行うと、すぐにサーバーにアクセスできます。しかし、「get pxelinux.0」コマンドを試してみると、別のタイムアウトメッセージが表示されます。ファイアウォールが正しく設定されていて、ファイアウォールを完全にオフにしても違いはありません。 SeLinuxも無効になっています。ポート69でtcpdumpを作成すると、次のメッセージが表示されます。
12:34:33.477401 IP 172.16.1.202.ah-esp-encap > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:35.481131 IP 172.16.1.202.acp-port > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:39.490793 IP 172.16.1.202.msync > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:45.477712 IP 172.16.1.202.gxs-data-port > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:53.441801 IP 172.16.1.202.vrtl-vmf-sa > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:35:03.384065 IP 172.16.1.202.newlixengine > tools.dmz.tuxme.dk.tftp: 32 RRQ "pxelinux.0" octet blksize 1456
12:35:39.414843 IP 172.16.1.202.newlixconfig > tools.dmz.tuxme.dk.tftp: 32 RRQ "pxelinux.0" octet blksize 1456
12:36:51.422568 IP 172.16.1.202.tsrmagt > tools.dmz.tuxme.dk.tftp: 32 RRQ "pxelinux.0" octet blksize 1456
12:38:39.406732 IP 172.16.1.202.tpcsrvr > tools.dmz.tuxme.dk.tftp: 32 RRQ "pxelinux.0" octet blksize 1456
残念ながら、システムログには何も役に立ちません。
Jan 15 13:13:19 tools xinetd[6993]: EXIT: tftp status=67 pid=7954 duration=0(sec)
Jan 15 13:13:21 tools xinetd[6993]: START: tftp pid=7955 from=172.16.1.202
Jan 15 13:13:21 tools in.tftpd[7955]: no user tftp: Success
Jan 15 13:13:21 tools xinetd[6993]: EXIT: tftp status=67 pid=7955 duration=0(sec)
Jan 15 13:13:25 tools xinetd[6993]: START: tftp pid=7956 from=172.16.1.202
Jan 15 13:13:25 tools in.tftpd[7956]: no user tftp: Success
Jan 15 13:13:25 tools xinetd[6993]: EXIT: tftp status=67 pid=7956 duration=0(sec)
Jan 15 13:13:31 tools xinetd[6993]: START: tftp pid=7957 from=172.16.1.202
Jan 15 13:13:31 tools in.tftpd[7957]: no user tftp: Success
/ var/lib/tftpbootディレクトリへの権限は0755です。
これが私のセットアップファイルです:
/etc/xinetd.d/tftp:
service tftp
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -c -v -u tftp -p -U 117 -s /var/lib/tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
tcpdump
の出力には要求のみが含まれ、応答はまったく含まれていないようです。これが実際に起こっていることである場合、タイムアウトエラーが予想されます。
XinetdのTFTP構成の_server_args
_行には、_-u tftp
_があります。これは、_in.tftpd
_にユーザーtftp
として実行するように指示します。それを考慮して、_in.tftpd
_によってログに記録されたこのメッセージは重要かもしれません:
_Jan 15 13:13:21 tools in.tftpd[7955]: no user tftp: Success
_
「nousertftp」と表示されます。 tftp
ユーザーアカウントは実際にシステムに存在しますか?
ログメッセージの最後にあるSuccess
を理解するには、Cプログラミングの知識が少し必要です。これは、おそらくperror()
を呼び出して、終了する前に必要なクリーンアップを実行する、最小限のエラー処理関数に由来する可能性があります。
perror()
関数は、呼び出し元からメッセージを受け取り、errno
変数の現在の値に対応する標準エラーメッセージを追加します。以前のシステムコールが失敗した状況で使用するように設計されています。カスタムメッセージは、エラーが発生したときにプログラムが何をしていたかを説明する必要があり、標準メッセージは、発生した問題のタイプを明確にする必要があります。
ただし、プログラマーがエラー処理機能を使用して、他の方法でキャッチされたエラーを報告した場合、標準のエラーメッセージ部分はSuccess
と表示されます。
私の推測では、_in.tftpd
_プロセスはxinetd
によって開始され、ユーザーtftp
に切り替える準備をして、そのようなユーザーが存在しないことを発見します。したがって、_in.tftpd
_プロセスはそのログメッセージを出力し、クライアントに何も送信せずに終了します。
最後に誤解を招く「成功」が付いた簡潔なメッセージは、「唯一のツールがハンマーである場合、すべてを釘として扱う傾向がある」という古い概念の例です。この場合、プログラマーは、出力形式が完全に適合しない状況で、おそらく唯一のエラー処理機能を使用しています。
また、これらのリクエストは少し奇妙に見えます。
_12:34:33.477401 IP 172.16.1.202.ah-esp-encap > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:35.481131 IP 172.16.1.202.acp-port > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:39.490793 IP 172.16.1.202.msync > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:45.477712 IP 172.16.1.202.gxs-data-port > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
12:34:53.441801 IP 172.16.1.202.vrtl-vmf-sa > tools.dmz.tuxme.dk.tftp: 27 RRQ "pxelinux.0" octet tsize 0
_
_tsize 0
_は、クライアントが合計0バイトのファイルサイズのTFTP転送を予期していることを示します。
UEFI PXE仕様は、UEFIバージョン2.3程度に存在していたため、DHCPサーバーがPXEクライアントにロードする予定のファイルのサイズを通知する必要があることをご存知ですか? ISC DHCPサーバーを使用している場合、必要なオプションは次のように指定できます。
_option boot-size <size value>;
_
_<size value>
_は、バイト単位のブートファイルのサイズを512で割ってから、切り上げます。