🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

1769閲覧

MySQLにログインできません。

kitakitune

総合スコア9

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

2グッド

2クリップ

投稿2023/05/25 11:01

編集2023/05/25 11:10

実現したいこと

実現したいこと
以下の条件で、
クライアント(VB.NETフォームアプリ)から
サーバー(os:ubuntu 22.04.02 LTS)のデータベース(MySQL 8.0.33)に接続する。
(現在は、同一LAN内での接続です。)

条件
1. クライアントとサーバー間はSSHで接続する。
2. サーバ(Ubuntu)のファイアーウォールの設定は、
Incomig、基本deny としssh用ポートのみ Action:allow, From:anywhere とする。
3.MySQLの設定で、bind-addressは‘127.0.0.1’とする。
4.MySQLにログインするMySQLのユーザーは 'xxx'@'localhost'とする。

前提

DBサーバーは、OS:ubuntu 22.04.02 LTS DBMS:MySQL 8.0.33にて作成しました。
クライアントはOS:Windows11でサーバに接続するプログラムは、VB.NET で作成しました。

クライアントよりサーバーのデータベースに接続するのにMySQLのバインドアドレスを0.0.0.0として
Mysqlプロトコルで直にサーバーのMySQLの待ち受けポートに接続するのは好ましくないと考えました。

SSH接続で接続した後、ポート転送をして接続をすれば、
MySQLのバインドアドレスも0.0.0.0から127.0.0.1に変更でき
ユーザーもローカルホストのユーザーでMySQLログインできることで、
セキュリティの向上を実現できると思い実装したつもりが、思うように動作しません。

以下の手順で実装できると考えコーディングしました。
1.サーバーにSSH接続する
2.ポートを転送する
3.MySQLにログインする

発生している問題・エラーメッセージ

以下のコード最終行 ‘mysql_conn.Open()’の所で例外が投げられます。
エラーメッセージは次の通りです。
MySqlException:Reading from the strem has failed.
EndOfStreamException: ストリームの末尾を越えて読み取ろうとしました。

### 該当のソースコード VB.net で作成したフォームアプリ 接続に関連している部分の抜粋です。 ソースコード 01 Imports Renci.SshNet 02 Imports MySql.Data.MySqlClient ----------------------------------------------------------------------------------------------- 03 Public Class Mainform 04 'SSH接続設定 05 Private Const ssh_host As String = 192.168.10.36 'リモートホストのIPアドレス 06 Private Const ssh_port As Integer = 2222 'サーバ側SSHの待ち受けport番号(デフォルト値を変更しています。) 07 Private Const ssh_user As String = "aaa" 'サーバーのユーザー名 08 Private ssh_key = New PrivateKeyFile("C:\Users\user\Documents\aaa\id_rsa.pem","pass01") '("秘密キーのパス", "キーのパスフレーズ")' 09 Private ssh_mthd = New PrivateKeyAuthenticationMethod(ssh_user, ssh_key) 10 Private ssh_cninf = New ConnectionInfo(ssh_host, ssh_port, ssh_user, ssh_mthd) 11 Private ssh_client = New SshClient(ssh_cninf) 12 ' ポートフォワーディング設定 13 Private Const localPort As Integer = 5001 'クライアントSSH接続用ポート 14 Private Const remotePort As Integer = 3306 'サーバーのMySQL用ポート番号(デフォルト) 15 Private fpl = New ForwardedPortLocal("127.0.0.1", localPort, ssh_Host, remotePort) 16 'DB接続設定 17 Private mysql_conn As MySqlConnection 18 Private Const mysql_db As String = "schm01" '対象データベース 19 Private Const mysql_user As String = "bbb" 'MySQLのユーザー名 20 Private Const mysql_pswd As String = "pass02" 'bbbのMySQLパスワード ・・・・・ ----------------------------------------------------------------------------------------- 21 Sub New() 22 InitializeComponent() 23 'SSH接続 24 Try 25 ssh_client.Connect() 26 Catch ex As Exception 27 MessageBox.Show("サーバーに接続できません", "SSH接続", MessageBoxButtons.OK) 28 End Try 29 'SSH接続確認 30 If ssh_client IsNot Nothing AndAlso ssh_client.IsConnected Then 31 MessageBox.Show("接続OK", "サーバーSSH接続", MessageBoxButtons.OK) 32 End If 33 'ポート転送 34 Try 35 ssh_client.AddForwardedPort(fpl) 36 fpl.Start() 37 Catch ex As Exception 38 MessageBox.Show("転送失敗 :" & ex.Message, "ポートフォワーディング ", MessageBoxButtons.OK) 39 End Try 40 'ポート転送確認 41 If fpl.isstarted Then 42 MessageBox.Show("転送OK", "sshポート転送", MessageBoxButtons.OK) 43 End If 44 'MySQLログイン 45 Dim cnstr As String = $"server={fpl.BoundHost};" & 46 $"port={fpl.BoundPort};" & 47 $"database={mysql_db};" & 48 $"user={mysql_user};" & 49 $"password={mysql_password}" 50 mysql_conn = New MySqlConnection(cnstr) 51 mysql_conn.Open() ### 補足情報(FW/ツールのバージョンなど) 上記コーディングで31行目と42行目では正常に動作している(と自分は考える)メッセージが表示されるので、 51行目のOpenメソッドはサーバー内部からの操作だから、 MySQLのbind-addressを‘127.0.0.1’とすると接続できない理由が自分には理解できません。 MySQLの設定で、bind-addressを‘0.0.0.0’とすると MySQLのユーザー 'bbb'@'%' ではMySQLにログイン出来て正常にクエリを発行できます。 また上記コードでSSH接続するサーバーのユーザー、およびMySQLのユーザーで 「MySQL Workbenchで同一クライアント機よりサーバーへの接続してMySQLにログインすること」 「Tera Termを使用でSSH公開鍵認証によりサーバーへの接続してMySQLにログインすること」 はできています。 一応、MySQLへの接続文字列を、記述しておきます。 server=127.0.0.1; port=5001; database=schm01; user=bbb; password=pass02 最後まで、目を通していただきありがとうございます。 よろしくお願いいたします。
emerald👍を押しています
emeraldを押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kitakitune

