JDBC通过SSH Tunnel连接MySQL数据库

有时候我们无法直接访问某台数据库,因为没有授权或者ip限制,但是可以通过登陆其他机器来访问,如果这台服务器安装有SSH,就可以方便的在本地通过该服务的端口映射来代理访问数据库。Navicat就有这个方便的功能,如下图所示:

由此联想到,在Java代码中能否实现类似的功能呢?

参考OSC上的这个问题:http://go.rritw.com/www.oschina.net/question/125831_79245

红薯已经给出了链接,当然,在google上搜索排第一的也是stackoverflow上的回答:http://go.rritw.com/sina.lt/gUe

SSH自带有端口转发的命令,可将本地的任意可用端口转发到远程服务器的其他端口:

ssh -L 1234:localhost:3306 mysql.server.remote
JScH 就是一个实现了SSH2协议的Java包,示例代码如下: 

[java]  view plain  copy
  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.ResultSet;  
  4. import java.sql.Statement;  
  5.   
  6. import com.jcraft.jsch.JSch;  
  7. import com.jcraft.jsch.Session;  
  8.   
  9. public class TestJSch {  
  10.   
  11.     static int lport = 3306;//本地端口  
  12.     static String rhost = "10.10.10.10";//远程MySQL服务器  
  13.     static int rport = 3306;//远程MySQL服务端口  
  14.   
  15.     public static void go() {  
  16.         String user = "username";//SSH连接用户名  
  17.         String password = "password";//SSH连接密码  
  18.         String host = "10.10.10.11";//SSH服务器  
  19.         int port = 2222;//SSH访问端口  
  20.         try {  
  21.             JSch jsch = new JSch();  
  22.             Session session = jsch.getSession(user, host, port);  
  23.             session.setPassword(password);  
  24.             session.setConfig("StrictHostKeyChecking""no");  
  25.             session.connect();  
  26.             System.out.println(session.getServerVersion());//这里打印SSH服务器版本信息  
  27.             int assinged_port = session.setPortForwardingL(lport, rhost, rport);  
  28.             System.out.println("localhost:" + assinged_port + " -> " + rhost + ":" + rport);  
  29.         } catch (Exception e) {  
  30.             e.printStackTrace();  
  31.         }  
  32.     }  
  33.       
  34.     public static void sql() {  
  35.         Connection conn = null;  
  36.         ResultSet rs = null;  
  37.         Statement st = null;  
  38.         try {  
  39.             Class.forName("com.mysql.jdbc.Driver");  
  40.             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test""root""");  
  41.             st = conn.createStatement();  
  42.             String sql = "SELECT COUNT(1) FROM All";  
  43.             rs = st.executeQuery(sql);  
  44.             while (rs.next())  
  45.                 System.out.println(rs.getString(1));  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         } finally {  
  49.             //rs.close();st.close();conn.close();  
  50.         }  
  51.     }  
  52.   
  53.     public static void main(String[] args) {  
  54.         go();  
  55.         sql();  
  56.     }  
  57. }  

从而连接SSH后,通过访问本地的3306端口就被指向了 10.10.10.10服务器的3306端口,就好像MySQL安装在本地一样。前提是SSH服务器10.10.10.11能够访问MySQL数据库服务器10.10.10.10的3306端口才能做转发。

P.S.

1.关于SSH连接中的StrictHostKeyChecking参数manpage解释为:该选项可被用于阻止未知的或更改过的host key的登陆。参见:http://go.rritw.com/sina.lt/gUh

SSH对主机的public_key的检查等级是根据StrictHostKeyChecking变量来配置的。默认情况下,StrictHostKeyChecking=ask。简单所下它的三种配置值:                                          1.StrictHostKeyChecking=no #最不安全的级别,当然也没有那么多烦人的提示了,相对安全的内网测试时建议使用。如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告。 2.StrictHostKeyChecking=ask #默认的级别,就是出现刚才的提示了。如果连接和key不匹配,给出提示,并拒绝登录。                                                                                                                    3.StrictHostKeyChecking=yes #最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息。

2.关于JSch的网站,还有很多其他协议的Java实现,比如SFTP,用于加密的ftp连接等等,参见代码:http://go.rritw.com/www.jcraft.com/jsch/examples/Sftp.java

3.关于SSH端口转发,参见通过SSH实现 端口映射

工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口.

另见 实战 SSH 端口转发、 SSH端口转发

EOF.


转载自:http://blog.csdn.net/a351945755/article/details/21782693

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值