MariaDB ed25519認証プラグイン徹底解説:セキュリティと実装

2025-05-27

ed25519認証プラグインとは

MariaDBは、ユーザーのパスワードを安全に保存し、ユーザーを認証するために様々な認証プラグインを提供しています。従来のmysql_native_passwordプラグインはSHA-1に基づいていましたが、SHA-1は現在では安全性が低いとされています。

ed25519認証プラグインは、Elliptic Curve Digital Signature Algorithm (ECDSA) を用いて、ユーザーのパスワードを安全に保存し、認証を行います。これは、OpenSSHでも使用されているのと同じアルゴリズムであり、Daniel J. Bernsteinによって作成された楕円曲線とコードに基づいています。

主な特徴と利点

  • 鍵の配布不要: sha256_passwordのようにクライアントに鍵を配布する必要がないため、運用がより便利です。
  • パスワードベース認証: ユーザーからは従来通りのパスワードによる認証として機能します。内部的に高セキュリティなアルゴリズムが使われているだけなので、ユーザー体験は変わりません。
  • 高いセキュリティ: SHA-1に代わる、より強力で現代的な暗号アルゴリズムであるed25519を使用することで、パスワードのセキュリティが大幅に向上します。

ed25519認証では、以下のようなチャレンジ&レスポンス方式で認証が行われます。

  1. サーバーからのチャレンジ: クライアントが接続を試みると、MariaDBサーバーはランダムな「ナンス(nonce)」と呼ばれる32バイトのデータをクライアントに送信します。
  2. クライアントでの署名: クライアントは、ユーザーのパスワードを秘密鍵として使用し、受け取ったナンスにEd25519デジタル署名を行います。
  3. 署名の送信: クライアントは生成した署名をサーバーに送り返します。
  4. サーバーでの検証: サーバーは、mysql.userテーブルに保存されているユーザーの公開鍵を使用して、クライアントから送られてきた署名が正当であるかを検証します。署名が検証されれば、認証成功となります。

このプロセスでは、実際のパスワードがネットワーク上を流れることがないため、盗聴によるパスワード漏洩のリスクが低減されます。

ed25519プラグインの利用方法

ed25519認証プラグインは、MariaDBのバージョン10.1.22以降で導入されました。

プラグインのインストール

デフォルトではインストールされていない場合があるため、MariaDBサーバーにプラグインをインストールする必要があります。

  • サーバー起動時にロードするように設定する場合: MariaDBの設定ファイル(例: my.cnf)に以下の行を追加します。
    [mariadb]
    plugin_load_add = auth_ed25519
    
  • 動的にインストールする場合(サーバー再起動不要):
    INSTALL SONAME 'auth_ed25519';
    

ed25519認証を使用するユーザーの作成/変更

ユーザーを作成または変更する際に、IDENTIFIED VIA ed25519句を指定して、ed25519認証プラグインを使用するように設定します。

  • 既存のユーザーの認証プラグインを変更する場合:
    ALTER USER 'username'@'hostname' IDENTIFIED VIA ed25519 USING PASSWORD('new_secret_password');
    
  • 新しいユーザーを作成する場合:
    CREATE USER 'username'@'hostname' IDENTIFIED VIA ed25519 USING PASSWORD('secret_password');
    
  • パスワードの強度: ed25519は非常に安全なアルゴリズムですが、それでも推測されにくい複雑なパスワードを使用することが重要です。
  • MySQL Workbenchとの互換性: MySQL WorkbenchはMariaDBのed25519認証プラグインを直接サポートしていない場合があります。この場合、SSL/TLS接続を使用するか、別のデータベース管理ツールを検討する必要があります。
  • クライアント側の対応: クライアントアプリケーションやライブラリがed25519認証に対応している必要があります。MariaDB Connector/CなどのMariaDB公式クライアントライブラリには、client_ed25519というクライアント認証プラグインが提供されています。


ed25519プラグインは、MariaDBのセキュリティを大幅に向上させますが、適切に設定されていないと接続の問題を引き起こすことがあります。

