- 浏览: 939565 次
- 性别:
- 来自: 江西上饶
文章分类
- 全部博客 (460)
- p.spring (56)
- p.maven (20)
- p.ant (17)
- p.jee (18)
- p.jse (33)
- p.ofbiz (31)
- p.软件工程 (8)
- p.struts2 (5)
- p.hibernate (5)
- linux (25)
- 设计模式 (2)
- p.javascript (11)
- 硬件 (1)
- p.jsp (2)
- p.windows批处理 (1)
- 操作系统问题 (5)
- 算法 (1)
- p.mysql (7)
- p.sql (5)
- p.c (1)
- google产品 (0)
- 内存 (1)
- p.struts (1)
- p.freemarker (7)
- p.css (4)
- p.log4j (10)
- p.html (3)
- 淘宝产品 (0)
- 其他 (3)
- 编译器 (0)
- svn (4)
- p.spring.security (11)
- 图形 (0)
- p.xml (1)
- p.ssh (0)
- p.jquery (4)
- p.jdbc (3)
- p.flex (0)
- p.c++ (0)
- p.c#Net (0)
- p.assembly (0)
- p.sqlserver (0)
- p.其他 (3)
- p.webwork (21)
- p.wap (12)
- p.cglib (1)
- p.jee服务器 (11)
- windows (2)
- p.iphone (1)
- p.java.分布式与集群 (2)
- p.ibatis (16)
- p.eclipse (5)
- 架构 (2)
- http协议 (5)
- 我的个人标准 (2)
- 多线程 (1)
- 奇怪问题 (5)
- p.jira (13)
- p.httpclient (1)
- 服务器.apache (11)
- 安全防范 (1)
- p.PODAM (1)
- p.junit (16)
- fop (2)
- 硬盘安装 (1)
- powerdesigner (0)
- 单元测试 (1)
- apache commons (4)
- tomcat+apache集群 (10)
- 各类诡辩 (1)
- 安卓 (8)
- qvod (1)
- java编程基础知识考试考点及答案 (0)
- 工作总结 (4)
- oracle (0)
- spring的util工具 (3)
- json (2)
- maven (3)
- jms (19)
- p.bat (3)
- hadoop (2)
- git (3)
- nginx (1)
- p.移动开发 (1)
- shiro (3)
- 游戏破解 (1)
- react-native (7)
- ios开发 (1)
- webmagic (6)
- socks5 (1)
最新评论
-
weituotian:
说的不好,没人看的
公司系统中的菜单功能和权限功能 -
石不易:
非常详细的注解~
绑定端口和IP,Listen 与VirtualHost指令 -
spring_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
spring mvc -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装 -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装
java通过ssh链接数据库,需要用到
JSCH是一个纯粹的用java实现SSH功能的java 客户端。
原理则是先通过 jsch链接到真实的ssh目标服务器,建立起链接通道。
然后通过jsch开启一个本地端口,数据库链接,先进入该端口,jsch监控到该端口有数据,把该端口的数据获取,并通过上面的SSH链接通道,发送给目标服务器的SSH,目标的SSH服务器再转发给真是的目标IP(目标地址是相对SSH服务器,而不是相对本地而言的地址)和端口。
package cn.gou23.cgodo.jdbc;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.gou23.cgodo.util.UtilLog;
import cn.gou23.cgodo.util.UtilUrl;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
/**
*
*
* 描述:mysqlssh驱动
*
* @author liyixing
* @version 1.0
* @since 2015年9月17日 上午11:02:23
*/
public class MySqlSsh implements Driver {
private static final String PRIEX = "jdbc:mysqlssh:";
/**
* 代理端口
*/
private static final int PROXY_PORT = 3307;
private Proxy proxy;
/**
* 最后一个匹配到的驱动
*/
private Driver lastUnderlyingDriverRequested;
private static final Set<String> SUBDRIVERS_SET = new TreeSet<String>();
static {
// 需要对接的驱动
SUBDRIVERS_SET.add("net.sf.log4jdbc.DriverSpy");
SUBDRIVERS_SET.add("com.mysql.jdbc.Driver");
try {
DriverManager.registerDriver(new MySqlSsh());
for (Iterator<String> i = SUBDRIVERS_SET.iterator(); i.hasNext();) {
String driverClass = (String) i.next();
try {
Class.forName(driverClass);
} catch (Throwable c) {
i.remove();
}
}
} catch (SQLException s) {
throw (RuntimeException) new RuntimeException("无法注册驱动!")
.initCause(s);
}
}
/**
*
* 描述:计算出实际的驱动
*
* @param url
* @return
* @throws SQLException
* @author liyixing 2015年9月17日 上午11:05:40
*/
private Driver getUnderlyingDriver(String url) throws SQLException {
if (url.startsWith(PRIEX)) {
url = url.substring(PRIEX.length());
Enumeration<Driver> e = DriverManager.getDrivers();
Driver d;
while (e.hasMoreElements()) {
d = (Driver) e.nextElement();
if (d.acceptsURL(url)) {
lastUnderlyingDriverRequested = d;
return d;
}
}
}
return null;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public synchronized Connection connect(String url, Properties info)
throws SQLException {
// 查找实际驱动
Driver d = getUnderlyingDriver(url);
if (d == null) {
return null;
}
url = url.substring(PRIEX.length());
// 解析出实际的MYSQLIP和端口
Pattern pattern = Pattern
.compile("mysql://(\\d{1,}\\.\\d{1,}\\.\\d{1,}\\.\\d{1,}):+(\\d{1,})/");
Matcher matcher = pattern.matcher(url);
matcher.find();
try {
if (proxy == null) {
proxy = new Proxy();
// 真实的mysql地址
String mysqlIp = matcher.group(1);
// 真实的MYSQL端口
String mysqlPort = matcher.group(2);
Map<String, String> params = UtilUrl.urlToMap(url, "utf-8");
String sshIp = params.get("sshIp");
String sshUser = params.get("sshUser");
String sshPassword = params.get("sshPassword");
String sshPort = params.get("sshPort");
proxy.setMysqlIp(mysqlIp);
proxy.setMysqlPort(Integer.valueOf(mysqlPort));
proxy.setSshIp(sshIp);
proxy.setSshUser(sshUser);
proxy.setSshPassword(sshPassword);
proxy.setSshPort(Integer.valueOf(sshPort));
proxy.doPorxy();
}
// sshIp = params
url = url
.replaceFirst(
"mysql://(\\d{1,}\\.\\d{1,}\\.\\d{1,}\\.\\d{1,}):+(\\d{1,})/",
"mysql://127.0.0.1:" + PROXY_PORT + "/");
Connection c = d.connect(url, info);
if (c == null) {
throw new SQLException("无效的URL: " + url);
}
return c;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("url解析出错", e);
}
}
/**
* 是否自己需要处理的链接
*
* @see java.sql.Driver#acceptsURL(java.lang.String)
*/
@Override
public boolean acceptsURL(String url) throws SQLException {
Driver d = getUnderlyingDriver(url);
if (d != null) {
return true;
} else {
return false;
}
}
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException {
Driver d = getUnderlyingDriver(url);
if (d == null) {
return new DriverPropertyInfo[0];
}
return d.getPropertyInfo(url, info);
}
@Override
public int getMajorVersion() {
if (lastUnderlyingDriverRequested == null) {
return 1;
} else {
return lastUnderlyingDriverRequested.getMajorVersion();
}
}
@Override
public int getMinorVersion() {
if (lastUnderlyingDriverRequested == null) {
return 0;
} else {
return lastUnderlyingDriverRequested.getMinorVersion();
}
}
@Override
public boolean jdbcCompliant() {
return lastUnderlyingDriverRequested != null
&& lastUnderlyingDriverRequested.jdbcCompliant();
}
/**
*
* 描述:代理ssh
*
* @author liyixing 2015年9月17日 上午11:18:03
*/
public class Proxy {
public String sshUser;// SSH连接用户名
public String sshPassword;// SSH连接密码
public String sshIp;// SSH服务器
public int sshPort;// SSH访问端口
public String mysqlIp;
public int mysqlPort;
public String getMysqlIp() {
return mysqlIp;
}
public void setMysqlIp(String mysqlIp) {
this.mysqlIp = mysqlIp;
}
public int getMysqlPort() {
return mysqlPort;
}
public void setMysqlPort(int mysqlPort) {
this.mysqlPort = mysqlPort;
}
public String getSshUser() {
return sshUser;
}
public void setSshUser(String sshUser) {
this.sshUser = sshUser;
}
public String getSshPassword() {
return sshPassword;
}
public void setSshPassword(String sshPassword) {
this.sshPassword = sshPassword;
}
public String getSshIp() {
return sshIp;
}
public void setSshIp(String sshIp) {
this.sshIp = sshIp;
}
public int getSshPort() {
return sshPort;
}
public void setSshPort(int sshPort) {
this.sshPort = sshPort;
}
public void doPorxy() {
try {
JSch jsch = new JSch();
// 先链接到ssh,建立通道
Session session = jsch.getSession(sshUser, sshIp, sshPort);
session.setPassword(sshPassword);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
UtilLog.debug("ssh版本信息:{}", session.getServerVersion());// 这里打印SSH服务器版本信息
/**
* Registers the local port forwarding for loop-back interface.
* If lport is 0, the tcp port will be allocated.
*
* 总共有三个参数,第一个参数,jsch会在本地机器开启一个端口,并把该端口,并告知上面session建立的通道,
* 该通道是用来做数据转发的,<br>
* 实际的参数需要发送给目标IP和端口 <br>
* 本地机器看成C,目标SSH服务器看成B,目标数据库看成A <br>
* 那么就是驱动链接到C,C通过通道B,发送给A
*/
int assinged_port = session.setPortForwardingL(PROXY_PORT,
mysqlIp, mysqlPort);
UtilLog.debug("assinged", assinged_port);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
JSCH是一个纯粹的用java实现SSH功能的java 客户端。
原理则是先通过 jsch链接到真实的ssh目标服务器,建立起链接通道。
然后通过jsch开启一个本地端口,数据库链接,先进入该端口,jsch监控到该端口有数据,把该端口的数据获取,并通过上面的SSH链接通道,发送给目标服务器的SSH,目标的SSH服务器再转发给真是的目标IP(目标地址是相对SSH服务器,而不是相对本地而言的地址)和端口。
package cn.gou23.cgodo.jdbc;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.gou23.cgodo.util.UtilLog;
import cn.gou23.cgodo.util.UtilUrl;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
/**
*
*
* 描述:mysqlssh驱动
*
* @author liyixing
* @version 1.0
* @since 2015年9月17日 上午11:02:23
*/
public class MySqlSsh implements Driver {
private static final String PRIEX = "jdbc:mysqlssh:";
/**
* 代理端口
*/
private static final int PROXY_PORT = 3307;
private Proxy proxy;
/**
* 最后一个匹配到的驱动
*/
private Driver lastUnderlyingDriverRequested;
private static final Set<String> SUBDRIVERS_SET = new TreeSet<String>();
static {
// 需要对接的驱动
SUBDRIVERS_SET.add("net.sf.log4jdbc.DriverSpy");
SUBDRIVERS_SET.add("com.mysql.jdbc.Driver");
try {
DriverManager.registerDriver(new MySqlSsh());
for (Iterator<String> i = SUBDRIVERS_SET.iterator(); i.hasNext();) {
String driverClass = (String) i.next();
try {
Class.forName(driverClass);
} catch (Throwable c) {
i.remove();
}
}
} catch (SQLException s) {
throw (RuntimeException) new RuntimeException("无法注册驱动!")
.initCause(s);
}
}
/**
*
* 描述:计算出实际的驱动
*
* @param url
* @return
* @throws SQLException
* @author liyixing 2015年9月17日 上午11:05:40
*/
private Driver getUnderlyingDriver(String url) throws SQLException {
if (url.startsWith(PRIEX)) {
url = url.substring(PRIEX.length());
Enumeration<Driver> e = DriverManager.getDrivers();
Driver d;
while (e.hasMoreElements()) {
d = (Driver) e.nextElement();
if (d.acceptsURL(url)) {
lastUnderlyingDriverRequested = d;
return d;
}
}
}
return null;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public synchronized Connection connect(String url, Properties info)
throws SQLException {
// 查找实际驱动
Driver d = getUnderlyingDriver(url);
if (d == null) {
return null;
}
url = url.substring(PRIEX.length());
// 解析出实际的MYSQLIP和端口
Pattern pattern = Pattern
.compile("mysql://(\\d{1,}\\.\\d{1,}\\.\\d{1,}\\.\\d{1,}):+(\\d{1,})/");
Matcher matcher = pattern.matcher(url);
matcher.find();
try {
if (proxy == null) {
proxy = new Proxy();
// 真实的mysql地址
String mysqlIp = matcher.group(1);
// 真实的MYSQL端口
String mysqlPort = matcher.group(2);
Map<String, String> params = UtilUrl.urlToMap(url, "utf-8");
String sshIp = params.get("sshIp");
String sshUser = params.get("sshUser");
String sshPassword = params.get("sshPassword");
String sshPort = params.get("sshPort");
proxy.setMysqlIp(mysqlIp);
proxy.setMysqlPort(Integer.valueOf(mysqlPort));
proxy.setSshIp(sshIp);
proxy.setSshUser(sshUser);
proxy.setSshPassword(sshPassword);
proxy.setSshPort(Integer.valueOf(sshPort));
proxy.doPorxy();
}
// sshIp = params
url = url
.replaceFirst(
"mysql://(\\d{1,}\\.\\d{1,}\\.\\d{1,}\\.\\d{1,}):+(\\d{1,})/",
"mysql://127.0.0.1:" + PROXY_PORT + "/");
Connection c = d.connect(url, info);
if (c == null) {
throw new SQLException("无效的URL: " + url);
}
return c;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("url解析出错", e);
}
}
/**
* 是否自己需要处理的链接
*
* @see java.sql.Driver#acceptsURL(java.lang.String)
*/
@Override
public boolean acceptsURL(String url) throws SQLException {
Driver d = getUnderlyingDriver(url);
if (d != null) {
return true;
} else {
return false;
}
}
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException {
Driver d = getUnderlyingDriver(url);
if (d == null) {
return new DriverPropertyInfo[0];
}
return d.getPropertyInfo(url, info);
}
@Override
public int getMajorVersion() {
if (lastUnderlyingDriverRequested == null) {
return 1;
} else {
return lastUnderlyingDriverRequested.getMajorVersion();
}
}
@Override
public int getMinorVersion() {
if (lastUnderlyingDriverRequested == null) {
return 0;
} else {
return lastUnderlyingDriverRequested.getMinorVersion();
}
}
@Override
public boolean jdbcCompliant() {
return lastUnderlyingDriverRequested != null
&& lastUnderlyingDriverRequested.jdbcCompliant();
}
/**
*
* 描述:代理ssh
*
* @author liyixing 2015年9月17日 上午11:18:03
*/
public class Proxy {
public String sshUser;// SSH连接用户名
public String sshPassword;// SSH连接密码
public String sshIp;// SSH服务器
public int sshPort;// SSH访问端口
public String mysqlIp;
public int mysqlPort;
public String getMysqlIp() {
return mysqlIp;
}
public void setMysqlIp(String mysqlIp) {
this.mysqlIp = mysqlIp;
}
public int getMysqlPort() {
return mysqlPort;
}
public void setMysqlPort(int mysqlPort) {
this.mysqlPort = mysqlPort;
}
public String getSshUser() {
return sshUser;
}
public void setSshUser(String sshUser) {
this.sshUser = sshUser;
}
public String getSshPassword() {
return sshPassword;
}
public void setSshPassword(String sshPassword) {
this.sshPassword = sshPassword;
}
public String getSshIp() {
return sshIp;
}
public void setSshIp(String sshIp) {
this.sshIp = sshIp;
}
public int getSshPort() {
return sshPort;
}
public void setSshPort(int sshPort) {
this.sshPort = sshPort;
}
public void doPorxy() {
try {
JSch jsch = new JSch();
// 先链接到ssh,建立通道
Session session = jsch.getSession(sshUser, sshIp, sshPort);
session.setPassword(sshPassword);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
UtilLog.debug("ssh版本信息:{}", session.getServerVersion());// 这里打印SSH服务器版本信息
/**
* Registers the local port forwarding for loop-back interface.
* If lport is 0, the tcp port will be allocated.
*
* 总共有三个参数,第一个参数,jsch会在本地机器开启一个端口,并把该端口,并告知上面session建立的通道,
* 该通道是用来做数据转发的,<br>
* 实际的参数需要发送给目标IP和端口 <br>
* 本地机器看成C,目标SSH服务器看成B,目标数据库看成A <br>
* 那么就是驱动链接到C,C通过通道B,发送给A
*/
int assinged_port = session.setPortForwardingL(PROXY_PORT,
mysqlIp, mysqlPort);
UtilLog.debug("assinged", assinged_port);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
发表评论
-
java实现socks5
2019-07-16 23:05 1578socks5的基础知识 关于socks5的定义]https: ... -
java Runtime.exec方法详解
2019-07-11 14:11 20641.关于CMD(为了让exec ... -
Spring 定时任务,cron表达式,@Scheduled cron表达式
2016-04-25 15:48 5266一个cron表达式有至少6 ... -
xulrunner
2016-01-13 13:07 627http://ftp.mozilla.org/pub/xulr ... -
谈一谈自己对依赖、关联、聚合和组合之间区别的理解
2015-11-17 16:05 738在学习面向对象设计对象关系时,依赖、关联、聚合和组合这四种关系 ... -
java apache common unicode处理
2015-09-19 15:17 1512if (UnicodeConvertType.中文转unico ... -
swt 窗口 最大化最小化按钮设置等
2015-09-14 17:53 4238窗体顶部菜可以在实例化的时候设置,也可以单独设置:Shell ... -
java.lang.Process调用程序阻塞问题解决
2015-08-14 10:56 4220这两天一直在处理flv视频环境的搭建工作,包括服务器的安 ... -
java html解析
2015-07-31 17:31 1159dom解析是常用dom4j。 android中我们常用的是sa ... -
slf4j门面模式实现原理
2015-07-16 10:08 2940在使用slf4j的时候,只 ... -
java - 比较时间-相差月数
2015-06-15 09:57 1392Date经常会出现比较两个Date相差的月数,实际上可以做一个 ... -
log4jdbc
2014-12-25 13:55 3003该框架目前支持到jdbc3.和jdbc4的版本。 提供了多种 ... -
jdbc规范 jdbc1 jdbc2 jdbc3 jdbc4
2014-12-25 13:49 4958目前jdbc规范已经升级到 ... -
反射,代理,动态java原理
2014-12-22 16:44 1080需要两个类,用于下面的测试 package test; ... -
Bean Validation 1.0(JSR-303)
2014-11-18 16:15 1053http://jinnianshilongnian.iteye ... -
JRE最小化原理
2014-10-15 20:19 1265比如我们一个程序只用到了很少的类,像String,Intege ... -
时间重叠的判断
2014-02-14 11:16 1618如上图,粗线是时间1 细线是时间2 时间重叠,只可能是以上四 ... -
java获取当前类的绝对路径
2013-12-14 00:37 8571.如何获得当前文件路径 常用: (1).Test.class ... -
枚举 enum
2013-12-13 16:52 5192java的enum其实是一个类。编译器根据你enum的定义会为 ... -
EL表达式,ognl表达式对集合过滤和投影
2013-11-23 11:48 1156GONL<s:property value=" ...
相关推荐
Hibernate的工作原理 Hibernate的缓存体系 spring工作机制及为什么要用?
Android使用JDBC SSH连接外网数据库.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
ssh+jdbc+oracle所有依赖包(commons-pool2-2.8.0.jar,commons-collections-3.2.2.jar,commons-dbcp2-2.7.0.jar,ojdbc8.jar)
Android使用JDBC+SSH连接外网数据库
JDBC SSH 面试 SSH定义 MVC
JDBC基础和SSH编码
JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单...
jdbc jdbc jdbc jdbc jdbc jdbc jdbc jdbc
JDBC代码 JDBC代码JDBC代码 JDBC代码
JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础
JavaEE的知识点,包括servlet,jdbc,js,ssh框架的基础,原理。 收集总结了许多学长面试不同公司时面到的实际面试题。以及分享了回答问题的经验。 自己在去年10月份校招时,感觉有点用,特别是在给自己查漏补缺方面...
JDBC笔记 JDBC笔记 JDBC笔记
JDBC详解 JDBC详解JDBC详解 JDBC详解JDBC详解 JDBC详解
JDBC高级应用JDBC高级应用JDBC高级应用JDBC高级应用
JDBC 解析JDBC中文API各种数据库之间的链接问题,网络编程
jdbc资料jdbc资料jdbc资料jdbc资料
hive-jdbc
JDBC规范 java.sql和javax.sql两个包中的类与接口(天龙八部): DataSource:数据源 DriverManager:驱动管理 Driver:JDBC驱动 Connection:数据库连接 Statement:语句,执行SQL PrepareStatement:...
Java Web 开发过程中有很多文档是我们必备的,这里面整合了Struts,Spring,Hibernate,SQL,oracle,css,ajax,javascript,jsp,等必备文档,使开发便捷效率
ssh+jdbc+md5整理好的jar包直接导入即可