はじめに
目的
このドキュメントは、OpenSSLのSSL_get_error()関数が返すエラーコード「6」(SSL_ERROR_ZERO_RETURN)について調査した結果を分かりやすくまとめたものです。意味、発生する状況、実際の事例と対処方法、技術的背景を順に解説します。
対象読者
システム管理者、開発者、運用担当者を想定しています。SSL/TLSの基本は知っていると読みやすいですが、専門用語は最小限にして具体例で補足します。
本章の役割
本章では、ドキュメント全体の目的と構成を簡潔に示します。個別の問題解決を急ぐ場合は第4章(実際の事例と対処方法)を先にご覧ください。
ドキュメントの構成(概要)
- 第2章: SSL_get_error() 関数とエラーコード6の意味
- 第3章: エラーコード6が発生する状況
- 第4章: 実際の事例と対処方法
- 第5章: 技術的な背景
本資料は、実務で遭遇しやすいケースを想定して具体的な対処の考え方を提示します。必要に応じてログの見方や接続手順にも触れます。
SSL_GET_ERROR() 関数とエラーコード 6 の意味
SSL_get_error() とは
SSL_get_error() は、OpenSSL の SSL/TLS 通信で読み書き関数が失敗したときに、その原因を判定するための関数です。例えば SSL_read() や SSL_write() が -1 や 0 を返した際に使い、何が起きたかを数値で教えてくれます。専門用語を避けると、問題の種類をラベルで返す診断ツールのようなものです。
使い方のポイント
- 通常は読み書き関数の直後に呼びます。戻り値の状態を見て判断します。
- いくつかのエラーコードがあり、それぞれ対応が異なります。たとえば再試行すべき場合や接続を閉じるべき場合があります。
エラーコード 6 (SSL_ERROR_ZERO_RETURN) の意味
エラーコード 6 は SSL_ERROR_ZERO_RETURN を示します。これは“相手が正常にシャットダウンを行い、もうデータを送らない”という意味です。TCP の接続が突然壊れたわけではなく、TLS レベルで終端手順が完了した状態です。具体的には、相手が「Goodbye(正常終了)」を送ってきたようなイメージです。
例と受け止め方
- サーバがセッションを終了してきた場合、SSL_read() が 0 を返し、SSL_get_error() が 6 を返します。
- 多くのアプリでは接続をそのまま閉じるべきです。再送やリトライを繰り返す必要は通常ありません。
短い対応方針
- SSL_ERROR_ZERO_RETURN を受けたら、セッションは終了済みと判断します。
- ソケットを閉じ、必要なら再接続の処理を行います。
- ログを残しておくと、意図した切断かどうか確認しやすくなります。
この章では基礎的な意味と受け止め方を説明しました。次章では、このコードが実際にどのような状況で現れるかを具体例で見ていきます。
エラーコード 6 が発生する状況
概要
エラーコード 6 は、TLS/SSL 接続が意図的または予期せず中断されたときに発生します。ここでは代表的な発生状況と、それぞれの現場で何が起きているかを具体例とともに説明します。
代表的なケース
- クライアントが正常に切断を開始した場合
-
例: クライアントが SSL_shutdown() を呼び出すと、サーバー側は「グレースフルなシャットダウン」を返す必要があります。サーバーがそれに応答しないか、応答を待たずに接続を閉じるとエラーコード 6 が出ます。
-
ホスト側ソフトウェアがコネクションを中止した場合
-
例: VPN ソフトやプロキシが接続を強制終了すると、SSL 層で中止を検出してエラーコード 6 を返すことがあります。タイムアウトやプロトコルの不整合が原因になることが多いです。
-
ネットワーク機器や中継ソフトが接続を遮断した場合
- 例: ファイアウォールやNAT、負荷分散機器がパケットを破棄すると、TLS ハンドシェイクやシャットダウン手順が途中で止まりエラーになります。
発生時の特徴と確認方法
- ログに “SSL shutdown” や “connection aborted” の記録が残ります。アプリケーションログとシステムログを両方確認してください。
- パケットキャプチャ(tcpdump, Wireshark)で FIN/RST や TLS レコードの終端を確認すると原因が分かることが多いです。
運用上の対処のヒント
- サーバーはクライアントの SSL_shutdown() に対して適切に応答するよう実装を確認してください。
- VPN やプロキシのログも併せて調べ、タイムアウト設定やプロトコル互換性を見直すとトラブルが減ります。
実際の事例と対処方法
事例
FortiClient VPN 7.4などで接続が切断されると、ログに「poll_recv_ssl -> SSL_get_error(): 6」が残ることがあります。これはクライアント側がSSLコネクションを受信できず、既に切断されたことを示します。
基本的な対処手順
- ネットワークの安定性確認
- LANやWi‑Fiの途切れ、回線遅延をpingやトレースルートで調べます。短時間のパケットロスでも切断を誘発します。
- VPNソフトの再起動
- クライアントを完全に終了して再起動します。設定の再読み込みで復旧することが多いです。
- 新しいコネクションの確立
- エラー6は既にコネクションが閉じている状態です。古いセッションを破棄して再接続してください。
環境チェック
- ファイアウォールやNAT: ポートやセッションタイムアウトが切断原因になり得ます。ログやルールを確認します。
- VPNサーバー側ログ: サーバーで切断理由(キック、タイムアウト、証明書エラーなど)を確認します。
アプリケーション側の対策
- 適切なシャットダウン処理を実装することで、クライアント側が正常にセッションを閉じられます。接続失敗時は再試行ロジックとタイムアウトの調整を入れると安定します。
追加の対処
- クライアントソフトやファームウェアを最新に更新する。
- プロファイルを再作成して設定の破損を疑う。
これらを順に試すことで多くのケースで復旧します。問題が続く場合は、ログを添えてネットワーク管理者やベンダーに相談してください。
技術的な背景
概要
OpenSSLの戻り値では、エラーコード6は一般に「コネクションが明示的に終了した」ことを示します。具体的にはTLSレイヤーでの正常な終了(close_notify)や、相手がソケットを切ったことによる終端を表します。これは一時的な読み書き待ちではありません。
TLSと正規の終了手順
TLSは接続をただ切るのではなく、close_notifyという終了通知を交換する設計です。片方が通知を送ると、相手はそれを受け取ったことを示し、両方向で終了することで「正常終了」となります。
TCPとの関係
下位のTCPがRSTやFINで切れると、SSL層はそれを受けて読み込みでEOFを返します。OpenSSLではこの状況でSSL_readが0を返し、SSL_get_errorはコード6(SSL_ERROR_ZERO_RETURN)を返します。これは「もうデータは来ない」という意味です。
開発者が取るべき扱い
- EOFとして扱い、ソケットとSSL構造体をきれいに閉じる。再試行は意味がありません。
- 再接続が必要なら新しいハンドシェイクで再度コネクションを作る。
- ログに相手のIPやタイムスタンプを残すと原因追跡に役立ちます。
まとめのポイント
このエラーは「一時的なブロック」ではなく「接続状態の変化」を示します。適切にクリーンアップし、必要なら再接続の設計に切り替えてください。