エラーメッセージ: ER_PLUGIN_IS_NOT_LOADED: Plugin 'auth_ed25519' is not loaded

原因
このエラーは、MariaDBサーバーがauth_ed25519プラグインをロードしていない場合に発生します。これは、以下のいずれかが原因で起こります。

  • プラグインファイルが見つからないか、権限の問題がある。
  • MariaDBの設定ファイル(my.cnfなど)でプラグインが有効になっていない。
  • プラグインがインストールされていない。

トラブルシューティング

  1. プラグインのインストール状態を確認
    MariaDBクライアントから以下のSQLを実行し、プラグインがロードされているか確認します。

    SHOW PLUGINS;
    

    結果にauth_ed25519ACTIVEと表示されていればロードされています。INACTIVEまたは表示されない場合はロードされていません。

  2. プラグインの動的インストール(サーバー再起動なし)

    INSTALL SONAME 'auth_ed25519';
    

    このコマンドが成功すれば、プラグインは即座に利用可能になります。ただし、MariaDBサーバーを再起動すると、この設定は失われる可能性があります(設定ファイルに記述しない限り)。

  3. MariaDB設定ファイルでの設定(推奨)
    my.cnf(またはmy.ini)を開き、[mariadb]または[mysqld]セクションに以下の行を追加します。

    [mariadb]
    plugin_load_add = auth_ed25519
    

    ファイルを保存し、MariaDBサーバーを再起動します。

  4. プラグインファイルの場所と権限の確認
    プラグインファイル(例: auth_ed25519.so)がMariaDBのプラグインディレクトリ(plugin_dir変数で示される場所)に存在し、MariaDBユーザーが読み取り権限を持っていることを確認します。SHOW VARIABLES LIKE 'plugin_dir';で場所を確認できます。

エラーメッセージ: ER_PLUGIN_AUTH_PLUGIN_CANNOT_LOAD: Authentication plugin 'client_ed25519' cannot be loaded または Access denied for user 'user'@'host' (using password: YES)

原因
これは通常、クライアントアプリケーションがed25519認証をサポートしていないか、対応するクライアント側プラグイン(client_ed25519)が利用できない場合に発生します。サーバーはed25519認証を要求しているのに、クライアントがそれに応えられないため、認証が失敗します。

トラブルシューティング

  1. クライアントライブラリのバージョン確認
    使用しているプログラミング言語のMariaDB/MySQLクライアントライブラリが、ed25519認証をサポートしているか確認してください。一般的に、MariaDB Connector/C、Java Connector/J、Node.jsのmariadbドライバーなど、MariaDB公式のコネクタは対応しています。古いMySQLクライアントライブラリや一部の汎用ODBCドライバなどは未対応の場合があります。

    • MariaDB Connector/C (C API)
      バージョン3.0以上が必要です。
    • MariaDB Connector/J (Java)
      バージョン2.x以上が必要です。
    • Node.js (mariadbパッケージ)
      バージョン2.x以上が必要です。
  2. クライアント側プラグインの確認(特にCクライアントの場合)
    C言語で開発されたアプリケーションや、mysqlコマンドラインクライアントを使用している場合、client_ed25519.so(または.dll)ファイルがクライアントのプラグインディレクトリに存在し、正しくロードされている必要があります。 mysqlコマンドラインクライアントで試行している場合、そのクライアントがMariaDBのクライアントライブラリでコンパイルされていることを確認してください。MySQLの古いクライアントでは接続できないことがあります。

  3. 接続文字列/設定の確認
    一部のクライアントライブラリでは、接続時に明示的に認証プラグインを指定する必要がある場合があります。例えば、JavaのJDBC URLにauthenticationPlugins=client_ed25519のようなパラメータを追加する必要があるかもしれません(これはライブラリによって異なります)。

  4. 互換性のないツール
    MySQL Workbench: MySQL WorkbenchはMariaDBのed25519認証プラグインを直接サポートしていません。MySQL Workbenchでed25519認証のMariaDBに接続しようとすると、Access deniedまたはAuthentication plugin 'client_ed25519' cannot be loadedのようなエラーが発生します。

    • 解決策: MySQL Workbenchの代わりに、DBeaver、DataGripなどのMariaDBとより互換性のあるデータベース管理ツールを使用するか、従来のmysql_native_passwordまたはsha256_password認証を使用するユーザーを別途作成し、それらのツールからはそのユーザーで接続することを検討してください。

