Skip to content

SSL Provider エラー: SQL Server接続時の証明書検証失敗の解決方法

問題の概要

Ubuntu環境でODBC Driver 18 for SQL Serverを使用してSQL Serverに接続しようとすると、次のエラーが発生することがあります:

[Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate]

このエラーは、自己署名証明書を使用しているSQL Serverインスタンスに接続する際に、クライアント側で証明書の検証が失敗したことを示しています。

原因

ODBC Driver 18 for SQL Serverはデフォルトで暗号化接続を要求し、信頼された証明書機関(CA)によって発行された証明書を検証します。しかし、以下の状況ではこのエラーが発生します:

  • 自己署名証明書を使用している
  • 開発環境などで正式な証明書を使用していない
  • OpenSSLのセキュリティレベル設定が厳しすぎる

解決方法

方法1: 接続文字列にTrustServerCertificateを追加

接続文字列に TrustServerCertificate=yes を追加することで、サーバー証明書の検証を省略できます。

php
$sql_info = array(
    'UID' => 'your_sql_user',
    'PWD' => 'your_password',
    'Database' => 'your_DB_name',
    'TrustServerCertificate' => 1,
);

sqlsrv_connect('your_host_or_ip', $sql_info);
python
conn_str = f'DRIVER=ODBC Driver 18 for SQL Server;SERVER={server};DATABASE={database};UID={username};PWD={password};TrustServerCertificate=yes'
vb.net
Dim conStr As String = "Driver={ODBC Driver 18 for SQL Server};Server=your_servername;Database=your_databasename;Uid=your_username;Pwd=your_password;TrustServerCertificate=yes;"

WARNING

この設定は開発環境でのみ使用し、本番環境では適切な証明書を設定することを推奨します。

方法2: 暗号化を無効にする

接続文字列に Encrypt=no を追加することで、暗号化接続そのものを無効にすることもできます。

python
conn_str = f'DRIVER=ODBC Driver 18 for SQL Server;SERVER={server};DATABASE={database};UID={username};PWD={password};Encrypt=no'
php
'trust_server_certificate' => 'true',
'encrypt' => 'false'

DANGER

この方法は通信が平文で行われるため、セキュリティ上のリスクがあります。テスト環境以外での使用は避けてください。

方法3: OpenSSLのセキュリティレベルを調整

Ubuntu 22.04以降では、OpenSSLのデフォルトセキュリティレベルが2に設定されているため、接続に問題が発生することがあります。

bash
sudo nano /etc/ssl/openssl.cnf

以下の設定を変更します:

ini
[system_default_sect]
# 変更前
# CipherString = DEFAULT:@SECLEVEL=2

# 変更後
CipherString = DEFAULT:@SECLEVEL=0

変更後、サービスを再起動してください。

方法4: SQL Serverコマンドラインツールを使用する場合

sqlcmdを使用する場合は、-Cオプションを追加してサーバー証明書を信頼します。

bash
sqlcmd -S <server> -U <username> -P <password> -C

または、localhostの代わりにIPアドレスを使用してみてください:

bash
sqlcmd -S 127.0.0.1 -U sa -P 'YourPassword' -C

フレームワーク別の設定

Laravel (PHP)

config/database.phpで以下の設定を追加:

php
'sqlsrv' => [
    'driver' => 'sqlsrv',
    'host' => env('DB_HOST', 'localhost'),
    'port' => env('DB_PORT', '1433'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
    'trust_server_certificate' => 'true'
]

Django (mssql-django)

python
DATABASES['default'] = {
    'ENGINE': 'mssql',
    'NAME': 'your_db_name',
    'USER': 'your_username',
    'PASSWORD': 'your_password',
    'HOST': 'your_host',
    'OPTIONS': {
        'driver': 'ODBC Driver 18 for SQL Server',
        'extra_params': "Encrypt=no"
    },
}

SQLAlchemy (Python)

python
import sqlalchemy

conn_string = ...
engine = sqlalchemy.create_engine(
    conn_string,
    connect_args = {
        "TrustServerCertificate": "yes"
    }, echo=False)

ドライバーの確認

Linux環境では、正しいODBCドライバーがインストールされていることを確認してください:

bash
odbcinst -q -d

Windowsでは DRIVER={SQL Server} で動作する場合でも、Linuxでは DRIVER={ODBC Driver 18 for SQL Server} のように明示的にバージョンを指定する必要があります。

まとめ

SSL証明書検証エラーは、開発環境でよく発生する問題です。セキュリティ要件に応じて適切な解決方法を選択してください:

  • 開発環境:TrustServerCertificate=yes または Encrypt=no
  • 本番環境:正式な証明書の取得と適切な設定
  • プラットフォーム間の差異:ドライバー指定の確認とOpenSSL設定の調整

これらの解決策を適用することで、ODBC Driver 18 for SQL Serverを使用した接続問題を解決できます。