MySQL Connection over SSH

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von haVok4.Purplehaze.

    MySQL Connection over SSH

    Guten Tag,

    meine Datenbank (MySQL) liegt auf einem Linux System. Zurzeit rufe ich sie über HeidiSql über einen SSH Tunnel (plink.exe) auf.
    Ich will mich gerne per VB.NET über diesen SSH Tunnel mit der Datenbank verbinden.

    Ist dies tendenziell möglich und wenn ja, wie sieht ein beispielhafter Code aus?

    Beste Grüße
    havok4

    haVok4.Purplehaze schrieb:

    per VB.NET über diesen SSH Tunnel mit der Datenbank verbinden.
    Warum das? Mach doch einfach einen ConnectionString, der auf den Server zeigt und fertig.
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    HeidiSQL ist ein SQL Client. Lass den doch weg
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    haVok4.Purplehaze schrieb:

    beispielhafter Code
    Könntest mal folgendes probieren: Visual Basic Windows Application: SSH.NET Verbindung aufbauen
    Damit sind aber nur INSERT und UPDATE Statements (sinnvoll) einsetzbar. Lesende Zugriffe lassen sich dadurch schwer realisieren. Dazu müsstest du das Feedback auslesen und parsen, dir die Einträge raussuchen und weiterverarbeiten.

    Um aber auf eine MySQL Datenbank unter einer (beliebigen) .NET Sprache zuzugreifen, kannst du auch deine Verbindung aufbauen und SSL verschlüsseln. Musst mal danach googlen
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Danke für den Beitrag. Der SSH Tunnel ist offen und die Verbindung zur MySQL Datenbank ist hergestellt.
    Ich muss jedoch auch andere SQL-Statements ausführen. Beim Ausführen des SELECT Befehls bekomme ich den Fehler: Fatal error encountered during command execution.

    Quellcode

    1. Dim strSQL As String
    2. Dim uUserDataTable As New DataTable
    3. strSQL = "SELECT id, identifier, email, username, creation_date, first_phone_number, second_phone_number, last_login, facebook_id FROM user"
    4. Try
    5. cmdObj = New MySqlCommand
    6. With cmdObj
    7. .Connection = uConnection
    8. .CommandText = strSQL
    9. End With
    10. Catch exSqlLoadUser As Exception
    11. MsgBox(Consts.EROR_LOAD_USER & exSqlLoadUser.Message, MsgBoxStyle.Exclamation, Consts.BASE_NAME)
    12. Form_Main.Close()
    13. End
    14. End Try
    15. uAdapter = New MySqlDataAdapter(strSQL, uConnection)
    16. uUserDataTable = New DataTable("UserInfo")
    17. uAdapter.Fill(uUserDataTable)
    18. uAdapter.Update(uUserDataTable)


    Jemand eine Idee, wie es funktionieren könnte ?
    Bei dem obigen Codeschnipsel springt er bei dem Füllen mit dem Adapter der DataTable raus.

    Ich hatte es ebenfalls folgendermaßen probiert, aber da springt er beim ExecuteNonQuery raus.

    Quellcode

    1. cmdObj = New MySqlCommand
    2. With cmdObj
    3. .Connection = uConnection
    4. .CommandText = strSQL
    5. .ExecuteNonQuery()
    6. End With
    nee, bleib mal beim obigen Code mit Adapter.Fill. Weil dass das Sql ühaupt ausgeführt wird, ist ja schoma kein so ganz schlechtes Zeichen.
    Probier lieber mal ein einfacheres Statement, etwa

    SQL-Abfrage

    1. Select * From user

    Auch interessant wäre, ob die Exception eine InnerException transportiert, wo evtl. weitere Infos enthalten sind.
    Ah - evtl ist user bei Heidi-Sql ein reserviertes Wort.
    Man soll Db-Objekte immer quoten, um Namenskonflikte mit reservierten Wörtern des jeweiligen Sql-Dialektes von vornherein auszuschließen. Also

    SQL-Abfrage

    1. Select * From `user`
    (ich hoffe, Heidi quoted mit BackTicks - sonst lies halt die Doku dazu)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    So sieht die Methode aus, die die den Tunnel öffnet und die Verbindung herstellt.

    Quellcode

    1. Dim connInfo As New Renci.SshNet.PasswordConnectionInfo(Consts.DB_SSH_SERVER, Consts.DB_SSH_USER, Consts.DB_SSH_PASSWORD)
    2. Using sshClient As New Renci.SshNet.SshClient(connInfo)
    3. sshClient.Connect()
    4. If sshClient.IsConnected Then
    5. Dim port As New Renci.SshNet.ForwardedPortLocal(Consts.DB_MYSQL_SERVER, 3306, Consts.DB_MYSQL_SERVER, 3306)
    6. sshClient.AddForwardedPort(port)
    7. port.Start()
    8. MsgBox("ssh tunnle opened")
    9. Dim strConnStr As String
    10. uConnection = New MySqlConnection
    11. strConnStr = "Server=" & Consts.DB_MYSQL_SERVER
    12. strConnStr &= ";Database=" & Consts.DB_MYSQL_DATABASE
    13. strConnStr &= ";UserID=" & Consts.DB_MYSQL_USER
    14. strConnStr &= ";Password=" & Consts.DB_MYSQL_PASSWORD
    15. uConnection.ConnectionString = strConnStr
    16. Try
    17. uConnection.Open()
    18. Catch exOpenConnection As Exception
    19. MsgBox(Consts.ERROR_OPEN_CONNECTION & exOpenConnection.Message, MsgBoxStyle.Information, Consts.BASE_NAME)
    20. GoTo sub_end
    21. End Try
    22. End If
    23. End Using
    24. MsgBox("mysql connection opened")
    Doch, darauf kommts (auch) an. Die Zeilen hätten ja auch in einer Methode stehen können, die noch 400 Zeilen mehr hat.
    Oder - was ebenfalls entscheidend ist - in einer Function mit Rückgabewert.
    Oder in einer Methode, der Parameter übergeben werden.
    Oder beides.
    Aber dank meiner Nachfrage weiß ich nu bescheid: Keine Parameter, kein Rückgabewert, und auch kein weiterer Code.

    Zur Lösung weiß ich leider nicht viel - ich kenne dieses Renci.SshNet.SshClient- Dingens nicht.
    Was mir auffällt, ist, dasss du es in einem Using-Block hast, also nachdem der Code durchlaufen ist, ist das darin erstellte SshClient-Objekt auch schon wieder verworfen.

    Auch kanns iwie garnet stimmen, dass das der ganze Code sein soll, denn deine Fehlerzeile taucht in diesem Stück Code ja garnet auf.

    Also wenn ich recht überlege, nachwievor vorne und hinten Ungereimtheiten.
    Hier nochmal der vollständige Code (Verbindung öffnen und User laden)

    Verbindung:

    Quellcode

    1. Public Sub openConnection()
    2. Dim connInfo As New Renci.SshNet.PasswordConnectionInfo(Consts.DB_SSH_SERVER, Consts.DB_SSH_USER, Consts.DB_SSH_PASSWORD)
    3. Using sshClient As New Renci.SshNet.SshClient(connInfo)
    4. sshClient.Connect()
    5. If sshClient.IsConnected Then
    6. Dim port As New Renci.SshNet.ForwardedPortLocal(Consts.DB_MYSQL_SERVER, 3306, Consts.DB_MYSQL_SERVER, 3306)
    7. sshClient.AddForwardedPort(port)
    8. port.Start()
    9. MsgBox("ssh tunnle opened")
    10. Dim strConnStr As String
    11. uConnection = New MySqlConnection
    12. strConnStr = "Server=" & Consts.DB_MYSQL_SERVER
    13. strConnStr &= ";Database=" & Consts.DB_MYSQL_DATABASE
    14. strConnStr &= ";UserID=" & Consts.DB_MYSQL_USER
    15. strConnStr &= ";Password=" & Consts.DB_MYSQL_PASSWORD
    16. uConnection.ConnectionString = strConnStr
    17. Try
    18. uConnection.Open()
    19. Catch exOpenConnection As Exception
    20. MsgBox(Consts.ERROR_OPEN_CONNECTION & exOpenConnection.Message, MsgBoxStyle.Information, Consts.BASE_NAME)
    21. GoTo sub_end
    22. End Try
    23. End If
    24. End Using
    25. MsgBox("mysql connection opened")
    26. sub_end:
    27. End Sub



    User laden:

    Quellcode

    1. Public Function loadUser() As DataTable '// Tab-Page: Benutzer
    2. Dim strSQL As String
    3. Dim uUserDataTable As New DataTable
    4. strSQL = "SELECT * FROM user"
    5. cmdObj = New MySqlCommand
    6. With cmdObj
    7. .Connection = uConnection
    8. .CommandText = strSQL
    9. End With
    10. Try
    11. uAdapter = New MySqlDataAdapter(strSQL, uConnection)
    12. uUserDataTable = New DataTable("UserInfo")
    13. uAdapter.Fill(uUserDataTable)
    14. uAdapter.Update(uUserDataTable)
    15. Catch exSqlLoadUser As Exception
    16. MsgBox(Consts.EROR_LOAD_USER & exSqlLoadUser.InnerException.ToString, MsgBoxStyle.Exclamation, Consts.BASE_NAME)
    17. uConnection.Close()
    18. Form_Main.Close()
    19. End Try
    20. Return uUserDataTable
    21. End Function


    Die DataTable wird dann zu der Main-Form zurückgegeben und soll das DataGridView füllen.

    Irgendwelche Fehler im Code?
    Schade das du das "Renci.SshNet.SshClient- Dingens" nicht kennst. :/

    haVok4.Purplehaze schrieb:

    Irgendwelche Fehler im Code?
    Ja, natürlich - sonst würdest du hier ja nicht fragen.

    Erste Massnahme wäre, alle TryCatchens zu entfernen.
    TryCatch schon in diesem Stadium der Entwicklung behindert dich nur beim Debuggen.

    Als nächstes wäre zu probieren, obs klappt, wenn du den SSHClient nicht in einem Using-Block erzeugst.
    Jo, mehr fällt mir erstmal nicht ein, ausser, obs nicht iwo im INet Doku oder Anwendungsbeispiele für das Tunnel-Dingens gibt.