エラーメッセージ: ERROR 1045 (28000): Access denied for user 'user'@'host' (using password: NO)

原因
このエラーは、パスワードが間違っているか、ユーザーのホストが許可されていない場合に表示されます。using password: NOと表示されていても、ed25519認証では内部的にパスワードが使用されているため、パスワードが誤っている可能性が高いです。

トラブルシューティング

  1. パスワードの再確認
    ユーザーを作成/変更した際に設定したパスワードが正しいか、大文字・小文字を含め正確に入力しているか確認します。パスワードに特殊文字が含まれる場合は、クォート('")が正しく使われているか、シェルのエスケープが適切に行われているか確認します。

  2. ユーザーのホストの確認
    CREATE USER 'user'@'host'またはALTER USER 'user'@'host'で指定したhostが、接続元のホストと一致しているか確認します。'%'は任意のホストを意味します。もし特定のIPアドレスやホスト名に限定している場合、それが間違っている可能性があります。

    SELECT user, host, plugin FROM mysql.user WHERE user = 'your_username';
    

    これでユーザーのホストとプラグインを確認できます。

  3. 権限の確認
    ユーザーに接続するための十分な権限があるか確認します。

    SHOW GRANTS FOR 'your_username'@'your_host';
    

MariaDBサーバーのログファイルに手がかりがないか確認する

どのような認証エラーが発生した場合でも、MariaDBサーバーのエラーログファイル(通常はhostname.errのような名前)を確認することは非常に重要です。ログには、より詳細なエラーメッセージや、プラグインロードの失敗に関する情報が含まれていることがあります。

  • ログファイルの場所: MariaDBの設定ファイル(my.cnf)のlog_error変数で指定されています。


ed25519認証を使用する際のポイントは、クライアントライブラリがed25519認証に対応していることです。公式のMariaDB Connectorはそのほとんどが対応しています。

事前準備: MariaDBサーバー側の設定

ed25519認証を利用する前に、MariaDBサーバー側でauth_ed25519プラグインを有効にし、ed25519認証を使用するユーザーを作成しておく必要があります。

  1. auth_ed25519プラグインの有効化: my.cnf (またはmy.ini) に以下を追加してMariaDBを再起動します。

    [mariadb]
    plugin_load_add = auth_ed25519
    

    または、MariaDBクライアントで動的にインストールします。

    INSTALL SONAME 'auth_ed25519';
    
  2. ed25519認証を使用するユーザーの作成:

    CREATE USER 'my_ed25519_user'@'localhost' IDENTIFIED VIA ed25519 USING PASSWORD('your_strong_password');
    GRANT ALL PRIVILEGES ON your_database.* TO 'my_ed25519_user'@'localhost';
    FLUSH PRIVILEGES;
    

    your_strong_passwordは安全なパスワードに置き換えてください。your_databaseも実際のデータベース名に置き換えてください。

Python

PythonでMariaDBに接続する場合、mariadbコネクタ(MariaDB公式)またはPyMySQL(MySQL互換ですがed25519対応版あり)が使えます。ここではMariaDB公式のmariadbコネクタを推奨します。

まず、ライブラリをインストールします。

pip install mariadb

Pythonコード例

import mariadb
import sys

# データベース接続情報
DB_CONFIG = {
    'host': 'localhost',
    'port': 3306,
    'user': 'my_ed25519_user',
    'password': 'your_strong_password',
    'database': 'your_database' # 実際のデータベース名
}

try:
    # MariaDBデータベースに接続
    conn = mariadb.connect(
        host=DB_CONFIG['host'],
        port=DB_CONFIG['port'],
        user=DB_CONFIG['user'],
        password=DB_CONFIG['password'],
        database=DB_CONFIG['database']
    )
    print("MariaDBにed25519認証で正常に接続しました!")

    # カーソルオブジェクトの作成
    cur = conn.cursor()

    # 例: データを挿入
    try:
        cur.execute("INSERT INTO users (name, email) VALUES (?, ?)", ("John Doe", "[email protected]"))
        conn.commit()
        print("データを挿入しました。")
    except mariadb.Error as e:
        print(f"データの挿入中にエラーが発生しました: {e}")
        conn.rollback() # エラー時はロールバック

    # 例: データを取得
    cur.execute("SELECT * FROM users")
    for (id, name, email) in cur:
        print(f"ID: {id}, Name: {name}, Email: {email}")

except mariadb.Error as e:
    print(f"MariaDBへの接続または操作中にエラーが発生しました: {e}")
    sys.exit(1)
finally:
    # 接続を閉じる
    if 'conn' in locals() and conn:
        conn.close()
        print("MariaDB接続を閉じました。")

Java

JavaでMariaDBに接続する場合、MariaDB公式のJDBCドライバーであるMariaDB Connector/Jを使用します。

まず、MavenまたはGradleで依存関係に追加します。

Maven

<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>3.2.0</version> </dependency>

Javaコード例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MariaDbEd25519AuthExample {

    // データベース接続情報
    private static final String DB_URL = "jdbc:mariadb://localhost:3306/your_database"; // データベース名
    private static final String DB_USER = "my_ed25519_user";
    private static final String DB_PASSWORD = "your_strong_password";

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            // MariaDB JDBCドライバーのロード(Java 6以降では不要な場合が多い)
            // Class.forName("org.mariadb.jdbc.Driver");

            // MariaDBに接続
            conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            System.out.println("MariaDBにed25519認証で正常に接続しました!");

            // 例: テーブルが存在しない場合は作成
            try (PreparedStatement createTable = conn.prepareStatement(
                    "CREATE TABLE IF NOT EXISTS users (" +
                            "id INT AUTO_INCREMENT PRIMARY KEY," +
                            "name VARCHAR(255) NOT NULL," +
                            "email VARCHAR(255) NOT NULL UNIQUE" +
                            ")"
            )) {
                createTable.executeUpdate();
                System.out.println("テーブル 'users' が存在しない場合は作成されました。");
            }

            // 例: データを挿入
            String insertSql = "INSERT INTO users (name, email) VALUES (?, ?)";
            pstmt = conn.prepareStatement(insertSql);
            pstmt.setString(1, "Jane Smith");
            pstmt.setString(2, "[email protected]");
            pstmt.executeUpdate();
            System.out.println("データを挿入しました。");

            // 例: データを取得
            String selectSql = "SELECT id, name, email FROM users";
            pstmt = conn.prepareStatement(selectSql);
            rs = pstmt.executeQuery();

            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String email = rs.getString("email");
                System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
            }

        } catch (SQLException e) {
            System.err.println("MariaDBへの接続または操作中にエラーが発生しました: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // リソースのクローズ
            try {
                if (rs != null) rs.close();
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
                System.out.println("MariaDB接続を閉じました。");
            } catch (SQLException e) {
                System.err.println("リソースのクローズ中にエラーが発生しました: " + e.getMessage());
            }
        }
    }
}

