ASP.NET×MySQLのSSL/TLS接続:Encrypt/TrustServerCertificateの“option not supported”解決とFortify対策

ASP.NET から MySQL へ TLS 化した接続を行う際、SQL Server 向けの接続文字列プロパティ Encrypt と TrustServerCertificate をそのまま指定して「option not supported」と表示されてしまう――。本記事はその原因と正しい置き換え、セキュリティスキャン(Fortify など)で落ちないための実践手順を、.NET コード例・環境別のサンプル・検証チェックリストまで含めて体系的に解説します。

目次

症状と背景:「option not supported」が出る理由

ASP.NET(.NET)アプリから MySQL に接続する際に、以下のような接続文字列を指定すると接続失敗し、デバッガやログで option not supported と表示されることがあります。

Encrypt=yes;TrustServerCertificate=yes

このエラーは「プロバイダが知らない接続文字列キーが渡された」ことを示す一般的なメッセージです。Encrypt と TrustServerCertificate は SQL Server(System.Data.SqlClient / Microsoft.Data.SqlClient)専用のキーであり、MySQL の .NET コネクタではサポートされていません。MySQL における TLS 制御は SslMode、証明書関連は SslCa(またはコネクタ依存の同等キー)など、別の名前で指定します。

結論:MySQL では「Encrypt」「TrustServerCertificate」を使わない

以下の表のとおり、SQL Server 用のキーは MySQL では無効です。MySQL 固有のキーへ置き換えましょう。

誤った設定正しい設定例補足
Encrypt=yesSslMode=Required
(フォールバック許容なら Preferred)
Encrypt は SQL Server 専用。MySQL では SslMode を使用
TrustServerCertificate=yesSslCa=/path/to/ca-cert.pem
(検証しない場合は指定不要)
MySQL でサーバ証明書を信頼させるには CA 証明書を明示する
(任意)Trusted_Connection=no―(削除)Windows 認証専用の項目で MySQL には効果なし

完成形サンプル(Web.config / app.config 例)

<add
  key="app"
  value="server=server001;port=3306;database=db;
         uid=readonly;pwd=readonly;
         SslMode=Required;
         SslCa=/etc/ssl/certs/ca-cert.pem" />

MySQL の TLS オプションを正しく理解する

MySQL の .NET 接続では、概ね下記の SslMode が使われます。値の意味を誤解しないことが、セキュリティスキャン通過の近道です。

SslMode意味利用時の注意
None平文接続(TLS 無効)本番・社外ネットワークでは不可
PreferredTLS を優先するが失敗時は平文にフォールバック安全とは言い難い。検証環境限定
RequiredTLS を必須化。ただしサーバ証明書は検証しない暗号化のみ。MITM 耐性が弱く Fortify で指摘されやすい
VerifyCATLS 必須 + 証明書を CA で検証(ホスト名の一致は任意)CA 証明書の配置・指定が必要
VerifyFullTLS 必須 + 証明書検証 + ホスト名一致を要求最も厳格。Fortify 対策で第一候補

Fortify スキャン合格のためのポイント

  1. 資格情報をハードコーディングしない
    パスワードや証明書パスは 環境変数・ユーザーシークレット・クラウドのシークレットストア(例:Key Vault 等)に移行し、ログやリポジトリに残さない。
  2. TLS 必須化
    SslMode=Required 以上を徹底。より厳格にするなら VerifyCA / VerifyFull を採用し、CA 証明書を配布して検証させる。
  3. 自己署名の取り扱い
    自己署名のまま Required を使うと「証明書未検証」と判断される場合がある。社内 CA または公的 CA でサーバ証明書を発行し、CA ルートをクライアントへ配布する。
  4. 最新コネクタを利用
    .NET 用コネクタは新しいほど TLS 1.2/1.3、アルゴリズム、既知脆弱性の修正が進んでいる。プロジェクトで使用中のコネクタの更新計画を立てる。
  5. ホスト名の整合
    VerifyFull にする場合、接続文字列の server で指定する FQDN と、証明書の CN/SAN を一致させる。
  6. 平文フォールバック禁止
    検証でも Preferred は避け、本番同等ポリシーで動作検証する。

