MariaDB over SSL 接続で「certificate verify failed」エラーが発生した場合のトラブルシューティング

2024-05-27

MariaDB over SSL で「certificate verify failed」エラーが発生する際のトラブルシューティング

MariaDB を SSL で接続しようとすると、「certificate verify failed」エラーが発生する。

対象

  • OS: RHEL 7
  • データベース: MariaDB

原因

このエラーは、クライアントがサーバーの証明書を検証できなかったことを示しています。考えられる原因は以下の通りです。

  • クライアントがサーバーの証明書ファイルを持っていない
  • 証明書ファイルが破損している
  • 証明書ファイルの権限が正しくない
  • サーバーの証明書が自己署名されている

解決策

以下の手順で、問題を解決することができます。

クライアントマシンに、ca.pem または cacert.pem などの名前の証明書ファイルがあることを確認します。このファイルは、通常、MariaDB のインストールディレクトリ内の ssl ディレクトリにあります。

クライアントが正しい証明書ファイルを使用していることを確認します。証明書ファイルの名前がわからない場合は、サーバー管理者に確認してください。

証明書ファイルをテキストエディタで開いて、破損がないことを確認します。破損している場合は、新しい証明書ファイルをサーバーから取得する必要があります。

証明書ファイルの権限が 644 になっていることを確認します。

サーバーの証明書が自己署名されている場合は、クライアントマシンに CA ファイルをインストールする必要があります。CA ファイルは、通常、サーバー管理者から入手できます。