Node.js

Node.jsでMariaDBに接続する場合、mariadbパッケージを使用します。

まず、パッケージをインストールします。

npm install mariadb

Node.jsコード例

const mariadb = require('mariadb');

// データベース接続情報
const pool = mariadb.createPool({
    host: 'localhost',
    port: 3306,
    user: 'my_ed25519_user',
    password: 'your_strong_password',
    database: 'your_database', // 実際のデータベース名
    connectionLimit: 5
});

async function runExample() {
    let conn;
    try {
        conn = await pool.getConnection();
        console.log("MariaDBにed25519認証で正常に接続しました!");

        // 例: テーブルが存在しない場合は作成
        await conn.query(
            "CREATE TABLE IF NOT EXISTS users (" +
            "id INT AUTO_INCREMENT PRIMARY KEY," +
            "name VARCHAR(255) NOT NULL," +
            "email VARCHAR(255) NOT NULL UNIQUE" +
            ")"
        );
        console.log("テーブル 'users' が存在しない場合は作成されました。");

        // 例: データを挿入
        const resInsert = await conn.query("INSERT INTO users (name, email) VALUES (?, ?)", ["Bob Johnson", "[email protected]"]);
        console.log("データを挿入しました:", resInsert);

        // 例: データを取得
        const rows = await conn.query("SELECT id, name, email FROM users");
        console.log("取得したデータ:");
        rows.forEach(row => {
            console.log(`ID: ${row.id}, Name: ${row.name}, Email: ${row.email}`);
        });

    } catch (err) {
        console.error("MariaDBへの接続または操作中にエラーが発生しました:", err);
    } finally {
        if (conn) {
            conn.release(); // 接続をプールに戻す
            console.log("MariaDB接続をプールに返却しました。");
        }
    }
}

