有时候咱们没法直接访问某台数据库,由于没有受权或者ip限制,可是能够经过登录其余机器来访问,若是这台服务器安装有SSH,就能够方便的在本地经过该服务的端口映射来代理访问数据库。Navicat就有这个方便的功能,以下图所示: html
由此联想到,在Java代码中可否实现相似的功能呢? java
参考OSC上的这个问题:http://www.oschina.net/question/125831_79245 mysql
红薯已经给出了连接,固然,在google上搜索排第一的也是stackoverflow上的回答:http://sina.lt/gUe linux
SSH自带有端口转发的命令,可将本地的任意可用端口转发到远程服务器的其余端口: sql
ssh -L 1234:localhost:3306 mysql.server.remoteJScH就是一个实现了SSH2协议的Java包,示例代码以下:
import java.sql.*; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; public class TestJSch { static int lport = 3306;//本地端口 static String rhost = "10.10.10.10";//远程MySQL服务器 static int rport = 3306;//远程MySQL服务端口 public static void go() { String user = "username";//SSH链接用户名 String password = "password";//SSH链接密码 String host = "10.10.10.11";//SSH服务器 int port = 2222;//SSH访问端口 try { JSch jsch = new JSch(); Session session = jsch.getSession(user, host, port); session.setPassword(password); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); System.out.println(session.getServerVersion());//这里打印SSH服务器版本信息 int assinged_port = session.setPortForwardingL(lport, rhost, rport); System.out.println("localhost:" + assinged_port + " -> " + rhost + ":" + rport); } catch (Exception e) { e.printStackTrace(); } } public static void sql() { Connection conn = null; ResultSet rs = null; Statement st = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", ""); st = conn.createStatement(); String sql = "SELECT COUNT(1) FROM All"; rs = st.executeQuery(sql); while (rs.next()) System.out.println(rs.getString(1)); } catch (Exception e) { e.printStackTrace(); } finally { //rs.close();st.close();conn.close(); } } public static void main(String[] args) { go(); sql(); } }
从而链接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://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://www.jcraft.com/jsch/examples/Sftp.java session
3.关于SSH端口转发,参见经过SSH实现端口映射: app
工做原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了链接, 该链接就通过安全通道转发出去, 同时远程主机和 host 的 hostport 端口创建链接. 能够在配置文件中指定端口的转发. 只有 root 才能转发特权端口.
EOF.