无法通过 SSH-Tunnel 使用 JDBC 连接连接到 Azure DB
Failing to connect to Azure DB via SSH-Tunnel using a JDBC connection
我无法使用 JDBC 连接通过 SSH-Tunnel 连接到 Azure 数据库。
出于安全原因,我无法直接访问 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:1433
和 dbuser@mydb-server.database.windows.net
连接到 Azure DB,如果我使用使用 MS OLE DB 的客户端 SQL driver
- 使用 MS SQL JDBC driver 建立连接失败:
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 driver,与 Azure DB 的通信开始使用隧道 (
127.0.0.1:randomport <--> 127.0.0.1:1433
),但随后切换到隧道外,使用 my-external-IP:randomport <--> xxx.yyy.zzz.worker.database.windows.net:11111
,由于防火墙而失败。
我缺少什么才能得到这个 运行?
Driver已使用:
- JDBC driver版本为mssql 8.2.2.0 jre11
- MS OLE DB Driver 用于 SQL 服务器 18.3.0.0
测试程序:
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();
}
}
}
}
数据库服务器的连接策略需要代理才能使用ssh隧道。
有关可用连接策略差异的详细信息,请参阅 Azure SQL Database and Azure Synapse Analytics connectivity architecture 文章。
我无法使用 JDBC 连接通过 SSH-Tunnel 连接到 Azure 数据库。 出于安全原因,我无法直接访问 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:1433
和dbuser@mydb-server.database.windows.net
连接到 Azure DB,如果我使用使用 MS OLE DB 的客户端 SQL driver - 使用 MS SQL JDBC driver 建立连接失败:
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 driver,与 Azure DB 的通信开始使用隧道 (
127.0.0.1:randomport <--> 127.0.0.1:1433
),但随后切换到隧道外,使用my-external-IP:randomport <--> xxx.yyy.zzz.worker.database.windows.net:11111
,由于防火墙而失败。
我缺少什么才能得到这个 运行?
Driver已使用:
- JDBC driver版本为mssql 8.2.2.0 jre11
- MS OLE DB Driver 用于 SQL 服务器 18.3.0.0
测试程序:
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();
}
}
}
}
数据库服务器的连接策略需要代理才能使用ssh隧道。
有关可用连接策略差异的详细信息,请参阅 Azure SQL Database and Azure Synapse Analytics connectivity architecture 文章。