You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java通过带PEM文件的SSH隧道连接Vertica DB遇连接错误

问题诊断与解决方案

核心问题:JDBC未使用SSH转发的本地端口

你的代码已通过PortForwarder.openConnection()获取到本地转发端口localBindingPort,但最终生成的JDBC URL仍直接指向远程数据库的公网IP和原端口(10.13.3.213:5433),完全未利用SSH隧道的本地转发能力。SSH隧道的作用是将本地端口的请求转发至SSH服务器,再由其转发到目标数据库,因此JDBC必须连接**localhost+本地转发端口**,而非直接连接数据库公网地址。

具体修复步骤

1. 修正JDBC URL生成逻辑

将JDBC URL中的主机改为localhost,端口替换为获取到的localBindingPort:

int localBindingPort = PortForwarder.openConnection();
// 替换主机为localhost,使用转发后的本地端口
JDBCurl = String.format("jdbc:vertica://localhost:%d/%s", localBindingPort, Schema);
return DriverManager.getConnection(JDBCurl, username, password);

2. 校验SSH端口转发参数正确性

检查portsString的参数格式与取值:

  • Port:本地要绑定的未被占用端口(如54330)
  • Host:数据库在SSH服务器内网中的可访问地址(若SSH服务器能直接访问数据库公网IP10.13.3.213,则该值可保留,否则需替换为内网IP)
  • SSHPort:数据库的实际服务端口(Vertica默认是5433)

3. 修正PEM密钥使用方式

使用PEM私钥时需注意:

  • 若PEM文件无密码,不要调用session.setPassword(password),否则会干扰密钥认证流程
  • 确保传入的pemFile是私钥文件路径(而非公钥),JSch需要私钥完成SSH认证
  • 可显式指定密钥绝对路径避免路径问题:
jsch.addIdentity(new File(pemFile).getAbsolutePath());
// 仅当PEM有密码时才设置,无密码则注释此行
// session.setPassword(pemPassphrase);

4. 增强错误排查日志

在PortForwarder.openConnection()的异常捕获块中打印详细堆栈信息,确认SSH连接或端口转发是否成功:

catch (Exception e) {
    System.err.println("SSH连接/端口转发失败详情:");
    e.printStackTrace();
    System.exit(1);
}

验证流程

  1. 先通过telnet localhost localBindingPort测试本地转发端口是否能正常连通
  2. 再运行JDBC连接代码,确认是否通过隧道成功访问数据库

内容的提问来源于stack exchange,提问作者Will Preston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:07:24