2013-02-20 59 views
3

我想编写Java程序使用SSH隧道访问远程mySQL数据库。SSH隧道到远程访问MySQL数据库

下面是我的代码:

int lport = 5656; 

int rport = 3306; 

String rhost = "111.222.333.444"; 

String host = "111.222.333.444"; 

String user = "username"; 

String password = "password1234"; 

String dbUser = "mySQLuser"; 

String dbPass = "mySQLpassword1234"; 

String schema = "test_db"; 





Connection conn = null; 


try { 


Properties config = new Properties(); 

config.put("StrictHostKeyChecking", "no"); 


JSch jsch = new JSch(); 

jschSession = jsch.getSession(user, host, 22); 

jschSession.setPassword(password); 

jschSession.setConfig(config); 

jschSession.connect(); 

logger.info("Connected"); 


int assigned_port = jschSession.setPortForwardingL(lport, rhost, rport); 

logger.info("localhost:" + assigned_port + " -> " + rhost + ":" + rport); 

logger.info("Port Forwarded"); 




Class.forName("com.mysql.jdbc.Driver").newInstance(); 

String url = "jdbc:mysql://localhost:" + rport + "/" + schema; 

conn = DriverManager.getConnection(url, dbUser, dbPass); 

logger.info("Database connection established"); 


Statement stmt = conn.createStatement(); 


String sql = "SELECT * FROM TEST_TABLE"; 

ResultSet rs = stmt.executeQuery(sql); 


while(rs.next()) { 

logger.info(rs.getInt(1) + " " + rs.getString(2)); 

} 


rs.close(); 

stmt.close(); 


logger.info("DONE"); 


} catch (Exception e) { 

e.printStackTrace(); 

logger.error(e.getMessage()); 

if (jschSession != null && jschSession.isConnected()) { 

System.out.println("Closing SSH Connection during error"); 

logger.error("Closing SSH Connection during error"); 

jschSession.disconnect(); 

} 


} finally { 

if (conn != null && !conn.isClosed()) { 

System.out.println("Closing Database Connection"); 

logger.info("Closing Database Connection"); 

conn.close(); 

} 


if (jschSession != null && jschSession.isConnected()) { 

System.out.println("Closing SSH Connection"); 

logger.info("Closing SSH Connection"); 

//jschSession.disconnect(); 

} 


} 

我敢肯定,所有的用户名和密码是否正确。

然而,当我试图运行上面的代码,它总是失败在下面的行:

conn = DriverManager.getConnection(url, dbUser, dbPass); 

但下列情况除外:

INFO | jvm 1 | 2013/02/20 17:25:24 | java.sql.SQLException: Access denied for user 'mySQLuser'@'localhost' (using password: YES) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:885) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3421) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1247) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.Connection.<init>(Connection.java:1555) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at java.sql.DriverManager.getConnection(DriverManager.java:582) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at java.sql.DriverManager.getConnection(DriverManager.java:185) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at com.prject.testing.Test.<init>(Test.java:97) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$4.run(AbstractAutowireCapableBeanFactory.java:997) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at java.security.AccessController.doPrivileged(Native Method) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:995) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:955) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:874) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:731) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:605) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:926) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:477) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:638) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:595) 
INFO | jvm 1 | 2013/02/20 17:25:24 |  at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:652) 

我还检查了MySQL,用户“mySQLuser”的“主机”已在“用户”表中设置为“%”。
任何人都可以给我一些建议吗?

更新:

采用从@ bmorris591建议,

我已经改变字符串URL = “JDBC:MySQL的://本地主机:” + RPORT + “/” +模式; into String url =“jdbc:mysql:// localhost:”+ lport +“/”+ schema;

然而,有一个新的例外出现:

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost. 
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997) 
    at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:573) 
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1044) 
    at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775) 
    at com.mysql.jdbc.Connection.<init>(Connection.java:1555) 
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285) 
    at java.sql.DriverManager.getConnection(DriverManager.java:582) 
    at java.sql.DriverManager.getConnection(DriverManager.java:185) 
    at com.project.testing.Test.<init>(Test.java:98) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147) 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$4.run(AbstractAutowireCapableBeanFactory.java:997) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:995) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:955) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:874) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:731) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:605) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:926) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:477) 
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:638) 
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:595) 
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:652) 
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:514) 
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:455) 
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138) 
    at javax.servlet.GenericServlet.init(GenericServlet.java:212) 
    at sun.reflect.GeneratedMethodAccessor120.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:270) 
    at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:269) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAsPrivileged(Subject.java:517) 
    at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:302) 
    at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:163) 
    at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:117) 
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1200) 
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1026) 
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4421) 

,仍然在这行代码发生的错误:

conn = DriverManager.getConnection(url, dbUser, dbPass); 

错误消息让我很迷惑,

可以给我更多的建议吗?

+0

含义是ssh隧道无法正常工作。尝试添加代码以查看在添加数据库连接之前是否有效。 – Stevo 2013-02-20 09:47:54

+1

有点偏题,但为什么你需要一个java程序来建立SSH隧道,不会仅仅用普通的ssh来建立隧道就简单一点,那么你的java程序只能访问本地端口? – beny23 2013-02-20 10:03:05

+0

@Hei我有同样的问题通过TCP/IP连接使用SSH/SSL连接Java应用程序。所以,我发现这个使用证书PEM - 隐私增强邮件(PEM)的链接[http://blog.sodhanalibrary.com/2015/12/connect-amazon-ec2-instance-using-java.html]。你对这个问题的解决方案有什么想法吗? – EAA 2016-09-22 14:57:03

回答

2

这似乎是错误的是在这条线:

String url = "jdbc:mysql://localhost:" + rport + "/" + schema; 

给予比rport3306,即在远程机器上的MySQL端口,您连接到

"jdbc:mysql://localhost:3306/" + schema; 

哪个是你的本地机器。您需要连接到:

String url = "jdbc:mysql://localhost:" + lport + "/" + schema; 

这将是本地机器转发到3306在远程机器上的端口。

+0

感谢您的提示。我已经更改为lport,现在我有一个新的异常: java.io.EOFException:无法读取服务器的响应。预计会读取4个字节,在连接意外丢失之前读取0个字节。 这让我有点迷惑...... – Hei 2013-02-20 10:14:57

+0

这种情况下,你的隧道不开放我猜。如果你从你的java应用程序中执行'LocalForward',你应该能够从命令行测试隧道。 – 2013-02-20 10:22:42

+0

因此,您如何评价Java代码执行隧道操作,我最初遵循本教程,但似乎在我的情况下并不成功。 http://www.journaldev.com/235/java-program-to-connect-to-remote-database-through-ssh-using-port-forwarding – Hei 2013-02-20 10:42:58

0

"mySQLuser"@"%"让我们从任何远程主机连接。你应该有"mySQLuser"@"localhost"能够本地登录,这是通过SSH隧道时的情况。

默认的MySQL安装具有主机为localhost的匿名用户帐户,因此在本地登录时,这被认为是更“特定”的用户。也就是说,如果没有"mySQLuser"@"localhost"帐户,则认为您是匿名用户帐户。