`
liyixing1
  • 浏览: 958789 次
  • 性别: Icon_minigender_1
  • 来自: 江西上饶
社区版块
存档分类
最新评论

jdbc ssh通道

ssh 
阅读更多
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();
}
}
}
}
分享到:
评论

相关推荐

    安卓SQLite数据库相关-Android使用JDBCSSH连接外网数据库.rar

    本资料包"安卓SQLite数据库相关-Android使用JDBCSSH连接外网数据库.rar"主要探讨的是如何在Android应用中通过JDBC(Java Database Connectivity)和SSH(Secure Shell)隧道来连接并操作远程的MySQL或其他类型的网络...

    Android使用JDBC+SSH连接外网数据库

    在Android开发中,有时我们需要实现从移动设备上访问位于外网的数据库,这通常涉及到使用Java Database Connectivity(JDBC)来实现数据交互,并通过Secure Shell(SSH)建立安全的网络通道。本文将深入探讨如何在...

    SSHSAMPLE3.zip_J2EE SSH_SSHSAMPLE3_SSH查询_ssh_ssh j2ee

    3. 验证成功后,用户可以发起查询请求,这些请求可能通过SSH通道安全地传递。 4. 应用服务器接收到请求后,可能使用JDBC(Java Database Connectivity)与后台数据库进行交互,执行查询。 5. 查询结果返回给用户,...

    SSH需要的jar,ssh完整jar

    它允许用户通过安全通道访问远程服务器,执行命令、传输文件等。在Java中,实现SSH功能通常会依赖一些特定的jar文件,这些文件包含了处理SSH连接、身份验证、加密等功能的类和方法。 以下是SSH实现可能需要的一些...

    SSH2连接Oracle数据库的例子

    // 关闭SSH通道和会话 channel.disconnect(); session.disconnect(); ``` 这个示例代码展示了如何通过JSch库创建一个SSH2连接,并使用它来建立一个到Oracle数据库的安全通道。请注意,这只是一个基本的框架,实际...

    SSH2测试程序

    在这个SSH2测试程序中,SSH2被用作一个通道,通过它我们可以安全地与Oracle数据库交互。Oracle数据库是世界上最广泛使用的数据库管理系统之一,它提供了高性能、高可用性和可扩展性,适用于大型企业级应用。 首先,...

    ssh2 mysql 注释开发

    在SSH2环境中,这可能涉及到使用SFTP(SSH文件传输协议)来传输数据,或者通过SSH通道执行命令并获取服务器的响应。 总的来说,这个项目涵盖了以下几个关键知识点: 1. SSH2协议:理解其工作原理,如何配置和使用...

    ssh图片存数据库 ssh图片存数据库

    通过SSH通道,可以执行远程命令,如操作数据库。 4. **数据库操作**:使用SQL语句插入图片数据。例如,在Java中,可以使用JDBC API来执行SQL的`INSERT INTO`语句,将图片二进制数据和相关元数据插入到表中。 5. **...

    mysql教程ssh配置

    SSH提供了一种安全的网络通信方式,可以让你通过加密的通道远程访问MySQL服务器,防止数据在传输过程中被窃取或篡改。下面将详细讲解如何进行MySQL教程中的SSH配置。 1. **SSH基础知识**: SSH是一种网络协议,...

    SSH2用户名密码验证

    SSH(Secure Shell)是一种网络协议,用于在不安全的网络环境...此外,生产环境中通常不建议直接通过SSH执行SQL,而是使用更安全的JDBC连接来操作数据库。在开发过程中,记得遵循最佳实践,确保代码的安全性和稳定性。

    ssh_employee.rar_ssh_ssh人员管理源代码

    SSH通常用于在服务器之间建立安全的通信通道,比如远程登录、文件传输等。它通过加密技术确保数据在传输过程中的安全性,防止被第三方窃取或篡改。SSH员工管理实例则可能涉及了对系统中具有SSH访问权限的用户进行...

    ssh2 全jar包oracle mysql.rar

    例如,使用Java的JDBC-ODBC桥接,开发人员可以利用SSH2库创建一个安全的通道,然后通过这个通道进行数据库操作。 再来看MySQL,它是开源的关系型数据库,被许多开发者用于构建Web应用程序。SSH2与MySQL的结合同样...

    一些SSH相关

    根据提供的文件信息,可以看出这里混入了关于JDBC配置与JSP页面上下文对象的知识,而标题和描述指向的是SSH相关的概念。为了更好地满足需求,本篇内容将着重阐述SSH的基础概念及其在IT领域的实际应用。 ### SSH简介...

    ssh2+oracle 全注解 annotation lib包

    SSH2库可能包括了如JSch这样的组件,它是一个实现了SSH2协议的Java库,用于建立SSH2通道,实现SFTP(Secure File Transfer Protocol)或者执行远程命令。这些功能在管理远程服务器,例如自动化部署、文件传输等方面...

    SSH2的jar包及的一个简单增删改查及分页和排序的例子

    一旦通道建立,你可以通过这个通道创建JDBC连接,执行SQL语句,实现增删改查操作。 在SSH2环境中实现分页和排序,通常是在SQL查询语句中加入相应的子句。例如,`LIMIT`和`OFFSET`用于实现分页,`ORDER BY`用于指定...

    SSH工作流程

    1. **封装JDBC访问数据库的代码:** Hibernate通过高级的API封装了底层的JDBC操作,大大减少了数据访问层的代码量。 2. **优秀的ORM实现:** Hibernate提供了一种简洁的方式来管理对象和关系型数据库之间的映射,...

    SSH初学源代码2

    SSH本身并不直接处理数据库事务,但可以被用作安全地远程执行数据库命令的通道。在源代码中,这部分可能包含使用SQL语句来插入数据,如`INSERT INTO`语句,以及使用相应的数据库API(如JDBC for Java或psycopg2 for ...

    音乐分享网站(SSH/MySQL/MyEcplise)

    【音乐分享网站(SSH/MySQL/...综上所述,"音乐分享网站(SSH/MySQL/MyEcplise)"是一个综合运用了多种Java Web技术的实例,它展示了如何利用SSH框架搭建功能丰富的社交网络平台,为用户提供音乐分享和交流的便捷通道。

    51CTO下载-ssh原理

    1. 封装 JDBC:Hibernate 抽象了数据库访问,使得开发者无需编写大量的 JDBC 代码。 2. ORM 实现:它将数据库表映射为 Java 对象,简化数据操作。 3. 反射机制:通过反射,Hibernate 能够在运行时动态处理对象和...

    SSH集成框架

    4. 数据库连接与操作:在SSH框架中,通常使用Spring的JDBC模板或者整合Hibernate来处理数据库连接。Spring JDBC提供了一种抽象层,可以避免直接写JDBC代码,简化了事务管理。而Hibernate则通过Session接口进行CRUD...

Global site tag (gtag.js) - Google Analytics