runExample();

PHP

PHPのmysqli拡張機能は、MariaDBのed25519認証を直接サポートしていません。これは、PHPのmysqlndライブラリが、MySQLの認証プロトコルに依存しているためです。MariaDB独自のed25519認証は、現在のところPHPのコア拡張機能では対応していません。

したがって、PHPからed25519認証を使用するには、以下のいずれかの方法を検討する必要があります。

  1. SSHトンネル/SSL接続を利用する: MariaDBサーバーへの接続自体はTLS/SSLで暗号化し、ed25519認証とは別の、PHPがサポートする認証方法(例: mysql_native_password)を、SSL/TLS経由で接続する特定のユーザーに対して使用する。これは認証自体をed25519にするわけではありませんが、通信のセキュリティを確保できます。

  2. mysql_native_passwordなどの代替認証を使用する: セキュリティ要件が許容する範囲で、より一般的な認証プラグインを使用します。ただし、これはed25519の最大の利点である高セキュリティなパスワード認証を放棄することになります。

  3. コミュニティ製のライブラリやパッチを探す: 非公式なコミュニティプロジェクトでed25519認証をサポートするPHPライブラリが存在する可能性がありますが、安定性やセキュリティの保証は公式のものに劣る場合があります。

PHPコード例 (一般的な接続方法、ed25519は直接サポートしないため注意)

<?php

// データベース接続情報
$host = 'localhost';
$user = 'my_ed25519_user'; // ed25519認証ユーザー、ただしPHPのmysqliはこれを直接理解しない
$password = 'your_strong_password'; // 実際には接続失敗する可能性が高い
$database = 'your_database';
$port = 3306;

// mysqliオブジェクトを作成
$mysqli = new mysqli($host, $user, $password, $database, $port);

// 接続エラーのチェック
if ($mysqli->connect_error) {
    die("MariaDBへの接続に失敗しました: " . $mysqli->connect_error);
}

echo "MariaDBに接続を試みました。\n";
echo "注意: PHPのmysqliはMariaDBのed25519認証を直接サポートしていません。\n";
echo "このコードは、ed25519ユーザーでは接続に失敗する可能性が高いです。\n";

// 例: データを取得
$sql = "SELECT id, name, email FROM users";
$result = $mysqli->query($sql);

if ($result) {
    if ($result->num_rows > 0) {
        echo "取得したデータ:\n";
        while($row = $result->fetch_assoc()) {
            echo "ID: " . $row["id"]. ", Name: " . $row["name"]. ", Email: " . $row["email"]. "\n";
        }
    } else {
        echo "データが見つかりませんでした。\n";
    }
    $result->free();
} else {
    echo "クエリ実行中にエラーが発生しました: " . $mysqli->error . "\n";
}

// 接続を閉じる
$mysqli->close();
echo "MariaDB接続を閉じました。\n";

?>

PHPでのed25519認証の課題: PHPのmysqlndは、MariaDBのed25519認証プロトコルを直接実装していません。そのため、ed25519で認証されたMariaDBユーザーに直接接続しようとすると、Authentication method unknown to the clientのようなエラーが発生します。これはPHPの将来のバージョンで改善される可能性がありますが、現状では注意が必要です。



