MariaDB over SSL 接続で「certificate verify failed」エラーが発生した場合のトラブルシューティング
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