Hi I am trying to connect via ssh tunneling to a database on a server, but I can't even get the Jsch session to connect. I am attempting to do this in GWT as part of my back-end code. So this is in the Implementation part of the server side code.
I am not that familiar with servers in general. Typically in terminal I type:
ssh -x username#xxxxx.xxx.edu
Then I am prompted for my password and I enter the password and then I am in.
So in java my code is as follows:
String host="xxxxx.xxx.edu";
String user="username";
String password="password";
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();
}
I've double checked the username and the password and the host string and they are all what I use in terminal successfully.
The error I get on the 'session.connect()' line is as follows: (scroll right to see whole error)
com.jcraft.jsch.JSchException: java.security.AccessControlException: access denied (java.net.SocketPermission xxxxx.xxx.edu resolve)
at com.jcraft.jsch.Util.createSocket(Util.java:341)
at com.jcraft.jsch.Session.connect(Session.java:194)
at com.jcraft.jsch.Session.connect(Session.java:162)
at com.front.server.GameServiceImpl.createGame(GameServiceImpl.java:39)
Is there something I am missing? Is this not identical to what I do in terminal to sign in via ssh? I have also tried prepending 'ssh://' to the host string as well but to no avail.
Thanks in advance!
I figured out that there is no problem with the code above. I copied/pasted it into a simple java main and it worked fine. It appears there is something wrong with putting that same code in GWT back-end.
According to the exception message, it seems that the problem has not come from JSch.
Refer to Security and Permissions on java.sun.com:
All applets and any applications invoked with a security manager must
be granted explicit permission to access local system resources apart
from read access to the directory and its subdirectories where the
program is invoked. The Java platform provides permissions to allow
various levels of access to different types of local information.
,and see SocketPermission section.
Related
I am using JSch in a Java client to connect to a remote server and get some files using SFTP. The following code has been working fine for me: -
JSch ssh = new JSch();
JSch.setConfig(FileTransferConstants.STRICT_HOST_KEY_CHECKING, FileTransferConstants.NO);
Session session = ssh.getSession(userName, host, port);
session.setPassword(password);
session.connect();
Channel channel = session.openChannel(FileTransferConstants.SFTP);
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
sftp.cd(remoteDirectoryPath);
sftp.lcd(localDirectoryPath);
sftp.get(remoteDirectoryPath + remoteFileName, remoteFileName);
The problem is that there has now been a change of site policy. I am no longer permitted to log on directly as this user (userName above). I must first log on as my personal user and then su into the user that has access to the files I want to SFTP.
I don't think there is anyway I can refactor the above code to achieve this and so I have started looking at using a shell or exec channel instead. I have had little success so far and cannot seem to find any examples on the web, so I would be very grateful for any advice or pointers in the right direction. Many thanks.
I do not think you can do this directly with JSch. But with some modification of its code, it's probably doable.
Note that my answer assumes that the server is *nix-based (what is backed by your reference to su) and uses OpenSSH SFTP server.
You have to open SSH "exec" channel, to execute something like:
sudo /bin/sftp-server
But on top of that channel, you need to build the ChannelSftp instance, not ChannelExec.
So you will need to implement Session.openChannel-like method, that will open exec channel, but create ChannelSftp for it.
For some background, see how it's possible to do sudo with WinSCP SFTP client.
Note that while the FAQ claims, that you won't be able to use password for the sudo, that's true for WinSCP. But as you have a full control of the session with JSch, you may be able to feed the password to sudo.
For that you might override the ChannelSftp.start() to write the password to the channel input, before starting the actual SFTP session.
You still need the requiretty option be off, as the SFTP cannot work with TTY.
For general considerations when automating operations using a different/root account, see:
Allowing automatic command execution as root on Linux using SSH
I am able to connect to our SFTP server using WinScp(sftp client app) but before that i need to establish a session locally using MFA.
Now i am trying to achieve this programmatically using JSch but i am getting SocketTimeoutException
because i think it requires the same MFA setup to be done programmatically, if my understanding is correct then is there a way to achieve this using JSch ?
JSch jsch = new JSch();
Session session = jsch.getSession(userName, hostName, 22);
session.setPassword(password);
session.connect();
It throws exception at session.connect().
I am closing this question myself as there is no additional setup is required for this. From the machine on which this code is getting executed, if that machine has established the MFA session then it should work seamlessly and without making any other change.
It did not work for me earlier because my MFA session was expired.
So, I haven't worked with docker for very long. But this is the first time where I've had a requirement to ssh OUT of a docker container. It should be straight forward because I know I can connect to databases pull files from repositories. But for some reason I cannot seem to connect to a remote sftp server. Interestingly on my local it runs fine (no docker), but when building on Jenkins the tests cannot connect. Even to a MOCK server that I set up and put a test file on before the tests run. Running on Jenkins also makes it difficult to debug what the issue is.
Im using Jcraft to get the connection below:
public static Session getSession (String host, String user) throws JSchException{
JSch jsch = null;
int port = 22;
if (JunitHelperContext.getInstance.isJunit()){
port = JunitHelperContext.getInstance.getSftpPort();
Session session = jsch.getSession(user,host,port);
java.util.Properties config = new java.util.Properties();
config.put(“StrictHostKeyChecking”, “no”);
if (!JunitHelperContext.getInstance.isJunit()){
config.put(“PreferredAuthentications”, “publickey”);
jsch.setKnownHosts(”~/.ssh/known_hosts”);
jsch.addIdentity(“~/.ssh/id_rsa”);
}
session.setConfig(config);
session.connect();
return session;
}
}
My requirement is to go out and read a file and process it. I can build the kit fine using a non-docker template. The file is found and processed. Running it inside a docker container though, I get this error when I try to connect:
Invalid Key Exception: the security strength of SHA-1 digest algorithm is not sufficient for this key size.
com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
So this seems like a security issue. In production, the certificates are on the server and they can be read in that /.ssh directory. But this is a mock Jcraft server, and I shouldnt need to authenticate.
Is there a piece I am missing here? Configuration in the docker file ?Thanks in advance.
You probably need to enable Java's JCE unlimited strength stuff in the docker container:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
There are export restrictions on this cryptography stuff and I'll bet your docker container has the weak strength exportable jars.
Copy local_policy.jar and US_export_policy.jar into the docker container with the Dockerfile and overwrite what's there.
Follow the instructions at that link.
I am trying to connect to EC2 instance with the following Java code:
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
Session session = jSch.getSession(username, EC2-IP, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
In EC2 IAM web console I created an user/password and I can use it to login to AWS management console. But when I use this user/password in the above Java code, I receive:
Error: com.jcraft.jsch.JSchException: Auth fail
SSH/SFTP username for Amazon EC2 is:
For an Amazon Linux AMI, the user name is ec2-user.
For a RHEL AMI, the user name is ec2-user or root.
For an Ubuntu AMI, the user name is ubuntu or root.
For a Centos AMI, the user name is centos.
For a Fedora AMI, the user name is ec2-user.
For SUSE, the user name is ec2-user or root.
See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html
To authenticate, use a private key that you have associated with the instance, when you were creating the instance.
See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html
In general, you should first setup and test connection with some standalone SFTP/SSH client. And only then try to connect with your code.
I have written a guide for connecting to Amazon EC2 with WinSCP SFTP client. If you follow it and make a successful connection with WinSCP, it should be then easy to do the same with JSch code.
I am trying to copy some files from a Windows machine to a Linux machine, which is working fine with JSch so far. I can copy files using StrictHostKeyChecking no or I need to have the known_host file from the Linux machine I copy to. I am using the code for a Java project which should be able to send files automatically to (unknown) Linux machines. I got the username, password, IP and the publickey for the machine. Is there any way to authenticate without the known_host file and via the publickey? Because of security issues I do not want to switch StrictHostKeyChecking to no but then I get "com.jcraft.jsch.JSchException: UnknownHostKey"
FileInputStream fis = null;
JSch jsch = new JSch();
//jsch.setKnownHosts("");
jsch.addIdentity("D:\\Uni\\Arbeit\\remote_id_rsa");
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
//session.setConfig("StrictHostKeyChecking", "no");
session.connect();
That does not make sense. Either you know the host public key and you can verify it either using the known_host file or programmatically using:
public void KnownHosts.add(HostKey hostkey, UserInfo userinfo)
(You can access the instance of KnownHosts using Session.getHostKeyRepository())
For more details, see How to resolve Java UnknownHostKey, while using JSch SFTP library?
Or you do not know the host public key, and then you cannot create a secure connection (and the StrictHostKeyChecking=no is your only option).
See my article about verifying the host key to understand, what is it about, and its importance. The article is about WinSCP client, but it's valid in general for any SSH client.