上記の手順で問題が解決しない場合は、以下の情報とともに、詳しい説明をお願いします。

  • エラーメッセージの詳細
  • 使用している MariaDB のバージョン
  • 使用している SSL ライブラリのバージョン
  • サーバーとクライアントのファイアウォール設定



    C

    #include <stdio.h>
    #include <mysql/mysql.h>
    
    int main() {
      MYSQL *conn;
      MYSQL_RES *res;
    
      // Initialize connection
      conn = mysql_init(NULL);
      if (!conn) {
        fprintf(stderr, "Error initializing MySQL connection: %s\n", mysql_error(conn));
        return 1;
      }
    
      // Set SSL options
      mysql_ssl_set(conn, MYSQL_SSL_CERT, "client-cert.pem");
      mysql_ssl_set(conn, MYSQL_SSL_KEY, "client-key.pem");
      mysql_ssl_set(conn, MYSQL_SSL_CA, "ca.pem");
    
      // Connect to the database
      if (mysql_real_connect(conn, "localhost", "user", "password", "database", 3306, NULL, 0)) {
        printf("Connected to MariaDB server\n");
    
        // Execute a query
        if (mysql_query(conn, "SELECT * FROM some_table")) {
          fprintf(stderr, "Error executing query: %s\n", mysql_error(conn));
        } else {
          res = mysql_store_result(conn);
          if (res) {
            // Process query results
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res))) {
              for (int i = 0; i < mysql_field_count(conn); i++) {
                printf("%s\t", row[i]);
              }
              printf("\n");
            }
            mysql_free_result(res);
          }
        }
    
        mysql_close(conn);
      } else {
        fprintf(stderr, "Error connecting to MariaDB server: %s\n", mysql_error(conn));
      }
    
      return 0;
    }
    

    C++

    #include <iostream>
    #include <mysql/mysql.h>
    
    int main() {
      MYSQL *conn;
      MYSQL_RES *res;
    
      // Initialize connection
      conn = mysql_init(NULL);
      if (!conn) {
        std::cerr << "Error initializing MySQL connection: " << mysql_error(conn) << std::endl;
        return 1;
      }
    
      // Set SSL options
      mysql_ssl_set(conn, MYSQL_SSL_CERT, "client-cert.pem");
      mysql_ssl_set(conn, MYSQL_SSL_KEY, "client-key.pem");
      mysql_ssl_set(conn, MYSQL_SSL_CA, "ca.pem");
    
      // Connect to the database
      if (mysql_real_connect(conn, "localhost", "user", "password", "database", 3306, NULL, 0)) {
        std::cout << "Connected to MariaDB server" << std::endl;
    
        // Execute a query
        if (mysql_query(conn, "SELECT * FROM some_table")) {
          std::cerr << "Error executing query: " << mysql_error(conn) << std::endl;
        } else {
          res = mysql_store_result(conn);
          if (res) {
            // Process query results
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res))) {
              for (int i = 0; i < mysql_field_count(conn); i++) {
                std::cout << row[i] << "\t";
              }
              std::cout << std::endl;
            }
            mysql_free_result(res);
          }
        }
    
        mysql_close(conn);
      } else {
        std::cerr << "Error connecting to MariaDB server: " << mysql_error(conn) << std::endl;
      }
    
      return 0;
    }
    

    Python

    import mysql.connector
    
    conn = mysql.connector.connect(
        user="user",
        password="password",
        host="localhost",
        database="database",
        ssl_ca="ca.pem",
        ssl_cert="client-cert.pem",
        ssl_key="client-key.pem",
    )
    
    cursor = conn.cursor()
    
    cursor.execute("SELECT * FROM some_table")
    
    for row in cursor:
        print
    



    Using a connection string

    You can also connect to MariaDB over SSL using a connection string. This is a more concise way to specify the connection parameters, including the SSL options.

    # C
    mysql_real_connect(conn, "localhost", "user", "password", "database", 3306, NULL, MYSQL_OPT_SSL | MYSQL_OPT_SSL_CERT | MYSQL_OPT_SSL_KEY | MYSQL_OPT_SSL_CA, "client-cert.pem", "client-key.pem", "ca.pem");
    
    # C++
    mysql_real_connect(conn, "localhost", "user", "password", "database", 3306, NULL, MYSQL_OPT_SSL | MYSQL_OPT_SSL_CERT | MYSQL_OPT_SSL_KEY | MYSQL_OPT_SSL_CA, "client-cert.pem", "client-key.pem", "ca.pem");
    
    # Python
    conn = mysql.connector.connect(
        user="user",
        password="password",
        host="localhost",
        database="database",
        ssl_ca="ca.pem",
        ssl_cert="client-cert.pem",
        ssl_key="client-key.pem",
        ssl_mode=mysql.connector.SSLMode.VERIFY_CA,
    )
    

    Using the SSLVerifyServerCert option

    You can also use the SSLVerifyServerCert option to control how the client verifies the server's certificate. The following values are available:

    • SSL_VERIFY_NONE: The client does not verify the server's certificate.
    • SSL_VERIFY_PEER: The client verifies the server's certificate is valid and matches the expected hostname.
    # C
    mysql_ssl_set(conn, MYSQL_SSL_VERIFY_SERVER_CERT, SSL_VERIFY_CA);
    
    # C++
    mysql_ssl_set(conn, MYSQL_SSL_VERIFY_SERVER_CERT, SSL_VERIFY_CA);
    
    # Python
    conn = mysql.connector.connect(
        user="user",
        password="password",
        host="localhost",
        database="database",
        ssl_ca="ca.pem",
        ssl_cert="client-cert.pem",
        ssl_key="client-key.pem",
        ssl_verify=mysql.connector.SSLVerify.VERIFY_CA,
    )
    

    You can also use the SSLVerifyDepth option to control the depth of the certificate chain that the client verifies. The default value is 1, which means that the client will only verify the server's certificate and not any intermediate certificates.

    # C
    mysql_ssl_set(conn, MYSQL_SSL_VERIFY_DEPTH, 2);
    
    # C++
    mysql_ssl_set(conn, MYSQL_SSL_VERIFY_DEPTH, 2);
    
    # Python
    conn = mysql.connector.connect(
        user="user",
        password="password",
        host="localhost",
        database="database",
        ssl_ca="ca.pem",
        ssl_cert="client-cert.pem",
        ssl_key="client-key.pem",
        ssl_verify_depth=2,
    )
    

    Troubleshooting

    If you are still having trouble connecting to MariaDB over SSL, you can try the following:

    • Check the server logs for any errors related to SSL.
    • Make sure that the firewall on both the client and server machines is allowing SSL traffic.
    • Try using a different SSL library.

    I hope this helps!


    ssl mariadb rhel7


    MariaDBのALTER TABLEコマンドを使いこなす!既存の列をNOT NULLに変更する方法

    MariaDBで既存の列をNOT NULLに変更するには、ALTER TABLEステートメントを使用します。このステートメントは、テーブル構造の変更に使用されます。手順以下のコマンドを実行して、MariaDBに接続します。以下のコマンドを実行して、列をNOT NULLに変更します。...


    データベースのセキュリティ対策に必須!MariaDB/MySQL テーブル暗号化のメリットと具体的な方法

    MariaDBとMySQLでは、テーブル暗号化という機能を提供し、データベース内のデータを暗号化して安全性を強化することができます。この機能は、機密性の高いデータを扱うアプリケーションにとって非常に有用です。MariaDB/MySQLのテーブル暗号化は、AES (Advanced Encryption Standard) という暗号化アルゴリズムを用いて、テーブルデータを暗号化します。暗号化には、暗号鍵と呼ばれるパスワードのような情報が必要となります。この暗号鍵は、データベースサーバーとは別の場所に保管する必要があります。...


    コマンド1つで解決!MySQL/MariaDBテーブルのDEFINERを確認する方法

    INFORMATION_SCHEMA テーブルを使用するMySQL 5.0.15 以降では、INFORMATION_SCHEMA. TABLES テーブルを使用して、テーブルの定義者を確認することができます。SHOW CREATE TABLE ステートメントを使用して、テーブルの作成定義を取得することができます。この定義には、定義者に関する情報も含まれています。...


    mysqli_multi_query() 関数を使用して複数の非同期 INSERT クエリを実行する

    このチュートリアルでは、PHP の MySQLI 拡張機能と MariaDB サーバーを使用して、非同期 INSERT クエリを実行し、処理を継続する方法を説明します。非同期 INSERT のメリット従来の同期 INSERT クエリとは異なり、非同期 INSERT はデータベースとのやり取りを待たずに処理を継続できます。これは、パフォーマンスとスループットを向上させるのに役立ちます。...


    MySQL Workbenchを使ってMariaDBユーザーのプラグインインストール権限を編集する方法

    MariaDBでは、セキュリティ上の理由から、デフォルトでユーザーにプラグインのインストール権限は付与されていません。プラグインをインストールするには、ユーザーに明示的に権限を与える必要があります。権限の付与MariaDBユーザーにプラグインインストール権限を付与するには、GRANTステートメントを使用します。以下の例では、user1ユーザーにALL PLUGINS権限を付与しています。...


    SQL SQL SQL SQL Amazon で見る



    MariaDBの柔軟なセキュリティ:TLSクライアント証明書で個別制御

    そこで、TLSを有効にしつつ、TLSなしの接続も許可する方法をご紹介します。方法MariaDBの設定ファイル(my. cnfなど)に以下の設定を追加します。この設定により、以下のようになります。デフォルトでは、TLSによる暗号化が要求されます。