无法使用 JDBC 连接通过 SSH 隧道连接到 Azure DB

Posted

技术标签:

【中文标题】无法使用 JDBC 连接通过 SSH 隧道连接到 Azure DB【英文标题】:Failing to connect to Azure DB via SSH-Tunnel using a JDBC connection 【发布时间】:2020-09-24 20:27:48 【问题描述】:

我。 出于安全原因,我无法直接访问 Azure DB,但我有一个跳转服务器/隧道 VM,可用于间接连接到 DB。

从隧道 VM 对 Azure DB 的命令行访问(通过 JDBC)工作 建立一个 SSH 隧道 (ssh -f vm_user@tunnel_vm_host -L 127.0.0.1:1433:mydb-server.database.windows.net:1433 -N),然后通过 127.0.0.1:1433dbuser@mydb-server.database.windows.net 连接到 Azure DB 工作,如果我使用使用 MS OLE DB SQL 驱动程序的客户端 使用 MS SQL JDBC 驱动程序建立连接失败:com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host xxx.yyy.zzz.worker.database.windows.net, port 11111 has failed. Error: "Connection refused: connect. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.". 从我在 Wireshark 中看到的情况来看,如果使用 JDBC 驱动程序,则使用隧道 (127.0.0.1:randomport <--> 127.0.0.1:1433) 开始与 Azure DB 的通信,但随后使用my-external-IP:randomport <--> xxx.yyy.zzz.worker.database.windows.net:11111 切换到隧道外部,但失败了由于防火墙。

让这个运行起来我缺少什么?

使用的驱动程序:

JDBC驱动版本是mssql 8.2.2.0 jre11 用于 SQL Server 18.3.0.0 的 MS OLE DB 驱动程序

测试程序:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class AzureDbTest 
  public static void main(final String[] args) throws SQLException 
    final String user = "db-user@mydb-server.database.windows.net";
    final String password = "password";
    final int portNumber = 1433;
    final String databaseName = "mydb";
    final String serverName = "127.0.0.1";
    final String url = String.format("jdbc:sqlserver://%s:%s;database=%s;user=%s;password=%s;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;",
        serverName, portNumber, databaseName, user, password);
    Connection connection = null;
    try 
      connection = DriverManager.getConnection(url);
      final String schema = connection.getSchema();
      System.out.println("Successful connection - Schema: " + schema);
     catch (final Exception e) 
      e.printStackTrace();
     finally 
      if (connection != null) 
        connection.close();
      
    
  

【问题讨论】:

你知道为什么在使用 MS SQL JDBC 驱动的时候端口会变成 '11111' 吗? 我没有更改端口。那是司机做的事情(我认为)。更改的主机和端口由异常报告,我可以看到,测试程序将连接从 127.0.0.1:1433 切换到异常报告的主机和端口。我不知道为什么。 【参考方案1】:

数据库服务器的连接策略需要代理才能与ssh隧道一起工作。

有关可用连接策略差异的详细信息,请参阅Azure SQL Database and Azure Synapse Analytics connectivity architecture 文章。

【讨论】:

以上是关于无法使用 JDBC 连接通过 SSH 隧道连接到 Azure DB的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 IntelliJ 和 JDBC 建立 SSH 隧道并连接到数据库?

使用 SSH 隧道时无法通过套接字错误连接到本地 MySQL 服务器

如何在 ruby​​ 中使用 ssh 隧道连接 postgres 数据库

ssh隧道代理连接

通过 SSH 隧道连接到 .Net Core 中的 AWS DocumentDb

无法使用 SSH 隧道将 MongoDB Compass 连接到 AWS DocumentDB