データガバナンスの最大の要因と基本の1つは、セキュリティです。企業や大量の消費にデータ管理を関与させる場合は常に、データベースセキュリティを実装することをお勧めします。
データのセキュリティは、データベース管理の最も重要な側面の1つです。これは、すべてのデータベース管理が実装する必要のある重要な役割を果たします。正しく実装および実行されると、データセキュリティが向上するだけでなく、システムの安定性にも影響を与え、開発ライフサイクルが向上し、データコンプライアンスが向上し、セキュリティ意識がチームレベルまで向上します。誰もが自分のデータが悪意のある人の手に渡ることを望んでいません。データが侵害された場合、データの機密性と整合性が損なわれるだけでなく、組織が重大な財務リスクにさらされる可能性があります。単純なデータベース管理の実装であっても、誰かがすでにシステムに侵入していることに気付いた場合、どのような結果がもたらされるかについて不安や恐怖を感じることは、まったく不快なことです。
MySQLサーバー接続が安全かどうかの判断は、MySQLが転送中のデータをどれだけ安全に送信するかによって異なります。 MySQLクライアントとサーバー間の暗号化されていない接続により、ネットワークにアクセスできる誰かがすべてのトラフィックを監視し、クライアントとサーバー間で送受信されるデータを検査できます。
安全な方法でネットワークを介して情報を移動する必要がある場合、暗号化されていない接続は受け入れられません。あらゆる種類のデータを読み取り不能にするには、暗号化を使用します。暗号化アルゴリズムには、暗号化されたメッセージの順序の変更やデータの2回の再生など、さまざまな既知の攻撃に抵抗するためのセキュリティ要素を含める必要があります。
しかし、私のMySQLは安全ですよね?
MySQLの安定性と脆弱性のチェックを決定せずに、MySQLが安全であると信じることは、宗教のようなものです。あなたはそれを見なくても、触れなくても信じる傾向があります。問題は、MySQLはテクノロジーであり、その存在は抽象的な考えに基づいていないということです。テストする必要があり、証明する必要があります。また、安全性が必要であり、他のユーザーによってもテストされているベストプラクティスに従います。
MySQLサーバー接続、つまり転送中が安全かどうか、または暗号化されているかどうかの判断は、「データベースをどのように設定しましたか?」に依存します。または「誰がデータベースをセットアップしますか?」
MySQLは、TLS(Transport Layer Security)プロトコルを使用したクライアントとサーバー間の暗号化された接続をサポートします。 TLSはSSL(Secure Sockets Layer)と呼ばれることもありますが、MySQLは暗号化が弱く、SSLがTLSを優先してすでに非推奨になっているため、暗号化された接続にSSLプロトコルを実際には使用しません。 TLSは暗号化アルゴリズムを使用して、パブリックネットワークを介して受信したデータを信頼できるようにします。データの変更、損失、または再生を検出するメカニズムがあります。 TLSには、X.509標準を使用したID検証を提供するアルゴリズムも組み込まれています。 SSLまたはTLSは同じ意味で使用されていますが、MySQLによる暗号化のコンテキストでは、MySQLがTLSv1、TLSv1.1、TLSv1.2、およびTLSv1.3プロトコルを使用した暗号化接続をサポートするTLSが使用されています。
X.509を使用すると、インターネット上の誰かを識別できます。基本的には、電子証明書を必要とする人に電子証明書を割り当てる「認証局」(またはCA)と呼ばれるエンティティが必要です。証明書は、2つの暗号化キー(公開キーと秘密キー)を持つ非対称暗号化アルゴリズムに依存しています。証明書の所有者は、身元の証明として証明書を別の当事者に提示できます。証明書は、その所有者の公開鍵で構成されます。この公開鍵を使用して暗号化されたデータは、証明書の所有者が保持している対応する秘密鍵を使用してのみ復号化できます。
スキュタレーは、紀元前400年頃に使用されたメッセージを暗号化および復号化する方法として使用されることが知られています。スパルタによって。彼らはスタッフを包んだパピルス(紙の一種)にメッセージを書きました。受信者は、スタッフの正しい直径とサイズの場合にのみメッセージを解読できます。これは、暗号化して、ターゲットの宛先へのメッセージまたはデータの不正な抽出を回避する方法として機能します。
MySQLの場合と同様に、SSL / TLSプロトコルと暗号を使用することで、データが有線またはインターネットを通過するときに、誰かがデータを抽出したり、データを乗っ取ったりするのを防ぐことができます。
デフォルトでは、サーバーが暗号化された接続をサポートしている場合、MySQLプログラムは暗号化を使用して接続を試み、暗号化された接続を確立できない場合は暗号化されていない接続にフォールバックします。バージョンMySQL>=5.7以降、変数をサポートしてTLS/SSLおよびRSAファイルを作成または生成できます。 OpenSSLを使用してコンパイルされたMySQLディストリビューションの場合、MySQLサーバーには、起動時に欠落しているSSLファイルとRSAファイルを自動的に生成する機能があります。 auto_generate_certs、sha256_password_auto_generate_rsa_keys、およびcaching_sha2_password_auto_generate_rsa_keys(バージョン> =8.0)のシステム変数は、これらのファイルの自動生成を制御します。これらの変数はデフォルトで有効になっています。起動時に有効にして検査することはできますが、実行時に設定することはできません。
デフォルトでは、これらの変数はオンまたは有効に設定されています。それ以外の場合、ユーザーはmysql_ssl_rsa_setupユーティリティを手動で呼び出すことができます。 RPMやDEBパッケージなどの一部の配布タイプでは、データディレクトリの初期化中にmysql_ssl_rsa_setupの呼び出しが発生します。この場合、opensslコマンドが使用可能である限り、MySQLディストリビューションはOpenSSLを使用してコンパイルされている必要はありません。
これらのファイルが利用可能または生成された後も、MySQLは次の理由で暗号化接続を使用しません。前述のように、デフォルトでは、サーバーが暗号化された接続をサポートしている場合、MySQLクライアントプログラムは暗号化された接続を確立しようとします。オプション:
-
デフォルトでは、MySQL接続に--ssl-modeのフラグが設定されていない場合、デフォルト値は次のように設定されます。 --ssl-mode=PREFFERED。したがって、クライアントは暗号化を使用して接続を試み、暗号化された接続を確立できない場合は暗号化されていない接続にフォールバックします。
-
--ssl-mode =REQUIREDを使用すると、クライアントは暗号化された接続を必要とし、確立できない場合は失敗します。
-
--ssl-mode =DISABLEDを使用すると、クライアントは暗号化されていない接続を使用します。
-
--ssl-mode=VERIFY_CAまたは--ssl-mode=VERIFY_IDENTITYを使用する場合、クライアントには暗号化された接続が必要ですまた、サーバーCA証明書に対して、および(VERIFY_IDENTITYを使用して)証明書内のサーバーホスト名に対して検証を実行します。
MySQLのデフォルトのメカニズムでは、優先接続を使用するため、暗号化または保護された接続を使用しようとする可能性がありますが、それでもやるべきことがいくつかあり、決定する必要があります。
前述のように、auto_generate_certs、sha256_password_auto_generate_rsa_keys、およびcaching_sha2_password_auto_generate_rsa_keys(バージョン> =8.0)変数は、必要なSSL / TLSおよびRSAファイルの生成に役立ちます。通常のユーザーは、接続中にこのような要件がありません。安全ではありません。たとえば、dbadminというユーザーを作成しましょう。
mysql> create user 'dbadmin'@'192.168.40.%' identified by '[email protected]';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'192.168.40.%';
Query OK, 0 rows affected (0.01 sec)
次に、変数が正しく設定されているかどうかを確認します。変数はデフォルトで有効になっている必要があります。
mysql> show global variables where variable_name in ('auto_generate_certs','sha256_password_auto_generate_rsa_keys','caching_sha2_password_auto_generate_rsa_keys');
+----------------------------------------------+-------+
| Variable_name | Value |
+----------------------------------------------+-------+
| auto_generate_certs | ON |
| caching_sha2_password_auto_generate_rsa_keys | ON |
| sha256_password_auto_generate_rsa_keys | ON |
+----------------------------------------------+-------+
3 rows in set (0.00 sec)
$ find /var/lib/mysql -name "*.pem"
/var/lib/mysql/ca-key.pem
/var/lib/mysql/ca.pem
/var/lib/mysql/server-key.pem
/var/lib/mysql/server-cert.pem
/var/lib/mysql/client-key.pem
/var/lib/mysql/client-cert.pem
/var/lib/mysql/private_key.pem
/var/lib/mysql/public_key.pem
次に、SSLファイルが正しくロードされているかどうかを確認します。
mysql> show global variables like 'ssl%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| ssl_ca | ca.pem |
| ssl_capath | |
| ssl_cert | server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_fips_mode | OFF |
| ssl_key | server-key.pem |
+---------------+-----------------+
8 rows in set (0.00 sec)
さて、これはよさそうです。また、MySQLが暗号化された接続を受け入れる準備ができていることも意味します。ただし、MySQLにそのまま接続すると、前述のように、デフォルトで--ssl-mode =PREFFEREDを使用するか、-ssl-modeが指定されていない場合でも、暗号化されていない接続を使用するようにフェールバックします。以下を参照してください:
$ mysql [email protected] -h 192.168.40.110 -udbadmin -e "status;" | grep ssl -i
SSL:使用されていません
これは、セキュリティで保護された接続を使用していないことを示しています。暗号が使用されているかどうかSSLセッションステータス変数を確認すると、空であることがわかります:
mysql> show global status like 'ssl%';
+--------------------------------+--------------------------+
| Variable_name | Value |
+--------------------------------+--------------------------+
| Ssl_accept_renegotiates | 0 |
| Ssl_accepts | 2 |
| Ssl_callback_cache_hits | 0 |
| Ssl_cipher | |
| Ssl_cipher_list | |
| Ssl_client_connects | 0 |
| Ssl_connect_renegotiates | 0 |
| Ssl_ctx_verify_depth | 18446744073709551615 |
| Ssl_ctx_verify_mode | 5 |
| Ssl_default_timeout | 0 |
| Ssl_finished_accepts | 2 |
| Ssl_finished_connects | 0 |
| Ssl_server_not_after | Aug 28 12:48:46 2031 GMT |
| Ssl_server_not_before | Aug 30 12:48:46 2021 GMT |
| Ssl_session_cache_hits | 0 |
| Ssl_session_cache_misses | 0 |
| Ssl_session_cache_mode | SERVER |
| Ssl_session_cache_overflows | 0 |
| Ssl_session_cache_size | 128 |
| Ssl_session_cache_timeouts | 0 |
| Ssl_sessions_reused | 0 |
| Ssl_used_session_cache_entries | 0 |
| Ssl_verify_depth | 0 |
| Ssl_verify_mode | 0 |
| Ssl_version | |
+--------------------------------+--------------------------+
25 rows in set (0.002 sec)
接続がまだ保護されていないことが明らかになったため、MySQLではrequire_secure_transport変数を導入しました。この変数では、確立するすべての接続を暗号化して保護する必要があります。セキュリティで保護されていない接続に接続しようとすると失敗します。たとえば、サーバーで有効にする:
mysql> set global require_secure_transport=1;
Query OK, 0 rows affected (0.00 sec)
暗号化されていない接続を使用してクライアントとして接続しようとすると失敗します:
$ mysql [email protected] -h 192.168.40.110 -udbadmin
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
正常かつ安全に接続するには、ssl-ca、ssl-cert、ssl-key変数を指定する必要があります。以下を参照してください:
$ mysql [email protected] -h 192.168.40.110 -udbadmin --ssl-ca=/tmp/pem/ca.pem --ssl-cert=/tmp/pem/server-cert.pem --ssl-key=/tmp/pem/server-key.pem -e "show global status like 'ssl%'\G"
*************************** 1. row ***************************
Variable_name: Ssl_accept_renegotiates
Value: 0
*************************** 2. row ***************************
Variable_name: Ssl_accepts
Value: 16
*************************** 3. row ***************************
Variable_name: Ssl_callback_cache_hits
Value: 0
*************************** 4. row ***************************
Variable_name: Ssl_cipher
Value: TLS_AES_256_GCM_SHA384
*************************** 5. row ***************************
Variable_name: Ssl_cipher_list
Value: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA
*************************** 6. row ***************************
Variable_name: Ssl_client_connects
Value: 0
*************************** 7. row ***************************
Variable_name: Ssl_connect_renegotiates
Value: 0
*************************** 8. row ***************************
Variable_name: Ssl_ctx_verify_depth
Value: 18446744073709551615
*************************** 9. row ***************************
Variable_name: Ssl_ctx_verify_mode
Value: 5
*************************** 10. row ***************************
Variable_name: Ssl_default_timeout
Value: 7200
*************************** 11. row ***************************
Variable_name: Ssl_finished_accepts
Value: 11
*************************** 12. row ***************************
Variable_name: Ssl_finished_connects
Value: 0
*************************** 13. row ***************************
Variable_name: Ssl_server_not_after
Value: Aug 28 12:48:46 2031 GMT
*************************** 14. row ***************************
Variable_name: Ssl_server_not_before
Value: Aug 30 12:48:46 2021 GMT
*************************** 15. row ***************************
Variable_name: Ssl_session_cache_hits
Value: 0
*************************** 16. row ***************************
Variable_name: Ssl_session_cache_misses
Value: 0
*************************** 17. row ***************************
Variable_name: Ssl_session_cache_mode
Value: SERVER
*************************** 18. row ***************************
Variable_name: Ssl_session_cache_overflows
Value: 0
*************************** 19. row ***************************
Variable_name: Ssl_session_cache_size
Value: 128
*************************** 20. row ***************************
Variable_name: Ssl_session_cache_timeouts
Value: 0
*************************** 21. row ***************************
Variable_name: Ssl_sessions_reused
Value: 0
*************************** 22. row ***************************
Variable_name: Ssl_used_session_cache_entries
Value: 0
*************************** 23. row ***************************
Variable_name: Ssl_verify_depth
Value: 18446744073709551615
*************************** 24. row ***************************
Variable_name: Ssl_verify_mode
Value: 5
*************************** 25. row ***************************
Variable_name: Ssl_version
Value: TLSv1.3
または、たとえばユーザーがREQUIRED SSLで作成されている場合、デフォルト値であるrequire_secure_transportが無効になっている場合でも、SSLを使用して接続する必要があります。 require_secure_transportが有効になっている場合、その機能は、優先されるアカウントごとのSSL要件を補足することに注意してください。したがって、アカウントがREQUIRE SSLで定義されている場合、require_secure_transportを有効にしても、そのアカウントを使用してUnixソケットファイルを使用して接続することはできません。
MySQLサーバーのデプロイメントが暗号化されて安全であることを確認する
手間のかからないことは、他の問題や心配する必要がないように、私たちが常に楽しみにしていることです。 ClusterControlは、暗号化された接続を使用してMySQLデータベースをデプロイし、SSLおよびRSA証明書を生成します。たとえば、以下のスクリーンショットは、ClusterControlからのクラスターの作成コマンドのジョブアクティビティを示しています。
SSLファイルとRSAファイルを設定し、/etc/に配置します以下のようなmysql/certs /パス:
mysql> show global variables like 'ssl%';
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| ssl_ca | /etc/mysql/certs/server_ca.crt |
| ssl_capath | |
| ssl_cert | /etc/mysql/certs/server.crt |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/mysql/certs/server.key |
+---------------+--------------------------------+
7 rows in set (0.00 sec)
次に、ClusterControlは、以下に示すように、生成されたSSLファイルとRSAファイルを[キー管理]ナビゲーションパネルの下で一元的にグループ化します。
デプロイしたら、必要なのは、必要なSSLを使用してユーザーを作成するか、MySQLサーバー接続に暗号化され保護されたレイヤーを適用する場合はrequire_secure_transportを使用することだけです。