2013-02-20 128 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"帳戶,則認爲您是匿名用戶帳戶。