I want use JSch as a common shell interactive tool, it's really useful.
I want create a ssh which is inner JSch channel shell and the shell's InputStream and OutStream is maintained by myself.
The problem is when I send a command string, ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=2 -o StrictHostKeyChecking=no -o ConnectTimeout=10 -T root#xxx.xxx.xxx.xxx -p 22, to OutputStream to setting a keep-live by ServerAliveInterval but it not works at all.the new channel will hold 1 min when I close network.This time is more over my config ServerAliveInterval=5 ServerAliveCountMax=2.
Is JSch support inner ssh connection setting to handle keep-alive check, such as ServerAliveInterval?
UPDATE
some step to describe the question:
1. create a shell channel use JSch to login host1
2. use the channel jump to host2 by send a command ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=2 root#xxx.xxx.xxx.xxx -p 22 which is a byte stream. The new ssh is config with ServerAliveInterval to check ssh network status of host2.
JSch can recognize host1 is disconnect if I'm use Session.setServerAliveInterval method and test it with Session.isConnected.
The problem is host2 can't be checked if only host2 network is break even through I'm use ServerAliveInterval config when jump to host2.It will hold a long time (more then 1min on my test) until get a packet_write_wait: Connection to xxx.xxx.xxx.xxx port 22: Broken pipe. But I'm expect some error message arrived less then 10 seconds as the ServerAliveInterval=5 ServerAliveCountMax=2 was set.
The shell is a black box for JSCh.
JSch is not aware of anything that you do there.
If you want to emulate, what OpenSSH ServerAliveInterval directive does, use Session.setServerAliveInterval.
See also JSch: How to keep the session alive and up.
Related
I'm trying to implement a "dynamic" proxy forward to access localhost from Internet, like Ngrok in pure Java.
This guy does essentially the same thing: https://serveo.net/#intro (but, without a client)
The idea would be to use the SAME port on the server, and make a dynamic proxy for each client, based on a subdomain
The problem is that the default implementation throws error on the second connection .. saying that the port is already open.
org.apache.sshd.common.forward.DefaultForwardingFilter # doBind
Who has an idea of how to implement this?
The advantage of this is that you do not even need a CLIENT like Ngrok for that ... just using normal ssh would be possible.
ssh -R http2:9000:localhost:8002 localhost -p 4440
ssh -R http2:pSERVER:localhost:pLOCAL localhost -p SSHD_PORT
an option I imagined, is to generate the ports dynamically on the server: IGNORING THE 'pSERVER' port, and creating an HttpProxy, to do the redirection for each port. But I find this very inefficient, I believe it would be possible to do only by analyzing the request header and making the redirects for the corresponding channels / connections
After too much headache.
The code is in very low quality, just a proof of concept that can be implemented.
The implemented idea was made by changing sshd-netty, and adding a function to unpack the http request and remove the HOST HEADER (this needs to be improved here).
Only 1 port on the server is used, and it is kind of a reverse proxy for clients ...
I would like the help of the developers to improve the code in question. My knowledge in Netty and Mina is very limited.
Appreciate:
Source: https://github.com/ricardojlrufino/sshd-dyn-tunneling
Testing: Open 2 connections:
ssh -v -R http1:9000:localhost:8001 localhost -p 4440
ssh -v -R http2:9000:localhost:8002 localhost -p 4440
Make requests:
curl -v -H "Host: http1" http1:9000
curl -v -H "Host: http2" http2:9000
Start test servers:
https://github.com/ricardojlrufino/sshd-dyn-tunneling/blob/tunel/src/test/resources/setup_remotes.sh
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 attempting to use the JSch class (Java Secure Channel; jsch-0.1.50.jar) to connect to an SFTP server and send a file from within a ColdFusion (9.0.2) application (which runs atop Java 1.7.0_15). The basic code in question is:
jsch = classLoader.create("com.jcraft.jsch.JSch").init(); // ColdFusion-specific to load the jar
jschSession = jsch.getSession("myusername", "ftp.example.com", 22);
jschSession.setConfig("StrictHostKeyChecking", "no");
jschSession.setTimeout(60000);
jschSession.setPassword("mypassword");
jschSession.connect();
Upon connection to a Serv-U SFTP server it is giving me the following error on the Serv-U side immediately after the connection opens:
SSH Protocol Error: packet size exceeds maximum allowed.
Serv-U then closes the session, at which point JSch throws the exception:
Session.connect: java.io.IOException: End of IO Stream Read
I am new to the JSch class, and it's possible I'm missing something obvious, but I am at a loss as to where the error may lie. Connecting to the same SFTP server from the same origin with WinSCP gives no errors. Any tips on what the code is doing wrong or where to turn next for troubleshooting?
SSH Protocol Error: packet size exceeds maximum allowed
This means that the local client received some data from the remote server which wasn't properly formatted as an SFTP protocol message. The usual reason is that the server sent some kind of plain text message through the SSH connection. There are few things that might be going on:
Your .bashrc, .bash_profile, or similar shell configuration file on the server is set to print some message.
The server is poorly configured, and it's sending some kind of greeting.
The server is sending some kind of error message.
If you have access to the ssh command-line utility, you can use that to see what the server is sending. Run something like this:
$ ssh myusername#ftp.example.com -s sftp
This will open a plain SSH session to the remote server and request the SFTP subsystem, which is the same thing an SFTP client would do. If the server starts SFTP properly, you won't see any output from this command--it'll just wait until you kill it. If you see any text from the remote server, that is the problem. You'll need to figure out why the server is sending that text and prevent it.
I'm trying to connect to a RMI registry that I have started on a remote server, but I get the following exception after a while:
java.rmi.ConnectException: Connection refused to host: *.*.*.*; nested exception is:
java.net.ConnectException: Connection timed out
By running the client localy on the server everything works, but I can't connect to it remotely; Not even from telnet. However, if I run
start rmiregistry 1337
I can connet to it remotely from telnet. I'm assuming that it's something I have to set up when I'm running the server code, but I have trouble finding out what it is.
This is part of the server code:
String codeBasePath = "file:/C:/*path*/build/classes";
System.setProperty("java.rmi.server.codebase", codeBasePath);
System.setProperty("java.rmi.server.hostname", *host IP*);
RemoteFileServer server = new FileServer();
Registry registry = LocateRegistry.createRegistry(PORT);
registry.bind(*name*, server);
System.out.println("Server ready");
Let me know if you need more info/code to help me figure it out.
Ok there is two options I can think of
1 - Did you give permission for incoming connections with a security policy. This step is quite simple actually see here: rmi run tutorial
2 - The port might be closed for outside from OS. For example if you are using linux you need to open the port from iptables like:
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1099 -j ACCEPT
iptables -A OUTPUT -m state --state NEW -m tcp -p tcp --dport 1099 -j ACCEPT
or if you use windows you can configure it from firewall.
If anything is unclear you can ask.
I am developing a Java tool which uploads a file from one remote server to another.
The program will run on a laptop. The software needs to connect to serverA with SSH protocol then once it is connected to serverA, it has to transfer files to serverB through FTP.
Files to be transfered are hosted on serverA.
I cannot directly connect to serverB because of a firewall.
Here is a summary:
Is it possible to do that with JSch? Something like the following:
JSch client = new JSch();
Session session = client.getSession("login", "serverA", 22);
// test purpose
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("password");
session.connect();
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("ftp -i ftp://username:password#serverB; put file.txt; close; quit;");
EDIT
What about writing a script and upload it on the serverA?
#!/bin/sh
ftp -n -i <<ENDOFINPUT
open serverB
user root password
cd /home/root
put xxx
close
bye
ENDOFINPUT