C#を始めよう|SSHでXSERVERのMySQLに接続

C#でXSERVERのMySQLを使ったプログラムを作る必要があったのですが、最初は簡単にできると思っていたのですが、かなり手こずったので完成した結果を記録に残します。

XSERVERのSSHキー

前提としてXSERVERのSSHキー(秘密の鍵)を取得していることです。

⇩秘密の鍵の取得方法

SSH設定 | レンタルサーバーならエックスサーバー
レンタルサーバー「エックスサーバー」のご利用マニュアル|エックスサーバーではSSH接続機能を提供しています。当マニュアルではお客様のサーバーアカウントへSSHで接続するための手順を記載しています。



処理の順番

接続から解放までの順番。

  1. sshキーを取得
  2. ssh接続
  3. ポートフォワーディング開始
  4. MySQL接続
  5. 任意のSQL文を発行して必要なロジックを実行
  6. MySQL解放
  7. ポートフォワーディング終了
  8. ssh解放

凄く簡単ですがこのような流れになります。

必要な情報

C#でコードを書く上で必要になるXSERVERに関係する内容です。

sshキー

sshキーを取得してダウンロードされて、それを保存しているパス。

sshキー取得時に設定したパスフレーズ。

sshキーは無くさないように分かりやすいフォルダに保管したほうがいいでしょう。
sshキー取得時に入力したパスフレーズは忘れないように何かに書き留める等して忘れないようにして下さい。

サーバーID

サーバーパネルにログインする時に使っているサーバーIDとパスワードです。

サバーIDはサーバーパネルで確認できます。

サーバーパネルのアカウントデータに表示されています。

サーバーパネルログインパスワード

サーバーパネルログインパスワードはどこにも表示されないので、契約時に決定した内容です。

契約時の内容はテキスト形式等で大事に保管することをお勧めします。

サーバーアドレス

  

サーバーアドレスはサーバーパネルのサーバー情報で確認できます。

ホスト名、もしくはIPアドレスを使用します。

SSH接続ポート

通例では接続ポートは22ですが、SSH接続では10022になります。

ローカルアドレス

127.0.0.1にしました。

他のアドレスでも可能だと思うのですが、試していません。

ローカルポート

13306にしました。

使われていないポートであれば任意のポートいいようです。

XSERVER MySQLアドレス

 

サーバーパネルのMySQL設定で確認することが出来ます。

MySQLホスト名、もしくはMySQLIPアドレスの内容を使用します。

 

XSERVER MySQLポート

標準的な3306ポートを使用します。

XSERVERのMySQLのデータベースに接続するユーザーID

 

サーバーパネルのMySQL設定、MySQL一覧で確認できます。

アクセス権所有ユーザーをクリックしてみて下さい。
xxxxxx(サーバーアドレス)が表示されるので、()の前のxxxxxxがアクセス権を所有したユーザーIDになります。

 

データベースに接続するパスワード

データベースに接続するユーザーIDのパスワードになります。

確認にすることはできませんが、データベースに接続可能なユーザーIDを設定したときに指定したパスワードになります。

XSERVERのMySQLのデータベース

サーバーパネルのMySQL設定で確認することができます。

データベース名はサーバーID_xxxxxxとなっているはずです。

データベースにアクセスするユーザーID

サーバーパネルのMySQL設定で確認できます。

接続対象となるデータベースのアクセス権所有ユーザです。

アクセス権所有ユーザーのパスワード

これはMySQL設定のMySQLユーザ追加時に設定したパスワードが必要です。

見ることが出来ないので、忘れてしまったら対象ユーザーIDに対してパスワードを変更することができます。

ライブラリ

SSHとMySQLを使うので関連するライブラリをインストールします。

SSHSSH.NETVisual StudioであればNuGetパッケージの管理
MySQLMySql.DataVisual Studioであれば参照追加

SSHとポートフォーワディングのコード