ed25519認証は最も安全な認証方法の一つですが、特にレガシーなクライアントや特定のプログラミング言語のドライバでは、直接対応していないことがあります。そのような場合の代替手段として、以下の方法が考えられます。

TLS/SSL接続による通信経路の暗号化

これはed25519認証そのものの代替ではありませんが、認証情報の盗聴やデータ通信の改ざんを防ぐための最も重要な手段です。たとえ認証プラグインがmysql_native_passwordのような古いものであっても、TLS/SSLで接続を暗号化していれば、通信経路のセキュリティは大幅に向上します。

特徴

  • 広範なサポート: ほとんどのプログラミング言語とデータベースドライバがTLS/SSL接続をサポートしている。
  • 通信の機密性・完全性: ネットワーク上でのデータ盗聴や改ざんを防ぐ。
  • 認証のセキュリティ向上ではない: パスワード自体のハッシュ強度や認証プロトコルが変わるわけではない。

設定方法 (MariaDBサーバー側)

  1. TLS/SSL証明書と秘密鍵を生成または取得する。
  2. my.cnfにSSL関連の設定を追加する。
    [mariadb]
    ssl_ca   = /path/to/ca.pem
    ssl_cert = /path/to/server-cert.pem
    ssl_key  = /path/to/server-key.pem
    
  3. MariaDBサーバーを再起動する。

プログラミングでの利用例 (Python with mariadbコネクタ)

import mariadb
import ssl # SSLコンテキストを生成するため

# SSLコンテキストの作成
# 運用環境では、CA証明書、クライアント証明書、クライアント鍵を指定することが推奨されます
ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
# サーバーの証明書を検証する場合
ssl_context.load_verify_locations('/path/to/ca.pem')
# クライアント証明書認証を行う場合
# ssl_context.load_cert_chain(certfile='/path/to/client-cert.pem', keyfile='/path/to/client-key.pem')

DB_CONFIG = {
    'host': 'localhost',
    'port': 3306,
    'user': 'my_user_with_ssl', # SSL接続を許可するユーザー
    'password': 'my_password',
    'database': 'your_database',
    'ssl_context': ssl_context # SSLコンテキストを渡す
}

try:
    conn = mariadb.connect(**DB_CONFIG)
    print("MariaDBにSSL/TLSで正常に接続しました!")
    # ... 通常のデータベース操作
except mariadb.Error as e:
    print(f"MariaDBへの接続エラー: {e}")
finally:
    if 'conn' in locals() and conn:
        conn.close()

注意: SSL/TLSを使用する場合でも、MariaDBサーバー側でed25519認証を要求するユーザーを作成している場合、そのユーザーでは接続できない可能性があります。この代替手段は、mysql_native_passwordなどの認証プラグインを使用するユーザーと組み合わせて、通信の安全性を高めるために利用します。

認証にsha256_passwordプラグインを使用する

sha256_passwordプラグインは、SHA-256ハッシュアルゴリズムを使用してパスワードを保存し、より強力な認証を提供します。ed25519ほど最新ではありませんが、mysql_native_passwordよりははるかに安全です。

特徴

  • 公開鍵の配布が必要な場合がある: クライアントがパスワードを平文で送信するのを避けるために、サーバーの公開鍵をクライアントに配布する必要がある場合があります。
  • ed25519より広範なクライアントサポート: ed25519よりは多くのクライアントライブラリでサポートされている可能性が高い(特に古いMySQL互換ライブラリ)。
  • 高いセキュリティ: SHA-256を使用するため、SHA-1より安全。

設定方法 (MariaDBサーバー側)

  1. ユーザーを作成または変更する際にIDENTIFIED VIA sha256_passwordを指定する。
    CREATE USER 'my_sha256_user'@'localhost' IDENTIFIED VIA sha256_password USING PASSWORD('your_strong_password');
    GRANT ALL PRIVILEGES ON your_database.* TO 'my_sha256_user'@'localhost';
    FLUSH PRIVILEGES;
    

プログラミングでの利用例 (Python with mariadbコネクタ)
ed25519と同様に、通常は特別な設定は不要です。ライブラリが自動的にプラグインを検出して処理します。

