web-dev-qa-db-ja.com

Linux:クライアントのハローが遅れたためSSLハンドシェイクが遅い

すべて同時に影響を受けるプロキシのクラスターに影響を与える問題を調査しているときに、SSL接続の確立に奇妙な動作が見られました。

症状は、影響が発生したときに発信HTTPS要求が通常よりも遅いことです。私は、SSLハンドシェイクの終了が遅いことにピン留めしました。 HTTPリクエスト/接続は同じように影響を受けません。

この問題は、TCP 3ウェイハンドシェイクの終了とプロキシによる_Client Hello_の送信の間の遅延によってアウトバウンド接続で発生しているようです。その後、ハンドシェイクが完了します。通常は遅延なし。

トラフィックキャプチャの例を次に示します。

_api.Twitter.com_(2.4秒の遅延)へ: api.Twitter.com

_graph.facebook.com_(28.4秒の遅延)へ: graph.facebook.com

2番目の例の再送信を使用しても、_Client Hello_パケットが送信されるのにそれほど長い時間はかからなかったはずです。

いくつかの事実/考慮事項:

  • この問題は、1日の特定の時間(約1000時間と1700時間)に一時的に発生し、すべてのホストに影響し、約30分で消えます。後で同時に
  • これは外部の原因(おそらくネットワーク)を示しますが、tcpdumpの出力はローカルサーバーに責任があるようです
  • CPU、負荷、メモリ、およびその他すべての監視対象パフォーマンスインジケータは、その時点では正常です。
  • すべてのSSLリモートホストに影響します
  • 接続にランダムに影響し、一部は正常に動作しますが、多くは非常に低速です
  • スループット(ハンドシェイク後)は影響を受けていないようです
  • 問題が解決すると、同じリモートホストへのSSL接続は一貫して高速になります
  • テストはcurlと_openssl s_client connect_で実行され、同じ結果が得られました

説明が必要なもの:

  1. ローカル側でこのような遅延を引き起こしている可能性があるのは何ですか?
  2. Wiresharkが私をだましている可能性はありますか?
  3. 遅延の原因をさらにトラブルシューティングするために、他にどのようなパフォーマンス指標/統計/コマンドを調べることができますか?
  4. そのような動作を正当化できるネットワーク要素(MTU、受信バッファー、断片化)はありますか?
  5. サーバー外部のネットワークの問題であるかどうかを明確にする証拠を見つけるにはどうすればよいですか?

ソフトウェアバージョン

  • Red Hat Enterprise Linux Serverリリース5.11(Tikanga)
  • OpenSSL 0.9.8e-fips-rhel5 2008年7月1日
  • カーネル2.6.18-416.el5#1 SMP Wed Oct 26 12:04:18 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux

編集:strace情報

以下の回答で推奨されているように、いくつかのstraceを実行し、次の遅い呼び出しをキャッチしました。

_strace -T -o output.strace openssl s_client -connect 104.244.42.66:443 </dev/null

connect(3, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("104.244.42.66")}, 16) = 0 <2.266597>
poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}]) <2.387366>
write(3, "\26\3\1\0S\1\0\0O\3\1X\342\24\3556c\354\270T\302\225[\236\317\327\305\205r\177\t/"..., 88) = 88 <0.000034>
read(3, "\26\3\1\0001\2\0", 7)          = 7 <2.556229>
read(3, "\0-\3\1\332\37\254+\240\320\236qA\375\275L\23l\340\355\205x\264\274\273\213\377\323&\345\307O"..., 47) = 47 <0.000011>
read(3, "\26\3\1\v\273", 5)             = 5 <0.000007>
(...)
read(3, "\24\3\1\0\1", 5)               = 5 <2.223115>
_

poll()呼び出しはDNSの逆引き参照であり、次のことを実行します。

_sendto(4, "\3623\1\0\0\1\0\0\0\0\0\0\00266\00242\003244\003104\7in-ad"..., 44, MSG_NOSIGNAL, NULL, 0) = 44 <0.000157>
_

同じトレース内の他のそのようなpoll()呼び出しは迅速です。

1

Straceを使用してcurlコマンドを実行して、どのシステムコールで「ハング」するかを確認できます。これらのことは、DNSルックアップ(または逆DNSルックアップ)に関連していることがあります。

strace curl https://[...]
3
Nils