问题
I would like to run a simple SSH command like ssh -R 80:localhost:1337 serveo.net
, I know there is library jsch to do this , but it will not work without username and password . In my case there is no authentication is required . How can I do this ?
Update
When I run the command ssh -R 80:localhost:1337 serveo.net -v
, I get the following output
debug1: Server host key: ssh-rsa SHA256:07jcXlJ4SkBnyTmaVnmTpXuBiRx2+Q2adxbttO9gt0M
The authenticity of host 'serveo.net (159.89.214.31)' can't be established.
RSA key fingerprint is SHA256:07jcXlJ4SkBnyTmaVnmTpXuBiRx2+Q2adxbttO9gt0M.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'serveo.net,159.89.214.31' (RSA) to the list of known hosts.
debug1: rekey out after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks
debug1: Will attempt key: /home/paranoid/.ssh/id_rsa
debug1: Will attempt key: /home/paranoid/.ssh/id_dsa
debug1: Will attempt key: /home/paranoid/.ssh/id_ecdsa
debug1: Will attempt key: /home/paranoid/.ssh/id_ecdsa_sk
debug1: Will attempt key: /home/paranoid/.ssh/id_ed25519
debug1: Will attempt key: /home/paranoid/.ssh/id_ed25519_sk
debug1: Will attempt key: /home/paranoid/.ssh/id_xmss
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Trying private key: /home/paranoid/.ssh/id_rsa
debug1: Trying private key: /home/paranoid/.ssh/id_dsa
debug1: Trying private key: /home/paranoid/.ssh/id_ecdsa
debug1: Trying private key: /home/paranoid/.ssh/id_ecdsa_sk
debug1: Trying private key: /home/paranoid/.ssh/id_ed25519
debug1: Trying private key: /home/paranoid/.ssh/id_ed25519_sk
debug1: Trying private key: /home/paranoid/.ssh/id_xmss
debug1: Next authentication method: keyboard-interactive
debug1: Authentication succeeded (keyboard-interactive).
Authenticated to serveo.net ([159.89.214.31]:22).
debug1: Remote connections from LOCALHOST:80 forwarded to local address localhost:1337
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: pledge: network
debug1: Sending environment.
debug1: Sending env LC_ADDRESS = en_US.UTF-8
debug1: Sending env LC_NAME = en_US.UTF-8
debug1: Sending env LC_MONETARY = en_US.UTF-8
debug1: Sending env LC_PAPER = en_US.UTF-8
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env LC_IDENTIFICATION = en_US.UTF-8
debug1: Sending env LC_TELEPHONE = en_US.UTF-8
debug1: Sending env LC_MEASUREMENT = en_US.UTF-8
debug1: Sending env LC_TIME = en_US.UTF-8
debug1: Sending env LC_NUMERIC = en_US.UTF-8
debug1: remote forward success for: listen 80, connect localhost:1337
debug1: All remote forwarding requests processed
Forwarding HTTP traffic from https://vacuus.serveousercontent.com
It also creates known_hosts
file inside .ssh
folder. The content of known_hosts
id following
|1|2K3SBFWPCPqI3poBW2X99LiuP8c=|cqCa7m1e23x1P9UpcUuPac+KKI8= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxYGqSKVwJpQD1F0YIhz+bd5lpl7YesKjtrn1QD1RjQcSj724lJdCwlv4J8PcLuFFtlAA8AbGQju7qWdMN9ihdHvRcWf0tSjZ+bzwYkxaCydq4JnCrbvLJPwLFaqV1NdcOzY2NVLuX5CfY8VTHrps49LnO0QpGaavqrbk+wTWDD9MHklNfJ1zSFpQAkSQnSNSYi/M2J3hX7P0G2R7dsUvNov+UgNKpc4n9+Lq5Vmcqjqo2KhFyHP0NseDLpgjaqGJq2Kvit3QowhqZkK4K77AA65CxZjdDfpjwZSuX075F9vNi0IFpFkGJW9KlrXzI4lIzSAjPZBURhUb8nZSiPuzj
|1|F1SIE4/IIEjZPJfHBIx90xnSjSU=|NKCdGqv3SFcGcAqPLvVfuRXI4Ok= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxYGqSKVwJpQD1F0YIhz+bd5lpl7YesKjtrn1QD1RjQcSj724lJdCwlv4J8PcLuFFtlAA8AbGQju7qWdMN9ihdHvRcWf0tSjZ+bzwYkxaCydq4JnCrbvLJPwLFaqV1NdcOzY2NVLuX5CfY8VTHrps49LnO0QpGaavqrbk+wTWDD9MHklNfJ1zSFpQAkSQnSNSYi/M2J3hX7P0G2R7dsUvNov+UgNKpc4n9+Lq5Vmcqjqo2KhFyHP0NseDLpgjaqGJq2Kvit3QowhqZkK4K77AA65CxZjdDfpjwZSuX075F9vNi0IFpFkGJW9KlrXzI4lIzSAjPZBURhUb8nZSiPuzj
回答1:
Here is an example of using serveo through Jsch. The only real "trick" here seems to be specific to serveo. Serveo won't accept tunnel requests until the session has opened a "shell" or "exec" channel. Serveo uses the shell/exec channel to send status messages to the client. So it's necessary to open a shell or exec channel first, then request the remote forward.
The SSH protocol expects the client to supply a user name to login as. The ssh
command line utility defaults to using the local username if you don't supply one. Jsch similarly defaults to using the value of the system property "user.name". Serveo is somewhat unusual in that it'll accept SSH connections from anyone, so you can use whatever name you like. You can let jsch use its default--assuming that works on android--or you can use a hard-coded name like "x" or "foo".
import com.jcraft.jsch.*;
public class App {
public static void main(String[] arg) {
JSch.setLogger(new MyLogger());
JSch jsch = new JSch();
try {
final Session session = jsch.getSession("serveo.net");
session.setHostKeyRepository(new NoSecurityRepo());
session.connect();
// Establish a shell channel to receive messages from serveo
ChannelShell cc = (ChannelShell)session.openChannel("shell");
cc.setPty(false);
cc.setInputStream(System.in);
cc.setOutputStream(System.out);
cc.setExtOutputStream(System.err);
cc.connect();
// Now open a remote forward
session.setPortForwardingR(null, 80, "localhost", 3000);
} catch (Exception e) {
e.printStackTrace();
}
}
private static class MyLogger implements Logger {
@Override
public boolean isEnabled(int level) { return true; }
@Override
public void log(int level, String message) {
System.err.printf("%s\t%s%n", level, message);
}
}
/*
* This implementation of HostKeyRepository is just for demonstration.
* Every time you use it in production, a kitten dies. Please think of
* the kittens.
*/
private static class NoSecurityRepo implements HostKeyRepository {
@Override
public int check(String host, byte[] key) { return HostKeyRepository.OK; }
@Override
public void add(HostKey hostkey, UserInfo ui) { }
@Override
public void remove(String host, String type) { }
@Override
public void remove(String host, String type, byte[] key) { }
@Override
public String getKnownHostsRepositoryID() { return "NoSecurityRepo"; }
@Override
public HostKey[] getHostKey() { return new HostKey[0]; }
@Override
public HostKey[] getHostKey(String host, String type) { return new HostKey[0]; }
}
}
回答2:
I don't think, that your ssh command is not using any authentication. Please verify it using verbose out with ssh -v ...
. I guess it uses publickey
with your default key id_rsa
from ~/.ssh/id_rsa
and the server just accepts any key.
If this is the case, you can do the same using jsch.
final JSch jSch = new JSch();
jSch.addIdentity(idRsaFile);
final Session newSession = jSch.getSession(null, "serveo.net", 22);
newSession.setConfig("PreferredAuthentications", "publickey");
newSession.setConfig("StrictHostKeyChecking", "no");
session.setUserInfo(new UserInfo() {
@Override
public String getPassphrase() {
return null;
}
@Override
public String getPassword() {
return null;
}
@Override
public boolean promptPassword(String message) {
return false;
}
@Override
public boolean promptPassphrase(String message) {
return false;
}
@Override
public boolean promptYesNo(String message) {
return false;
}
@Override
public void showMessage(String message) {
}
});
newSession.connect(connectTimeout);
and then
newSession.setPortForwardingR(...);
来源:https://stackoverflow.com/questions/62663771/how-to-run-ssh-command-in-android-programmatically