How to choose network interface when connecting to SFTP using JSch
I am facing the problem of creating a session on the remote SFTP server JSch:
The command I'm using to connect the sftp server through the shell:
sftp -o BindAddress=SOME_IP_ADDRRESS myUserName@HOST_IP_ADDR
and its working fine, but when I try to use Java (JSch) I get a timeout exception. Java code
/* KEY_FILE_NAME = is a file with rsa public key */
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(KEY_FILE_NAME).getFile());
JSch jsch = new JSch();
jsch.addIdentity(file.getAbsolutePath());
Properties hash = new Properties();
hash.put("StrictHostKeyChecking", "no");
logger.debug("SSh Server Host name >>" + SSH_SERVER_HOST_NAME + " || User Name >>" + SSH_SERVER_USER_NAME);
session = jsch.getSession(SSH_SERVER_USER_NAME, SSH_SERVER_HOST_NAME);
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.setConfig(hash);
session.setPort(22);
session.setTimeout(45000);
session.connect();
The exception I am getting is:
com.jcraft.jsch.JSchException: Timeout: socket not set
I am assuming this will happen as I am not setting the parameter BindAddress
with the parameter -o
I am using when I use the shell command. If so, how do you set the parameter -o BindAddress
in JSch? Or am I doing something wrong, please suggest.
source to share
I don't think there is explicit support for choosing a network interface to connect in JSch.
But you can implement an SocketFactory
interface, for example, it instantiates Socket
using constructor overload withlocalAddr
:
public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
(use 0 for localPort
)
Then pass the factory in Session.setSocketFactory()
before the call connect()
and you should be good to go.
source to share
I have implemented the solution, I added the following code before the call session.connect()
.
session.setSocketFactory(new SocketFactory()
{
InputStream in = null;
OutputStream out = null;
public InputStream getInputStream(Socket socket) throws IOException
{
if (in == null)
in = socket.getInputStream();
return in;
}
public OutputStream getOutputStream(Socket socket) throws IOException
{
if (out == null)
out = socket.getOutputStream();
return out;
}
public Socket createSocket(String host, int port) throws IOException, UnknownHostException
{
// The IP Addresses are changed ....
// using the original IP in my code
byte[] remoteIpAddr = new byte[] { (byte) 11,(byte) 11, 11, 11 };
byte[] localIpAddr = new byte[] { 55, 55, 55, 55 };
InetAddress remoteIp = InetAddress.getByAddress(remoteIpAddr);
InetAddress localIp = InetAddress.getByAddress(localIpAddr);
logger.debug("remoteIp >>" + remoteIp.toString());
logger.debug("localIp >>" + localIp.toString());
Socket socket = new Socket(remoteIp, 22, localIp, 0);
logger.debug("socket created >> " + socket.toString());
return socket;
}
});
And its socket creation: checked the log file for ->
logger.debug("socket created >> " + socket.toString());
But now I am getting an exception:
Cancellation cancellation
What could be the reason. The key I have is the id_rsa.pub file which starts with
ssh-rsa AXTYU....
and I created a private key file from this file via keygen which I use in my method session.addIdentity()
, private key format:
-----BEGIN RSA PRIVATE KEY-----
KIOPU.....
-----END RSA PRIVATE KEY-----
I am missing something, please suggest ...
source to share
This will allow you to bind to a specific address (and port if needed): fooobar.com/questions/17540958 / ...
source to share