Known Issue: Microsoft JDBC Driver for SQL Server を使った接続が「SQL Server が不完全な応答を返しました。」のエラーで失敗する。

 

SQL Developer Support Escalation Engineer

高橋 理香

 

みなさん、こんにちは。

最近お問い合わせいただくことが多い事象がありますので、今回はその内容をご紹介したいと思います。

 

事象

Java アプリケーションから Microsoft JDBC Driver for SQL Server を使用して SQL Server に接続するアプリケーションがある。このアプリケーションからの接続時に以下のエラーが発生することがある。

com.microsoft.sqlserver.jdbc.SQLServerException: ドライバが SSL (Secure Sockets Layer) 暗号化による SQL Server への安全な接続を確立できませんでした。エラー: SQL Server が不完全な応答を返しました。接続が閉じられました。。

 

対象環境/アプリケーション

上記事象が発生する条件として以下の特徴があります。

  • Windows Server 2012 R2 に Windows Server 2012 R2 Update1 (2919355) をインストールした環境上で動作する Java アプリケーションから Microsoft JDBC Driver for SQL Server を利用している。
  • Windows Server 2008 R2 に KB361608 または KB3172605 をインストールした環境上の JDK/JRE バージョン 6 で動作する Java アプリケーションから Microsoft JDBC Driver for SQL Server を利用している。

 

エラーが示す意味

JDBC ドライバからの SQL Server への接続では内部的に SSL 暗号化を利用していますが、それが失敗したことを示しているのが「ドライバが SSL (Secure Sockets Layer) 暗号化による SQL Server への安全な接続を確立できませんでした」というメッセージです。また、「SQL Server が不完全な応答を返しました。」のメッセージは、SQL Server が受信したパケットに含まれるデータが本来想定される長さよりも短いために、"不完全である" と判断したと応答を返したことを示しています。

つまり、SSL 暗号化の処理の一環でクライアントからパケットを送信したものの、それが想定よりも短いために SQL Server で受け付けることができず、接続処理が失敗したことを意味します。

 

エラー発生の原因

Windows Server 2012 R2 以前の OS では、対象環境に示したような OS の更新プログラムによって Diffie-Hellman (DH) の暗号化スイートが追加されますが、それらの暗号化スイートが利用された場合に OS の問題によって 1 バイトが省略される不具合が存在することが判明しました。この不具合によって、クライアントから送信するパケットが 1バイト短くなり、SQL Server が不完全であると判断してエラーを返すに至ります。

 

エラーの対処方法

追加される暗号化スイートに起因した事象であるため、これらが使われないようクライアント環境を構成することが対処となります。具体的には以下の通りです。

 

A. Windows Server 2012 R2 Update1 (2919355) をアンインストールする。

B. KB 361608 や KB 3172605 をアンインストールする。(Windows Server 2008 R2 もしくは Windows 7 の場合)

C. Windows 10 TH2 以降, Windows Server 2016 の OS にアップグレードする。

D. DH を使わないように暗号化スイートを構成する。

 

更新プログラムのアンインストールや OS のアップグレードは運用環境維持の都合等で困難なケースが多いのではないかと思いますので、その場合には上記の D の構成変更を対処としてご検討ください。構成変更の手順は以下の通りです。

    1. クライアントで、レジストリ エディター (regedit.exe) を管理者として起動します。
    2. 次のレジストリを右クリックし、[修正] を選択します。 

      キー:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002]名前: Functions種類: REG_MULTI_SZ

    3. 次の 2 つの暗号スイートが追加されたものですので、これらを削除します。※ バックアップが必要な場合には、事前に当該キーをエクスポートします。 

      TLS_DHE_RSA_WITH_AES_128_CBC_SHATLS_DHE_RSA_WITH_AES_256_CBC_SHA※もしも上記以外に _DHE_ を含むエントリがある場合にはそちらも削除します。

      以下などは削除します。
      TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
      TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
      TLS_DHE_DSS_WITH_AES_256_CBC_SHA
      TLS_DHE_DSS_WITH_AES_128_CBC_SHA
       
      以下などは残します。
      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256
      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384
      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384
    4. 設定を反映させるために OS を再起動します。

 

なお、暗号化スイート構成変更も困難な場合には、大変恐れ入りますが、接続の再試行 (リトライ) の実装を検討ください。本事象は 256 回に 1回の頻度で発生する事象ですので、再試行により接続が成功する事を期待できます。最近では Azure 上の SQL Database や SQL Data Warehouse に対してアクセスする場合には、接続のリトライを推奨しており、また、その実装例なども Web サイトで各種紹介しております。オンプレミス上の SQL Server への接続の場合にも同様の実装を行っていただくことで、今回の事象にも対応できるアプリケーションとなります。