using System;
using Renci.SshNet;     //  ①
//  *******************************************************************
//  SSHでXSERVERのMySQLに接続する
//  *******************************************************************
class Ssh
{
    const   string  ServeAddress        =   "999.999.999.999";                  //  ②
    const   int     SshPort             =   10022;                              //  ③
    const   string  ServerUserId        =   "xxxxxxxxxxxx";                     //  ④
    const   string  ServerPassword      =   "xxxxxxxx";                         //  ⑤
    const   string  SshKey              =   @"C:\xxxxxx\xxxxxxxxxxxxxxxx.key";  //  ⑥
    const   string  SshKeyPassPhrase    =   "xxxxxxxx";                         //  ⑦

    const   string  LocalAddress        =   "127.0.0.1";                        //  ⑧
    const   int     LocalPort           =   13306;                              //  ⑨
    const   string  MySqlAddress        =   "999.999.999.999";                  //  ⑩
    const   int     MySqlPort           =   3306;                               //  ⑪

    public  const   bool    ConstOK             =   true;
    public  const   bool    ConstNG             =   false;

    public  SshClient   SshClient;

    public  ForwardedPortLocal  ForwardedPortLocal;
    //  *******************************************************************
    //  SSHでXSERVERのMySQLに接続する
    //  *******************************************************************
    public  bool    SshConnect()
    {
        //  SSH接続
        try
        {
            var _PassAuth = new PasswordAuthenticationMethod(ServerUserId, ServerPassword);   // パスワード認証
            // 秘密鍵認証
            var _PrivateKey = new PrivateKeyAuthenticationMethod(ServerUserId, new PrivateKeyFile[]
            {
                 new PrivateKeyFile(SshKey, SshKeyPassPhrase) 
            });
            // 接続情報の生成
            ConnectionInfo  ConnNfo   = new ConnectionInfo(ServeAddress, SshPort, ServerUserId,new AuthenticationMethod[]
            {
                _PassAuth,          // パスワード認証
                _PrivateKey,        // 秘密鍵認証
            });
            SshClient = new SshClient(ConnNfo);                 //  sshクライアント生成
            SshClient.Connect();                                //  ssh接続
            if(!SshClient.IsConnected)
            {
                Console.WriteLine("SSH Connection Error No1");
                return  ConstNG;
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine("SSH Connection Error No2");
            Console.WriteLine(ex.Message);
            return  ConstNG;
        }
        return  ConstOK;
    }
    //  *******************************************************************
    //  SSHクローズ
    //  *******************************************************************
    public  void    SshDeconnect()
    {
        SshClient.Disconnect();
    }
    //  *******************************************************************
    //  ポートフォワーディング開始
    //  *******************************************************************
    public bool PortForwardStart()
    {
        try
        {
            ForwardedPortLocal  =   new ForwardedPortLocal(LocalAddress,LocalPort,MySqlAddress,MySqlPort);
            SshClient.AddForwardedPort(ForwardedPortLocal);
            ForwardedPortLocal.Start();
            if (!ForwardedPortLocal.IsStarted)
            {
                Console.WriteLine("forwardedPortLocal ERROR No1");
                return  ConstNG;
            }
            //  var BoundHostaddress    =   ForwardedPortLocal.BoundHost;
            //  var BoundHostPort       =   ForwardedPortLocal.BoundPort;
        }
        catch(Exception ex)
        {
            Console.WriteLine("forwardedPortLocal ERROR No2");
            Console.WriteLine(ex.Message);
            return  ConstNG;
        }
        return  ConstOK;
    }
    //  *******************************************************************
    //  ポートフォワーディング終了
    //  *******************************************************************
    public void PortForwardStop()
    {
        ForwardedPortLocal.Stop();
    }
}

SSSとポートフォワーディングをまとめたクラスを作りました。

メソッドの機能

メソッド機能
SshConnect()SSH接続開始
SshDeconnect()SSH接続解除
PortForwardStart()ポートフォワーディング開始
PortForwardStop()ポートフォワーディング終了

①~⑪の説明

番号説明
SSH.NETを使用
XSERVERのIPアドレス、もしくはサーバーのホスト名
ホスト名の例:sv9999.xserver.jp
XSERVERのSSH接続は10022
サーバーのユーザーID
サーバーパネルにログインするパスワード
SSHキーファイルのフルパス
XSERVERでSSHキーを取得した時のパスフレーズ
ローカルプログラムからアクセスするローカルアドレス
ローカルポート
XSERVERのMySQLのIPアドレスもしくはMySQLのホスト名
MySQLホスト名の例:mysql9999.xserver.jp
XSERVERのMySQLポート

XSERVERのMySQLに接続するコード

先程作ったclass Sshを使ってXSERVERのMySQLに接続するコードの抜粋です。

通常の接続と異なるところはMySQLサーバーに接続するのではなくポートフォワードに接続するようになります。

using System;
using MySql.Data.MySqlClient;   //  ①

class MySQL
{
    public MySqlConnection Connection = new MySqlConnection();
    public bool     CONST_OK = true;
    public bool     CONST_NG = false;
    public string   CONST_Server = null;                            //  ②
    public uint     CONST_Port  =   0;                              //  ③
    public string   CONST_UserId = "xxxxxxxxxxxxxxxx";              //  ④
    public string   CONST_Password = "xxxxxxxx";                    //  ⑤
    public string   CONST_Database = "xxxxxxxxxxxxxxxxxxxxxxx";     //  ⑥

