Cannot connect to mysql server from java - java

I get the error "Communications link failure" at this line of code:
mySqlCon = DriverManager.getConnection("jdbc:mysql://**server ip address**:3306/db-name", "mu-user-name", "my-password");
I checked everything in this post:
I increased max-allowed-packet in my.cnf in etc/mysql: max_allowed_packet = 5073741824------ [mysqldump] max_allowed_packet = 1G
The bind-address is: 127.0.0.1
All timeout values are equal to a number
Tomcat is not yet installed on server (new server)
There is no skip-networking in my.cnf
I can ping the server
I am connected to the mysql database via ssh
When I change the query string to this:
mySqlCon = DriverManager.getConnection("jdbc:mysql://**server ip address**:22/127.0.0.1:3306/db-name", "mu-user-name", "my-password");
I get the error Packet for query is too large (4739923 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
While I have changed the packet size on my.cnf and restarted the mysql service after that.
Any suggestions?
NOTE:
I can connect through ssh with this code, but this way doesn't seem rational! I can connect once in main and then I should pass the connection to all the classes.
public my-class-constructor() {
try {
go();
} catch (Exception e) {
e.printStackTrace();
}
mySqlCon = null;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + rhost + ":" + lport + "/";
String db = "my-db-name";
String dbUser = "dbuser";
String dbPasswd = "pass";
try {
Class.forName(driver);
mySqlCon = DriverManager.getConnection(url + db, dbUser, dbPasswd);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void go() {
String user = "ssh-user";
String password = "ssh-pass";
String host = "ips-address";
int port = 22;
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
lport = 4321;
rhost = "localhost";
rport = 3306;
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
int assinged_port = session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:" + assinged_port + " -> " + rhost
+ ":" + rport);
} catch (Exception e) {
System.err.print(e);
e.printStackTrace();
}
}

Take a look here .
Looks the following describes your case
The largest possible packet that can be transmitted to or from a MySQL
5.7 server or client is 1GB.
When a MySQL client or the mysqld server receives a packet bigger than
max_allowed_packet bytes, it issues an ER_NET_PACKET_TOO_LARGE error
and closes the connection. With some clients, you may also get a Lost
connection to MySQL server during query error if the communication
packet is too large.
Both the client and the server have their own max_allowed_packet
variable, so if you want to handle big packets, you must increase this
variable both in the client and in the server.
So, it looks like you need to change the max_allowed_packet on the client as well:
mySqlCon = DriverManager.getConnection("jdbc:mysql://**server ip address**:3306/db-name?max_allowed_packet= 5073741824", "mu-user-name", "my-password");

I changed the binding address in my.cnf file in /etc/mysql to the ip address of the server, and it solved the problem.

Related

How to forward remote port 3306 to local port in android programmatically with ssh and connect to mysql

I want to transfer data from an android SQLite database to a remote mysql database securely. As I can't setup a VPN programmatically I want to transfer the data through an ssh tunnel. I have tried with jkraft.jsch. The forwarding runs without errors, but when I connect with mysql-connector
with
conexionMySQL = DriverManager.getConnection("jdbc:mysql://localhost:53009/",user, password);
I get the following error:
java.sql.SQLException: Communication link failure: java.io.EOFException, underlying cause: null
** BEGIN NESTED EXCEPTION **
java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1395)
at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:1414)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:625)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1808)
at com.mysql.jdbc.Connection.<init>(Connection.java:452)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:411)
at java.sql.DriverManager.getConnection(DriverManager.java:179)
at java.sql.DriverManager.getConnection(DriverManager.java:213)
at de.damian.android.common.Mysql$2.run(Mysql.java:151)
at java.lang.Thread.run(Thread.java:841)
** END NESTED EXCEPTION **
The code is:
public int connectSSH(int rport)
{
//
int assigned_port;
final int local_port = 53009;
// Remote host and port
final int remote_port = rport;
final String remote_host = "test.test.org";
try
{
jsch = new JSch();
// Create SSH session. Port 22 is your SSH port which.
// is open in your firewall setup.
session = jsch.getSession("xxx", remote_host, 22);
session.setPassword("xxxxxx");
// 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)
{
Log.e(Level.SEVERE.toString(), e.getMessage(), e);
return 0;
}
if (assigned_port == 0)
{
Log.e(Level.SEVERE.toString(), "Port forwarding failed !");
return 0;
}
return assigned_port;
}
The answer is quite simple: setPortForwarding must use "localhost" as hostname as the remoteport is not open on the remote interface and you are already logged in in the remote host.
assigned_port = session.setPortForwardingL(local_port,
"localhost", remote_port);

jcraft with copSSH throws Algorithm negotiation fail error in windows environment

I'm developing java program to connect with windows server over ssh. For this I used jcraft on java. And the ssh server is copSSH. The implementation throws
Error: com.jcraft.jsch.JSchException: Algorithm negotiation fail
error on java. At the same time it shows
fatal: Unable to negotiate with 192.168.28.111: no matching cipher
found. Their offer: aes128-cbc,3des-cbc,blowfish-cbc [preauth]
on CopSSH.
Java code block
public void sshExecPassword(String host, String USERNAME, String PASSWORD, String command) {
App objApp = new App();
int port = 22;
try {
/**
* Create a new Jsch object This object will execute shell commands
* or scripts on server
*/
JSch jsch = new JSch();
/*
* Open a new session, with your username, host and port Set the
* password and call connect. session.connect() opens a new
* connection to remote SSH server. Once the connection is
* established, you can initiate a new channel. this channel is
* needed to connect to remotely execution program
*/
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
Session session = jsch.getSession(USERNAME, host, port);
session.setConfig(config);
session.setPassword(PASSWORD);
session.connect();
// create the excution channel over the session
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
// Gets an InputStream for this channel. All data arriving in as
// messages from the remote side can be read from this stream.
InputStream in = channelExec.getInputStream();
// Set the command that you want to execute
// In our case its the remote shell script
String str = command;
channelExec.setCommand(str);
channelExec.connect();
// Read the output from the input stream we set above
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// retrieve the exit status of the remote command corresponding to
// this channel
int exitStatus = channelExec.getExitStatus();
// Safely disconnect channel and disconnect session. If not done
// then it may cause resource leak
channelExec.disconnect();
session.disconnect();
if (exitStatus < 0) {
System.out.println("Done, but exit status not set! " + exitStatus);
objApp.writeLogs("120","Done, but exit status not set! ");
} else if (exitStatus > 0) {
System.out.println("Done, but with error!");
objApp.writeLogs("120","Done, but with error!");
} else {
System.out.println("Done!");
objApp.writeLogs("121","SSH connection successful");
}
} catch (Exception e) {
System.err.println("Error: " + e);
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
objApp.writeLogs("120", sw.getBuffer().toString());
}
}
And the CopSSH host following versions
OpenSSH_7.1p2, OpenSSL 1.0.2e 3 Dec 2015
Can any one suggest a fix for it?
That happens due to lacking support for legacy ciphers in more recent releases of OpenSSH. Check this Copssh FAQ for a solution. Background information can also be found here.
Latest jcraft jar fix the issue

Java socket - client and server IP address

I am writing a program with TCP sockets connection between client and server. When the server starts I want to display the IP and port that clients need to use to connect, and when client connects I want the server to show what IP did the client connect from. I am getting confused which command should i use to each of those:
getInetAdress()
getLocalAdress()
getRemoteSocketAdress()
edit
I earlier used int port = 1234 and String IP = "localhost" to test and it worked, but I only used it on one PC, so I think localhost will not work if i start server and client on different computers.
This is server side:
int port = 1234;
...
public void start() {
keepRunning = true;
// create socket
try {
ServerSocket server = new ServerSocket(port);
while (keepRunning) {
display("Waiting for client connections on "
+ server.getInetAddress().getLocalHost()
.getHostAddress() + ":" + port);
Socket conn = server.accept();
if (!keepRunning)
break;
ClientThread t = new ClientThread(conn);
cList.add(t);
t.start();
And this is client:
int port = 1234;
String IP = "localhost";
//these variables can be changed from Client GUI before making connection
...
public boolean start() {
try {
socket = new Socket(IP, port);
} catch (Exception e) {
display("Error connectiong to server:" + e);
return false;
}
try {
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return false;
}
When i start the server,
display("Waiting for client connections on " + server.getInetAddress().getLocalHost().getHostAddress() + ":" + port);
return this:
Waiting for client connections on 192.168.1.104:1234
which is kind of what i want, but I still cant get it to show me the port. 1234 is a fixed value i used, but I want to use ServerSocket server = new ServerSocket(0); to asign port dynamically, then when i start the client i just put in the values that i got from server and connect.
I tried to use server.getLocalPort() in the display line in server and it returned 55410 or something like that, but when i put this port in client to make connection, it doesn't work. I get Error connectiong to server:java.net.ConnectException: Connection refused: connect. from client
To get the current port that the ServerSocket is listening to, use getLocalPort();
http://download.java.net/jdk7/archive/b123/docs/api/java/net/ServerSocket.html#getLocalPort%28%29
getLocalPort
public int getLocalPort()
Returns the port number on which this socket is listening.
If the socket was bound prior to being closed, then this method will continue to return the port number after the socket is closed.
Edit: Just saw your edit. Are you trying to connect by explicitly referencing the IP and Port? If so, and it's still failing, your server machine might be running a firewall. I'd check for that first.

JSchException: UnknownHostKey

I'm trying to use Jsch to establish an SSH connection in Java.
I have set "StrictHostKeyChecking" to yes. I understand that the hostkey of the server has to be obtained before hand and store in the hostkey file
before the first attempt to connect to the server. How can I get the HostKey of the server. My code produces the following exception:
com.jcraft.jsch.JSchException: UnknownHostKey: ASY-PC
RSA key fingerprint is 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4
How can I make connection with StrictHostKeyChecking Yes.
Here is my code.
package sshexample;
import com.jcraft.jsch.*;
import java.io.*;
public class SSHexample
{
public static void main(String[] args)
{
String user = "user";
String password = "password";
String host = "192.168.100.103";
int port=22;
try
{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "yes");
System.out.println("Establishing Connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
}catch(Exception e) {
e.printStackTrace();
}
}
You have to supply a KnownHostKeys file by calling following function
jsch.setKnownHosts(new FileInputStream(knownHostsFile));
this file should have all the the known hosts' fingerprints separated by new lines.
for example
hostname,10.1.1.120, ssh-rsa AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SItb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
you can obtain this key from server by using any sftp client however following command may help if you are using linux or unix
ssh-keyscan -t rsa 10.1.1.120
After a few minutes of testing i found a solution for this. If you don't want to use the default knownHost File, just create your own
This how the file could look:
192.168.0.1 ssh-rsa
AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SI
tb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif
/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X
/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU
/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
And all those entries are separated by new lines. You get the RSA key that you want by asking your session:
session=null;
com.jcraft.jsch.Channel channel =null;
try{
ssh=new JSch();
ssh.setKnownHosts("test");
session=ssh.getSession(userTextField.getText(),ip,22);
session.setPassword(passwordField1.getText());
System.out.println(session.getHostKey());
session.connect();
channel=session.openChannel("sftp");
channel.connect();
ChannelSftp sftp=(ChannelSftp) channel;
System.out.println(sftp.getHome());
for (Object o : sftp.ls(sftp.getHome())) {
System.out.println(((ChannelSftp.LsEntry)o).getFilename());
}
} catch (JSchException e1) {
e1.printStackTrace();
addHost(session.getHostKey().getKey());
} catch (SftpException e1) {
e1.printStackTrace();
}
}
private void addHost(String key){
try {
FileWriter tmpwriter=new FileWriter("test",true);
tmpwriter.append(ip + " ssh-rsa " + key+"\n");
System.out.println(ip + " ssh-rsa " + key);
tmpwriter.flush();
tmpwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
So session.getHostKey().getKey() is what you want to call to get the key.
You also need to call session.connect(); before you ask for the key and handle it in the catch.
As most the of the answers suggest you have to provide know host file but fail to address how to get it. You simply need to SSH to the host.
Eg ssh user#192.168.100.103
when prompted provide password. For first time connection it will you to save the hosts ssh key fingerprint. Once you are connected you can find your known_host file at
user/.ssh/known_hosts
For me on windows path is C:\Users\athakur\.ssh\known_hosts. You can directly use this file. Or edit the file and pick up entry from it corresponding to your IP address which would look something like
192.168.100.103 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1UsgiLH5hjIScZlqPA4kNhPoXAX00mMv65N8qTvYd1D1M5DwWtTTcxK4w0wGKKVA7RERzWbtjPpSomJwT1LofZr+qafLdiEvhirIXVYHSWZqp6zTJW0jzk3p07ugjoHV3YUWKDzOaiFuOMslt8hD7pZv8nhOYfxBZdsVHdukYRP8MADXC0ZgOD5ZYZ0EglaQJYPG7n73PSMZWZT/oafUcx6bFiRF4QsXaguWuu6umX9gaV7VvoyMJg+kxPAKnGDFY7If61AG7vAchUUhlQ44SB1FFr25y+qeUg2NGqAxH/Z/ZAfvZ+pDv3Cd9s+KCnEIqxyxY/sPQ2zCvwf0Z9fTeQ==
Note : Host machines SSH fingerprint (based on hosts public key that you can find at /etc/ssh/ssh_host_rsa_key.pub) may change in SSH is reinstalled in that machine. Or you may encounter MIM attack (even it is for testing sake). In such cases you will have to pick new entry in same way mentioned above.
Maybe it's no more relevant but in my case, the similar problem was happened with docker-compose.yml in container, that was build from spring-boot application that 100 % worked locally
config-service:
image: <host>/<bla>-config-service:<version>
hostname: config-service
ports:
- 3000:3000
depends_on:
- discovery
environment:
- CONSUL_HOST=discovery
- CONSUL_PORT=<port>
- CONFIG_GIT_URI=git#<host>:<group>/<repository>.git
- CONFIG_GIT_BRANCH=development
volumes:
- ~/.ssh/:/root/.ssh/:ro
Solution was to apply hack on ~/.ssh folder.
chcon -Rt svirt_sandbox_file_t ~/.ssh
After that I suppose volumes was correctly mapped between docker container and local machine, and described exception was gone.
Based on #nothing-to-know answer, the following method can be very handy:
public static String getHostKey(String hostName, int port, String userName, char[] password) {
JSch ssh;
Session session = null;
String hostKey = "";
try {
ssh = new JSch();
session = ssh.getSession(userName, hostName, port);
session.setPassword(new String(password));
if (session.getHostKey() != null) {
hostKey = session.getHostKey().getHost() + " " + session.getHostKey().getType() + " " + session.getHostKey().getKey();
}
session.connect();
} catch (JSchException e1) {
hostKey = session.getHostKey().getHost() + " " + session.getHostKey().getType() + " " + session.getHostKey().getKey();
} finally {
session.disconnect();
return hostKey;
}
}

What name do i use to connect to a server socket in java

I am writing a telnet like program in java using the server socket and socket classes. This is my current code for the client program. The user types in the server name and the port they would like to connect on.
static Socket getSocket()
{
while(true)
{
System.out.println("What server do you want to connect to on which port?");
String info = sc.nextLine();
String host = info.split(" ")[0];
int port = Integer.parseInt(info.split(" ")[1]);
try
{
InetAddress ip = InetAddress.getByName(host);
return new Socket(ip, port);
}
catch (UnknownHostException e)
{
System.err.println("The host is unknown.");
}
catch (IOException e)
{
System.err.println("Network error.");
}
}
}
I tried connecting on localhost, and it worked. Then i tried connecting with my friend on a remote computer using the ip address as the network name and it did not work giving an exception. What name do i use to connect to a remote server.
You need to give your friend your remote IP address.

Categories