2023/05/26 13:52

はい。そうです。
kikukiku

2023/05/29 07:22

運営の対応は素晴らしいと思います。 大変かと思いますが、今後も宜しくお願い致します。
guest

回答1

0

ベストアンサー

これで解決するかは分かりませんが、条件4番でアカウントが外部からの接続を拒否しているからプログラムからログインできないだけではないのでしょうか?。

VBNetでの開発はあまり無いので自信はないのですが、43行目より前の接続情報とそれ以降の接続情報が同一では無い可能性があります。

仮にSSH越しでSQLログインをする場合SSH接続後、コマンドを注入する形にプログラムを記述する必要があると思います。

ですがサンプルコードだと、別のパッケージを呼び出して別の接続を確立させようとしている様に見えます。

仮に別の接続を確立しようとしている場合、SSHからSQLを実行するパッケージの作成をする必要があると思われます。

投稿2023/05/26 11:02

編集2023/05/26 11:10
emerald

総合スコア42

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kitakitune

2023/05/26 13:50

ご回答ありがとうございます。 >これで解決するかは分かりませんが、 >条件4番でアカウントが外部からの接続を拒否しているから >プログラムからログインできないだけではないのでしょうか?。 自分の実現したいことは MySQLが外部(ローカルホスト以外)からの接続を拒否している状態 (MySQLのバインドアドレスが127.0.0.1の状態)で、 プログラムから、ログインできるようにすることです。 サーバーにサーバーのユーザーとしてSSH接続し そののち、サーバー上からローカルホストのMySQLユーザーとしてMySQLにログインする。 という手順を踏めば上記のことを実装できるのではないかと考えました。 'xxx'@'%'というユーザであれば、MySQLのバインドアドレスを0.0.0.0とすれば ログインでき、クエリも発行できております。 >ですがサンプルコードだと、別のパッケージを呼び出して別の接続を確立させようとしている様>>に見えます。 とのご指摘頂きました。全くご指摘の通りの動作です。 自分もその点を疑い、bind-addressが0.0.0.0で接続は確立しているのは、 別の接続を確立して接続しているのかと考えました。 44行目の前に‘fpl.Stop()’として転送を切断してみてプログラムを実行したところ。 MySQLにログインできませんでした。 よって(付け焼刃的な試行ですが)51行で行っているopenメソッドは それ以前のSSH接続・ポート転送と無関係ではないようです。 だからと言って‘別の接続を確立して接続している’かどうかはわからないのですが・・・。 >仮にSSH越しでSQLログインをする場合SSH接続後、コマンドを注入する形にプログラムを記述>する必要があると思います。 ご指摘は、(SSH接続後)MySQLへのログインコマンド(openメソッド)と SSHの接続・ポート転送の紐づけが必要だという意味と理解しましたが、 自分もその点についてはそのとおりだと思います。 この点については、 接続文字列中のserverとportパラメータが、 それ以前のポート転送のコーディングで fpl.Start()とし、そのfplより得られる値(fpl.BoundHost、fpl.Boundport)を参照しているので、 SSH接続・ポート転送でサーバー(127.0.01)よりMySQLにログインできるのだと考えました。 >仮に別の接続を確立しようとしている場合、 >SSHからSQLを実行するパッケージの作成をする必要があると思われます。 自分の実現したいことは‘SSHからSQLを実行する’ことにつきます。 自分のコーディングには大きな誤解・理解不足があると思われます。 エラーログを調べてみたり、 バインドアドレスと接続文字列をいろいろいじって試してみたりしております。 取り急ぎご返信いたします。
emerald