動作確認とデバッグ手順

サーバ側で TLS が有効か確認

SHOW VARIABLES LIKE 'have_ssl';      -- YES なら SSL 有効
SHOW STATUS LIKE 'Ssl_cipher';       -- 使用中の暗号スイート確認
SHOW VARIABLES LIKE 'tls_version';   -- 許可する TLS バージョン

クライアントの接続テスト(CLI)

mysql --ssl-mode=REQUIRED -h server001 -u readonly -p

CLI で成功し、Ssl_cipher に値が入っていれば TLS は機能しています。アプリ側でも同じ SslMode と CA 指定で接続しましょう。

.NET コード例(C#)

MySqlConnector(推奨)を使う例

using MySqlConnector;

// 例:接続文字列は環境変数から読み出す(ハードコーディングしない)
var cs = Environment.GetEnvironmentVariable("MYSQL_CS");

// 明示的にビルダーで構成する場合
var builder = new MySqlConnectionStringBuilder {
Server = "server001",
Port = 3306,
Database = "db",
UserID = "readonly",
Password = "readonly",
SslMode = MySqlSslMode.VerifyFull, // or Required / VerifyCA
// 代表例:CA ファイルを使う場合(コネクタ固有キーは後述)
// CACertificateFile = "/etc/ssl/certs/ca-cert.pem"
};

using var conn = new MySqlConnection(builder.ConnectionString);
await conn.OpenAsync();
// 接続後の確認(任意)
using var cmd = conn.CreateCommand();
cmd.CommandText = "SHOW STATUS LIKE 'Ssl_cipher'";
using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
Console.WriteLine($"{reader.GetString(0)}={reader.GetString(1)}");
} </code></pre>

<h3>Oracle MySQL Connector/NET(MySql.Data)を使う例</h3>
<p>同様に <code>SslMode</code> は利用できます。CA の指定方法や追加オプションはコネクタにより記法が異なるため、プロジェクトで採用しているライブラリの仕様に合わせてください(例:<code>SslCa</code>、または Windows 証明書ストアの利用など)。</p>

<h2>.NET 向け MySQL コネクタ別「TLS 早見表」</h2>
<p>同じ「CA の指定」でも、キー名が異なることに注意してください。表のキーは代表例です。実際には採用コネクタのドキュメントに合わせて最終確認してください。</p>
<table>
  <thead>
    <tr>
      <th>コネクタ</th>
      <th>TLS 有効化</th>
      <th>サーバ証明書の検証</th>
      <th>CA 証明書の指定例</th>
      <th>ホスト名検証</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>MySqlConnector</td>
      <td><code>SslMode=Required/VerifyCA/VerifyFull</code></td>
      <td><code>VerifyCA</code> / <code>VerifyFull</code></td>
      <td><code>CACertificateFile=/path/to/ca.pem</code></td>
      <td><code>VerifyFull</code> で要求</td>
    </tr>
    <tr>
      <td>MySQL Connector/NET(MySql.Data)</td>
      <td><code>SslMode=Required/VerifyCA/VerifyFull</code></td>
      <td><code>VerifyCA</code> / <code>VerifyFull</code></td>
      <td><code>SslCa=/path/to/ca.pem</code> または 証明書ストア</td>
      <td><code>VerifyFull</code> で要求</td>
    </tr>
    <tr>
      <td>MariaDB Connector/NET</td>
      <td><code>SslMode=Required/VerifyCA/VerifyFull</code></td>
      <td><code>VerifyCA</code> / <code>VerifyFull</code></td>
      <td><code>SslCa=/path/to/ca.pem</code></td>
      <td><code>VerifyFull</code> で要求</td>
    </tr>
  </tbody>
</table>
<p>いずれのコネクタでも <strong><code>Encrypt</code> と <code>TrustServerCertificate</code> は対象外</strong>である点は共通です。</p>