import mariadb

DB_CONFIG = {
    'host': 'localhost',
    'port': 3306,
    'user': 'my_sha256_user',
    'password': 'your_strong_password',
    'database': 'your_database'
}

try:
    conn = mariadb.connect(**DB_CONFIG)
    print("MariaDBにsha256_password認証で正常に接続しました!")
    # ... 通常のデータベース操作
except mariadb.Error as e:
    print(f"MariaDBへの接続エラー: {e}")
finally:
    if 'conn' in locals() and conn:
        conn.close()

SSHトンネリング

SSHトンネリングは、データベース接続をSSH接続内にカプセル化することで、暗号化された安全なチャネルを構築する方法です。特に、データベースサーバーが直接インターネットに公開されていない場合に有効です。

特徴

  • データベースドライバの変更不要: データベースドライバはローカルのポートに接続するだけでよく、SSHトンネルの存在を意識する必要がない。
  • 認証の分離: データベース認証とは別にSSH認証(公開鍵認証など)を組み合わせられる。
  • 強力なセキュリティ: SSHプロトコルによって通信が暗号化されるため、非常に安全。

設定方法

  1. SSHサーバーの設定: データベースサーバーがSSH接続を受け付けるように設定されていることを確認。
  2. トンネルの確立: クライアント側でSSHトンネルを確立する。
    ssh -L 3307:localhost:3306 user@your_ssh_server_ip
    
    これは、ローカルの3307番ポートへの接続を、your_ssh_server_ipを経由してリモートのlocalhost:3306(MariaDBサーバー)へ転送するトンネルを作成します。

プログラミングでの利用例
アプリケーションからは、SSHトンネルで指定したローカルのポート(例: 3307)に接続するだけです。データベースのユーザー認証プラグインは、mysql_native_passwordでもsha256_passwordでも、あるいはed25519であっても(クライアントが対応していれば)使用できます。SSHトンネルが通信経路を暗号化します。

import mariadb

# SSHトンネルを経由してローカルのポートに接続
DB_CONFIG = {
    'host': '127.0.0.1', # ローカルホスト
    'port': 3307,        # SSHトンネルで転送されたポート
    'user': 'your_mariadb_user', # MariaDBの通常のユーザー
    'password': 'your_mariadb_password',
    'database': 'your_database'
}

try:
    conn = mariadb.connect(**DB_CONFIG)
    print("MariaDBにSSHトンネル経由で正常に接続しました!")
    # ... 通常のデータベース操作
except mariadb.Error as e:
    print(f"MariaDBへの接続エラー: {e}")
finally:
    if 'conn' in locals() and conn:
        conn.close()

プロキシサーバー/中間層の導入

より複雑なケースですが、専用のプロキシサーバー(例: MaxScale, ProxySQL, HAProxyなど)をMariaDBの前に配置し、そのプロキシがed25519認証を処理し、クライアントからプロキシへの接続は別の認証方法を使用するという方法です。

特徴

  • 複雑性: 設定と運用が複雑になる。
  • 集中管理: 認証、ルーティング、ロードバランシングなどをプロキシで一元管理できる。
  • 柔軟性: クライアントとデータベースの認証方式を分離できる。

利用例

  • MaxScale: MariaDB MaxScaleは、MariaDBの公式プロキシであり、様々な認証プラグインをサポートしています。クライアントはMaxScaleに接続し、MaxScaleがed25519認証を使用してバックエンドのMariaDBに接続するという構成が可能です。

ed25519認証が直接利用できない場合の代替手段は、大きく分けて以下のシナリオで使い分けます。

  • 大規模な環境で認証やルーティングを柔軟に制御したい場合: プロキシサーバー
  • 非常にレガシーなクライアントを使用せざるを得ず、かつ高セキュリティが必要な場合: SSHトンネリング
  • パスワードハッシュの強度を向上させたいが、ed25519が使えない場合: sha256_password
  • 通信経路のセキュリティ確保が最優先で、認証方式は問わない場合: TLS/SSL接続またはSSHトンネリング