VPN 経由の MySQL:暗号化だけでなくサーバーを検証する
間違ったホストへの暗号化は、やはり間違いです。ssl-mode の値を比較し、意図したサーバーを名指ししてそれを証明する接続を実行してください。
接続の保存先は 10.20.4.15 です。VPN が切れても、クライアントは接続し続けます。それは良い知らせではありません。プライベートアドレスは、自分がいるどのルーティングコンテキストの中でも一つの場所にすぎず、同じ範囲を使うネットワークは数多くあります。クライアントは MySQL サーバーに到達しましたが、それはおそらく自分のサーバーではありません。
修正には二つの半分があり、ネットワークに関わるのはそのうち一つだけです。接続を意図した経路に保ち、クライアントに通信相手のサーバーを認証させます。前半は VPN が助ける部分であり、後半は設定が必要です。
何に対して暗号化されているのか?
TLS は会話を途中の誰からも守りますが、クライアントが確認しない限り、エンドポイントが名乗る身元については何も語りません。信頼された認証局に対して検証される証明書は、その証明書がその認証局から発行されたことを証明します。しかし、到達しようとしたホスト名に対して発行されたことは証明しません。これは別の問いです。
これは理論上の隙間ではありません。キャプティブポータル、誤った VRF のミス、重複するアドレス計画はどれも、あなたと TLS を交渉する用意が完全にあるサーバーを生み出します。クライアントが暗号化だけを要求するなら、セッションはプライベートですが、向き先は間違ったデータベースです。
したがって問うべきは、接続が暗号化されているかではなく、意図した身元に対して暗号化されているかです。MySQL のクライアントでは、その区別は ssl-mode 設定に完全に宿っています。
実践における五つの ssl-mode 値
値は五つあり、この手順書の問いに答えるのはそのうち一つだけです。表は、名前が示唆する内容ではなく、それぞれが実際に何を保証するかを示しています。
| Mode | What it guarantees |
|---|---|
DISABLED | No TLS at all; everything on the wire is readable |
PREFERRED | Tries TLS and falls back to plaintext when the account and server allow it, so it is not a fail-closed requirement |
REQUIRED | Refuses to connect without TLS, and does not validate the certificate |
VERIFY_CA | Validates the server certificate against the configured CA and does not check the hostname |
VERIFY_IDENTITY | Validates the CA and checks that the certificate names the host the client used |
この記事の問いに答えるのは最後の行だけです。 PREFERRED はそれ自体で注目に値します。黙って平文に落ちるクライアントは拒否するクライアントより悪く、暗号化があると思っているのにパケットキャプチャはそう言っていません。
今日実行できる接続
以下のコマンドが使うべき形で、二つのプレースホルダーがあります。承認されたデータベース名と、承認された経路で入手した CA ファイルです。どちらも、サーバーが最初の接触で提示するものから取るべきではありません。
mysql --host=db.corp.example --user=app_reader \
--ssl-mode=VERIFY_IDENTITY \
--ssl-ca=/approved/path/ca.pem --password
--password に値を付けないと入力を促し、秘密がプロセス一覧やシェル履歴に残りません。共有ジャンプホストではコマンドラインが他の利用者に見えるため、これは小さな習慣で大きな効果があります。
これが失敗したとき、エラーテキストは直感よりもうまくケースを区別します。CA の失敗はチェーンが検証できないことを意味し、どの CA がサーバー証明書に署名したかを見るべきです。ホスト名の失敗はチェーンが正常で名前が一致しないことを意味し、通常は間違ったサーバーではなく、正しいサーバーに間違った名前で接続したということです。
プロンプトが表示されたことは、パスワードがすでに送信された証拠ではなく、接続の失敗はクライアントから何も出なかったことを証明しません。過去の出来事を再構成するなら、クライアント、その設定、認証プラグイン、失敗した段階を特定してください。最後のエラーメッセージから露出を推定するのは推測です。
名前がトンネルから来るとき
ローカルポート転送は、人々を驚かせる形で身元確認を壊します。ローカルポートをデータベースに転送し、localhost に接続すると、クライアントは証明書を localhost に対して検証しますが、その名前に対して証明書は発行されていません。接続は完全に安全でも検証は失敗します。これは検証が意図どおりに機能しているということです。
正直な答えは二つあります。転送されたエンドポイントに、ループバックアドレスに解決されサーバー証明書に現れる名前を与えるか、ホスト名を端から端まで使ってクライアントに実際の身元を検証させます。前者は開発者に便利で証明書の作業が必要です。後者は考えるのが簡単で、自動化の正しい既定値であることがよくあります。転送を機能させるために検証を無効にすると、追加しようとしていた性質を捨てることになります。
受け入れは三つの条件
受け入れテストを三つの独立した文として書きます。接続が意図した経路を使ったこと、暗号化が好ましいではなく必須だったこと、サーバーの身元が信頼できる素材に対して検証されたことです。 緑の VPN アイコンはそのどれも確立しません。
GUI クライアントと MariaDB については、フラグの綴りがそのまま当てはまると仮定せず、ベンダー自身のドキュメントを確認してください。MySQL の暗号化接続に関するドキュメント はモードの違いと CA 配布の要件を扱っており、本番の接続文字列を変更する前に確認すべき参照です。