<h2>設定例:環境別テンプレート</h2>
<h3>Windows(IIS)で動かす場合</h3>
<ul>
  <li>CA ルート証明書を「ローカル コンピューター &gt; 信頼されたルート証明機関」に登録(または接続文字列で CA ファイルを指定)。</li>
  <li>接続文字列例:
    <pre><code>server=server001.example.local;port=3306;database=db;
uid=readonly;pwd=readonly;
SslMode=VerifyFull;
SslCa=C:\certs\corp-root-ca.pem

アプリプールの実行アカウントが CA ファイルにアクセスできるよう ACL を設定。

Linux(Kestrel)で動かす場合

  • CA を /etc/ssl/certs/ へ配置し、権限は 644 を基本に所有者/グループで読み取りを許可。
  • 接続文字列例: server=server001;port=3306;database=db; uid=readonly;pwd=readonly; SslMode=VerifyCA;SslCa=/etc/ssl/certs/ca-cert.pem

Docker / K8s の場合

  • CA をイメージに COPY せず、Secret としてマウント。
  • 環境変数で接続文字列を注入し、アプリは Environment.GetEnvironmentVariable から読み込む。
  • 例(Kubernetes マニフェストの一部): env: - name: MYSQL_CS valueFrom: secretKeyRef: name: app-secrets key: mysql-connection-string volumeMounts: - name: ca mountPath: /etc/ssl/certs readOnly: true

サーバ証明書の準備(要点のみ)

  1. 鍵と CSR を作成(サーバ名は FQDN) openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr \ -subj "/C=JP/ST=Tokyo/L=Chiyoda/O=Example Inc./CN=server001.example.local"
  2. 社内 CA で署名(中間 CA がある場合はチェーンを作る)
  3. MySQL サーバへ配置し mysqld に設定 [mysqld] ssl_ca=/etc/mysql/ssl/ca-chain.pem ssl_cert=/etc/mysql/ssl/server.crt ssl_key=/etc/mysql/ssl/server.key tls_version=TLSv1.2,TLSv1.3
  4. 再起動の上で検証 SHOW VARIABLES LIKE 'have_ssl'; SHOW STATUS LIKE 'Ssl_%';

よくある落とし穴と対処法

  • ホスト名不一致:VerifyFull では server= に指定したホスト名と、証明書の CN/SAN が一致していないと失敗。FQDN を統一する。
  • CA の読み取り権限:コンテナや IIS の実行ユーザーが CA ファイルを読めないと検証に失敗。
  • 古い TLS の強制:負荷分散装置や古い OS イメージが TLS1.0/1.1 のみを許可していると接続不可。サーバ側で TLS1.2/1.3 を有効化。
  • 自己署名 + Required:暗号化はされるが検証されないため、SAST/DAST で指摘されがち。VerifyCA 以上へ移行。
  • 接続文字列キーのスペル:誤ったキーは丸ごと無視されるか option not supported。綴りを厳密に。
  • プロバイダ混在:参照している NuGet が MySqlConnector か MySql.Data かでキーが違う。チーム内で統一する。

パフォーマンスの観点(TLS 化しても重くしない)

  • コネクションプーリングを有効:初回ハンドシェイクのコストを amortize。Pooling=true;MinimumPoolSize=0;MaximumPoolSize=100 などを適切に。
  • クエリはプレースホルダ化:TLS とは別に、SQL インジェクション対策と解析コスト削減に有効。
  • KeepAlive/アイドルタイムアウト:ロードバランサや FW によるアイドル切断を避けるため、アプリ側の再試行戦略を実装。

構成例:appsettings.json に接続情報を置かない

アプリ設定への直書きを避け、実行環境で注入するパターンです。

// Program.cs (.NET 8)
var builder = WebApplication.CreateBuilder(args);

// 例:接続文字列を環境変数から取得
builder.Services.AddTransient(_ => {
var cs = Environment.GetEnvironmentVariable("MYSQL_CS")
?? throw new InvalidOperationException("MYSQL_CS is not set.");
return new MySqlConnection(cs);
});