    Ssh Ssh =   new Ssh();                          //  ⑦   ssh接続クラス
    //  ***********************************************************
    //  MySQL(sssproduct)接続
    //  ***********************************************************
    public bool Connect()
    {
        //  ssh接続
        if ( Ssh.SshConnect() == Ssh.ConstNG  )
        {
            Console.WriteLine("SSH接続エラー");
            return  CONST_NG;
        }
        //  ポートフォワーディング開始
        if ( Ssh.PortForwardStart() ==  Ssh.ConstNG )
        {
            Console.WriteLine("ポートフォワーディング開始");
            return  CONST_NG;
        }

        try
        {
            CONST_Server    =   Ssh.ForwardedPortLocal.BoundHost;  // ⑧
            CONST_Port      =   Ssh.ForwardedPortLocal.BoundPort;  // ⑨
            Connection.ConnectionString = string.Format("Server={0};Database={1};Uid={2};Pwd={3};Port={4};Pooling=False;",
                CONST_Server, CONST_Database, CONST_UserId, CONST_Password,CONST_Port);
            Connection.Open();
        }
        catch (MySqlException e)
        {
            Console.WriteLine(string.Format("DATABASE:{0} CONNECT ERROR",CONST_Database));
            Console.WriteLine(e.Message);
            return CONST_NG;
        }
        return CONST_OK;
    }
    //  ***********************************************************
    //  MySQL(sssproduct)解放
    //  ***********************************************************
    public void DeConnect()
    {
        Ssh.PortForwardStop();
        Ssh.SshDeconnect();
        Connection.Close();
    }
}

メソッドの解説

メソッド説明
Connect()XSERVERのMySQLデータベースに接続します。

データベースに接続する前にSSHとポートフォワーディングを開始します。

DeConnect()XSERVERのMySQLデータベース接続を解放します。

データベースを解放する前にポートフォワーディングとSSHを終了します。

①~⑨の解説

番号解説
MySql.Dataを使用
ポートフォワードで取得した値を代入
ポートフォワードで取得した値を代入
XSERVERのMySQLのデータベースに接続するアクセス権所有ユーザーID
アクセス権所有ユーザーIDのパスワード
XSERVERのMySQLのデータベース名
SSH・ポートフォワーディング関連のクラスをインスタンス
ポートフォワードのホストを代入
ポートフォワードのポートを代入

接続が確立できたら通常のデータベース操作と同様です。

コメント

  1. あおきち より:

    貴重な情報ありがとうございます。
    これまでPuTTYを使う方法しか知らなかったので、大変参考になりました。
    これらのクラスを実際に使用してDBにクエリを発行するサンプルコードまであると、もっと喜ぶ人が増える記事だと思いました。