have been troubled by this for quite sometime, with reference to the code from here: http://www.journaldev.com/235/java-program-to-connect-to-remote-database-through-ssh-using-port-forwarding
have been trying, but still unable to get the connection. Here's my modified code:
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.sql.Connection;
public class MySqlConnOverSSH {
/**
* Java Program to connect to remote database through SSH using port forwarding
* #throws SQLException
*/
public static void main(String[] args) throws SQLException {
int lport=5656;
String rhost="fictitious#germany.com";
String host="fictitious#germany.com";
int rport=3306;
String user="root";
String password="root";
String dbuserName = "root";
String dbpassword = "root";
String url = "jdbc:mysql://localhost:"+lport+"/test";
String driverName="com.mysql.jdbc.Driver";
Connection conn = null;
Session session= null;
try{
//Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
int assigned_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assigned_port+" -> "+rhost+":"+rport);
System.out.println("Port Forwarded");
//mysql database connectivity
Class.forName(driverName).newInstance();
conn = DriverManager.getConnection (url, dbuserName, dbpassword);
System.out.println ("Database connection established");
System.out.println("DONE");
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn != null && !conn.isClosed()){
System.out.println("Closing Database Connection");
conn.close();
}
if(session !=null && session.isConnected()){
System.out.println("Closing SSH Connection");
session.disconnect();
}
}
}
and following is the error which i get:
Connected
localhost:5656 -> fictitious#germany.com:3306
Port Forwarded
java.sql.SQLInvalidAuthorizationSpecException: Could not connect: Access denied for user 'root'#'fictitious#germany.com' (using password: YES)
at org.mariadb.jdbc.internal.util.ExceptionMapper.get(ExceptionMapper.java:121)Closing SSH Connection
at org.mariadb.jdbc.internal.util.ExceptionMapper.throwException(ExceptionMapper.java:69)
at org.mariadb.jdbc.Driver.connect(Driver.java:110)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at myDB.MySqlConnOverSSH.main(MySqlConnOverSSH.java:50)
Caused by: org.mariadb.jdbc.internal.util.dao.QueryException: Could not connect: Access denied for user 'root'#'fictitious#germany.com' (using password: YES)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:433)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:397)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:318)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:630)
at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:580)
at org.mariadb.jdbc.Driver.connect(Driver.java:105)
... 3 more}
I am at Java:beginner level and trying to explore different ways to get this connection going. By the way, I am able to connect to the database using the given Username and password on SecureCRT, so the authorization error is kind of confusing. It would be great if someone could guide me in what I'm doing wrong and how it could be corrected. Thanks a ton in advance !
Related
Can I connect to remote Mysql via Jumpbox/proxy from my local machine.
I have a java application deployed in AWS machine(A) which has access and can connect to remote Mysql server(B). Now when I need to test my Java application locally I can not connect to Remote Mysql server(B).
So basically can my Java application connect to remote server from my local machine via AWS machine.
This way
Local Machine(java Application) ===> AWS machine(A)==> Mysql Server(B)
AWS Machine(A) can only be connected through SSH. :(
Can tunneling help here?
you can use JSch
http://www.jcraft.com/jsch/
an example of how to use it
package com.journaldev.java.ssh
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.sql.Connection;
public class MySqlConnOverSSH {
/**
* Java Program to connect to the remote database through SSH using port forwarding
* #author Pankaj#JournalDev
* #throws SQLException
*/
public static void main(String[] args) throws SQLException {
int lport=5656;
String rhost="secure.journaldev.com";
String host="secure.journaldev.com";
int rport=3306;
String user="sshuser";
String password="sshpassword";
String dbuserName = "mysql";
String dbpassword = "mysql123";
String url = "jdbc:mysql://localhost:"+lport+"/mydb";
String driverName="com.mysql.jdbc.Driver";
Connection conn = null;
Session session= null;
try{
//Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
System.out.println("Port Forwarded");
//mysql database connectivity
Class.forName(driverName).newInstance();
conn = DriverManager.getConnection (url, dbuserName, dbpassword);
System.out.println ("Database connection established");
System.out.println("DONE");
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn != null && !conn.isClosed()){
System.out.println("Closing Database Connection");
conn.close();
}
if(session !=null && session.isConnected()){
System.out.println("Closing SSH Connection");
session.disconnect();
}
}
}
}
Reference:
https://www.journaldev.com/235/java-mysql-ssh-jsch-jdbc
My JDK is 1.7.
import java.util.Properties;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class SSHClientTest {
public static void main(String[] args){
try {
String host = "192.168.1.233";
int port = 23;
String username = "root";
String password = "htnice";
// create JSch
JSch jSch = new JSch();
// get session
Session session = jSch.getSession(username, host, port);
session.setPassword(password);
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
// start connect
session.connect();
session.disconnect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I'm getting the following exception:
Exception in thread "main" java.lang.NullPointerException
at com.jcraft.jsch.Session.start_discard(Session.java:1066)
at com.jcraft.jsch.Session.read(Session.java:937)
at com.jcraft.jsch.Session.connect(Session.java:309)
at com.jcraft.jsch.Session.connect(Session.java:183)
at SSHClientTest.main(SSHClientTest.java:26)
The same error with jsch-0.1.54 and jsch-0.1.55.
I can connect to the server by TTerm. The port is 23.
JSch is SSH client (port 22).
You cannot use it to connect to Telnet server (port 23).
I want to make a connection to the remote database ssh, in my java program, so I write a java code for this, I can ssh to the database server from my code but I can't access to the database, this is my out put which contains the error :
identity added
session created.
session connected.....
shell channel connected....
db Method...
try-catch
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at Main.connectToDB(Main.java:68)
at Main.main(Main.java:46)
Goodbye!
done
I run my .java class with this command ( I give both jsch and mysql-connector jar file, for running my class) and both jar files are in the folder that contains Main.java class
java -cp .:mysql-connector-java-5.0.7-bin.jar.:jsch-0.1.54.jar Main
and here is my code
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class Main {
public static void main(String[] arg) {
try {
JSch jsch = new JSch();
String user = "server-username";
String host = "server-Ip";
int port = 22;
String privateKey = "id_rsa";
jsch.addIdentity(privateKey);
System.out.println("identity added ");
Session session = jsch.getSession(user, host, port);
System.out.println("session created.");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("session connected.....");
Channel channel = session.openChannel("sftp");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
System.out.println("shell channel connected....");
connectToDB();
System.out.println("done");
} catch (Exception e) {
System.err.println(e);
}
}
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/DBname";
static final String USER = "username";
static final String PASS = "";
public static void connectToDB() {
System.out.println("db Method...");
Connection conn = null;
Statement stmt = null;
try{
System.out.println("try-catch");
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,"");
System.out.println("hey!");
stmt = conn.createStatement();
String sql;
sql="SELECT * from test";
ResultSet rs = stmt.executeQuery(sql);
try (BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"))) {
while(rs.next()){
String name = rs.getString("name");
bw.write(name);
bw.newLine();
System.out.println(" name: " + name);
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
I confused , I think maybe I should put both jar files in the db-server ?
( Now there are in the javacode-server in the folder of java code)
Where I should put this jars,if I have to put them in the Database Server?
Ok - so I have been working on this for some time (sometimes not working on it), and I am ALMOST there but not yet. I am trying to tunnel into a mysql db and was able to successfully connect ssh using Jsch. But when I try to connect to the database, it gives me an "Access denied for user 'usernamne'#'localhost' (using password: YES)
Here is the following code: (of course I masked out sensitive info)
public void connect(){
String user = "user";
String password = "password";
String host = "host.com";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = null;
Properties info = new Properties();
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
jsch.addIdentity("/Users/user/.ssh/id_rsa", password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
if(session.isConnected()){
session.disconnect();
}
session.connect();
conn = DriverManager.getConnection("jdbc:mysql://localhost:4417/dbname","dbuser", "dbpassword");
System.out.print("Connection successful!" + "\n\n");
System.out.print("Connection:" + conn + "\n\n");
Statement stmt = conn.createStatement();
ResultSet resultSet = stmt.executeQuery("SELECT * FROM TABLENAME limit 1");
System.out.print(resultSet);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (JSchException j){
j.printStackTrace();
}
}
I've read other posts on here but I have not found the exact solution to my problem. I am able to ssh in correct. And what's even more interesting is that if I do the same exact procedure command_line, it works fine. So I don't know why it wouldn't work here.
Try this. it might help you . Already tested in my setup. Enjoy. :)
create db user in remote mysql db.
CREATE USER 'myuser'#'clientip' IDENTIFIED BY 'pass';
CREATE USER 'myuser'#'%' IDENTIFIED BY 'pass';
grant ALL ON mydb.* to 'myuser'#'clientip';
grant ALL ON mydb.* to 'myuser'#'%';
FLUSH PRIVILEGES;
Code for ssh tunneling.
int assigned_port;
final int local_port=8080;
// Remote host and port
final int remote_port=3306;
final String remote_host="192.168.150.139";
try {
JSch jsch = new JSch();
// Create SSH session. Port 22 is your SSH port which
// is open in your firewall setup.
session = jsch.getSession("sshuser", remote_host, 22);
session.setPassword("sshpassword");
// Additional SSH options. See your ssh_config manual for
// more options. Set options according to your requirements.
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("Compression", "yes");
config.put("ConnectionAttempts","2");
session.setConfig(config);
// Connect
session.connect();
// Create the tunnel through port forwarding.
// This is basically instructing jsch session to send
// data received from local_port in the local machine to
// remote_port of the remote_host
// assigned_port is the port assigned by jsch for use,
// it may not always be the same as
// local_port.
assigned_port = session.setPortForwardingL(local_port,
remote_host, remote_port);
} catch (JSchException e) {
LOGGER.log(Level.SEVERE, e.getMessage()); return;
}
if (assigned_port == 0) {
LOGGER.log(Level.SEVERE, "Port forwarding failed !");
return;
}
// Database access credentials. Make sure this user has
// "connect" access to this database;
// these may be initialized somewhere else in your code.
final String database_user="myuser";
final String database_password="pass";
final String database = "mydb";
// Build the database connection URL.
StringBuilder url =
new StringBuilder("jdbc:mysql://localhost:");
// use assigned_port to establish database connection
url.append(assigned_port).append ("/").append(database).append ("?user=").
append(database_user).append ("&password=").
append (database_password);
try {
Class.forName(
"com.mysql.jdbc.Driver");
System.out.println(url.toString());
java.sql.Connection connection =
java.sql.DriverManager.getConnection(url.toString());
String q="select * from customer";
PreparedStatement ps=connection.prepareStatement(q);
ResultSet rs= ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1)+rs.getString(2));
}
} catch (ClassNotFoundException |
java.sql.SQLException e) {
LOGGER.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
}
finally{
session.disconnect();
}
I am using Java Eclipse on Windows, and have Mysql set up on Solaris 10. I have used JSch but it is not letting me to connect to Mysql database with root user.
I am getting the below error:
Connected
localhost:3306 -> xxx.xx.xxx.xxx:3306
Port Forwarded
java.sql.SQLException: Access denied for user: 'root#192.168.1.1' (Using password: YES)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1056)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3376)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3308)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:894)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1309)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2032)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:729)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:283)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at ir.mnaeimabadi.hello.mysqltest.main(mysqltest.java:47)
Actually when in this line:
DriverManager.getConnection (url, dbuserName, dbpassword);
It is giving me the error.
This is overall code:
package ir.mnaeimabadi.hello;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.sql.Connection;
public class mysqltest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int lport=3306;
String rhost="xxx.xx.xxx.xxx";
String host="xxx.xx.xxx.xxx";
int rport=3306;
String user="myusr";//ssh user
String password="mypass";//ssh pass
String dbuserName = "root";//mysql user
String dbpassword = "rootPass"; //mysql pass
String url = "jdbc:mysql://xxx.xx.xxx.xxx:";
String driverName="com.mysql.jdbc.Driver";
Connection conn = null;
Session session= null;
try{
//Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
System.out.println("Port Forwarded");
url = url+assinged_port+"/myDB";
//mysql database connectivity
Class.forName(driverName).newInstance();
conn = DriverManager.getConnection (url, dbuserName, dbpassword);
System.out.println ("Database connection established");
System.out.println("DONE");
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if(conn != null && !conn.isClosed()){
System.out.println("Closing Database Connection");
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(session !=null && session.isConnected()){
System.out.println("Closing SSH Connection");
session.disconnect();
}
}
}
}