var app = builder.Build();
// 以降通常の DI で MySqlConnection を注入して利用 

安全な接続のチェックリスト(貼って使える)

  • 接続先:FQDN を使用(server=server001.example.local)。
  • TLS:SslMode=VerifyFull(少なくとも VerifyCA)。
  • CA:環境ごとに正しい CA を配置し、接続文字列で指定。
  • 資格情報:環境変数やシークレットストアから読み込み、ログに出さない。
  • フォールバック:Preferred は使わない。
  • 検証:SHOW STATUS LIKE 'Ssl_cipher' で暗号化を確認。
  • 依存関係:NuGet のバージョンを最新安定版へ。

ケーススタディ:誤設定から復旧まで

ある既存 ASP.NET MVC アプリで、SQL Server から MySQL に移行した際、既存の接続文字列を流用して次の設定が残っていました。

Encrypt=yes;TrustServerCertificate=yes;Trusted_Connection=no

結果、ステージングでは平文接続しか成立せず、本番では LB が TLS 強制のため接続不能。手順は次のとおりです。

  1. NuGet を確認:MySqlConnector を採用(最新安定版)。
  2. 接続文字列を置換: server=server001;port=3306;database=appdb; uid=app;pwd=***; SslMode=VerifyFull; SslCa=/etc/ssl/certs/org-root.pem
  3. サーバ証明書の CN/SAN を server001.example.local に再発行。
  4. CI でシークレットを注入し、アプリからは環境変数参照。
  5. Fortify を再実行し「暗号化無し」「検証無し」の指摘が解消。

「SQL Server の癖」を捨てる:置き換え早見表

SQL Server(誤って流用しがち)MySQL での相当設定意味
Encrypt=yesSslMode=Required暗号化を必須化(ただし検証は行わない)
TrustServerCertificate=yesSslMode=Required(CA 指定無し)検証スキップという点では近いが、MySQL では推奨されない
TrustServerCertificate=noVerifyCA / VerifyFullCA 検証 / ホスト名検証まで行う推奨モード

トラブルシューティング:エラーメッセージ別ヒント

  • option not supported:接続文字列キーの誤り。前述表を参照して置換。
  • SSL connection error: wrong version number:サーバ側が TLS1.2/1.3 を許可していない、もしくはプロキシが平文終端。LB/Proxy 設定を確認。
  • Certificate verify failed:CA パスが誤り・権限不足・チェーン不完全。中間 CA を含むチェーンを配置。
  • Host name mismatch:VerifyFull でのホスト名不一致。FQDN を合わせる。

セキュリティ運用の実務 Tips

  • 最小権限の徹底:接続ユーザーは読み取り専用(SELECT)など用途限定に。
  • ローテーション:パスワード・証明書は定期ローテーション。失効リスト(CRL/OCSP)を運用に組み込むとより堅牢。
  • 監査:接続失敗や TLS 例外は監視に取り込み、平文フォールバックの痕跡がないかをチェック。

まとめ

Encrypt と TrustServerCertificate は SQL Server 専用であり、MySQL では SslMode や SslCa(またはコネクタ固有の CA 指定キー)へ置き換える必要があります。最終形としては SslMode=VerifyFull + CA 配布 を基本とし、資格情報の外部化・ホスト名の整合・最新コネクタの採用までをワンセットで実施してください。これにより「option not supported」エラーは解消され、セキュアな通信とセキュリティスキャン合格の両立が実現できます。


付録:最小再現セット(ローカル検証用)

  1. Docker の MySQL を TLS 有効で立ち上げる(自己署名で可)。
  2. CA をコンテナ外へコピーし、.NET アプリから VerifyCA で接続。
  3. SHOW STATUS LIKE 'Ssl_cipher' が値を返すことを確認。
  4. その後、CA を社内 CA に置き換え VerifyFull で本番条件に寄せる。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次