はじめに
最近、職場のネットワークのリプレイスがあり、その影響からなのか freebsd-update が失敗する現象が発生した。この記事はその現象を確認し、解決するまでのメモである。
#結論
長くなりそうなので、先に結論を書いておく。
今回の原因は、freebsd-update
がダウンロードで使用しているコマンドphttpget
のタイムアウト時間が短いことである。
※ [phttpget.c] (https://github.com/freebsd/freebsd/blob/master/usr.sbin/portsnap/phttpget/phttpget.c) のソースを見ると15秒になっている。
このタイムアウト時間を変更するには、環境変数HTTP_TIMEOUT
で設定する。例えば180秒に指定するには、(Cシェル系の場合)コマンドラインで以下を実行する。
# setenv HTTP_TIMEOUT 180
これで解決。必要であれば、シェルの設定ファイルに書いておきましょう。
#作業メモ
以下は、余談というか、調べた過程をメモしておきます。
色々調べた結果、以下がわかった。
- freebsd-update fetch は成功するが、upgrade は失敗する。
- freebsd-update -v debug upgrade で、進行状況が確認ができる。
- 全てのホストで失敗するわけではない。
- 一番外側のセグメントのホストは失敗しない。
freebsd-update -v debug upgrade -r 11.0-RELEASE
を実行すると、最後に以下のエラーメッセージが表示された。
Fetching 1 metadata files...
/usr/libexec/phttpget update.FreeBSD.org 11.0-RELEASE/amd64/m/4298320cd2fcb7fdeb4d83a040f05290d2d01b920cf06b6d760bc36779e6f18d.gz
phttpget: Connection failure
failed.
コマンドラインから /usr/libexec/phttpget update.FreeBSD.org 11.0-RELEASE/amd64/m/4298320cd2fcb7fdeb4d83a040f05290d2d01b920cf06b6d760bc36779e6f18d.gz
を実行しても同じエラーが発生した、つまりここで問題が発生していることがわかった。
試しに、curlコマンドを使うと、問題は発生せずダウンロードできた。謎。
ここで状況を整理した。
- 特定のネットワークセグメントで問題が発生している。
- おそらくFirewallのポリシーの違いによる影響と仮定した。実際、スルーするようなポリシーを追加すると問題が発生しなくなることは確認できた。
-
curl
では問題なく、phttpget
で問題が発生する。個別の設定なのか、バグなのか...。
Firewallが通信を遮断していると仮定して、ログを探したのだが発見できなかった。そこで tcpdump & Wireshark にてパケットを確認すると、正常にコネクションが切断しているのが確認できた。ということは、Firewallで強制遮断しているのではなく、phttpget でなんらかの原因があって途中で通信を止めていることになる。
やっと、ここで気づくのである。Firewallではなくて、phttpget
でのタイムアウトの問題であることを。そう``HTTP_TIMEOUT`の存在を。気づいてしまえば、簡単なことでした。今回の一番の敗因は新しいFirewallの設定やログの検証に時間が掛かってしまったことかも。