2023/05/26 23:38

返信ありがとうございます。 >fpl.Start()とし、そのfplより得られる値(fpl.BoundHost、fpl.Boundport)を参照しているので、 >SSH接続・ポート転送でサーバー(127.0.01)よりMySQLにログインできるのだと考えました。 なるほど、Renci.SshNetの中身を詳しくわかっていないので少しSQLのパッケージについて調べてみたのですが、現在利用しているSQLのパッケージがRenci.SshNetに対応していない可能性が高いです https://mysqlconnector.net/tutorials/connect-ssh/ 利用するべきパッケージは下記のものです。 https://www.nuget.org/packages/MySqlConnector/ 提供されているソースコードのものはこれですかね。 https://www.nuget.org/packages/MySql.Data/ やはり問題は、SQLのパッケージにありそうですね。
emerald

2023/05/26 23:53

仮に問題がRenci.SshNetに起因する場合、今の私の持ってる知識じゃ解決するのは難しそうですね...。 一応VBNETでもMySqlConnectorというパッケージがインストールできるところまでは確認しました。 なので、SQLパッケージを置き変えるだけで接続ができるかもしれません。
kitakitune

2023/05/27 02:36

いろいろ調べていただきありがとうございます。 >SQLのパッケージがRenci.SshNetに対応していない可能性が高いです そういう可能性にはには、思い至りませんでした。 御呈示頂いたサイトを参考にして、結果を報告させて頂きます。 自分の理解が追いついていないので数時間でというのはちょっと無理なのですが・・・。 数日というスパンにはなると思いますが、結果は必ず投稿させて頂きます。 ありがとうございました。
kitakitune

2023/05/29 05:37

結果から報告さっせて頂きます。 現在の所、未だ解決には至っておりません。 emerald様よりのアドバイスをもとにやったことは、以下の通りです。 1。御指摘のサイトを開き、自分の環境に合わせて、VB.NETでコーディングして検証しました。   C# については初見でしたので、時間はかかりましたが、SSH接続やポート転送については定義とメソッ         ドの実行なので私が記述した旧コードと対照しながら自分なりの理解のもとで、少し手を加えて検証して      みましたが上手く機能しませんでした。状況は同じで、バインドアドレス0.0.0.0では接続できるけれど、 127.0.0.1とするとオープンで例外が発生しログインできませんでした。 この時点では、MySQLへの接続は、 MySql.Data.MySqlClient をインポートして使用していました。 想像するに、御指摘の通り違う接続を確立して、そちらの経路で接続しているのだと考えます。 2.MySql.Data をアンインストールして MySQLConnector をインストールしてやり直したところ、   やはりバインドアドレスの状態による接続状態に変わりはありませんでした。    自分の考えでは、定型的な処理でそれほど実装に手間取ることはなかろうと思っていたのですが、 甘かったようです。 実行中のプログラムでの検証はこれ以上無理と判断して、接続に限ったソフトを作成して 検証してみようと思います。 emerald様には いろいろと、不快な思いもさせてしまったかとも思います。 どうか、御容赦ください。 当事者となってしまった自分としては、ここでことの是非を主張する事は憚られますが、 Suf...さんの論理が破たんしていることは明らかです。 emerald様の主張に感情的な反論以上のことはできないと考えます。 おそらく、最後の貴方の投稿に回答を得ることもできないでしょう。 もう少し、論理的な主張が出来ているのなら、反論のしようもあるのですが、 Suf...さんは感情に走りすぎているように私には感じられます。 Suf...さんが私を嘘つきだと指摘しましたが、根拠なく他人に対して嘘をついたときめつけることは、 私の属するコミュニティではどこにおいても許されるものではありません。 (そういう言葉を、簡単に発すること自体その人の品性・知性を疑われます。) Suf...さんがそのような言葉を残したことで、その根拠を問い、運営に正否を問うこともできるかと思いますが 彼の人の知識によって手助けとなる人もいるであろうことを考えると二の足を踏みます。 一旦、このスレは終了しようと思います。 検証の過程で、いろいろと知らぬ知識に触れられたことにも感謝していることを 付け加えさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問