简体   繁体   English

如何使用 JSch 将 SSH 连接到另一个 SSH 服务器后面的服务器?

[英]How to SSH to a server behind another SSH server using JSch?

I need to be able to ssh from a Java program into a remote server, and from there SSH to another server.我需要能够将 ssh 从 Java 程序插入远程服务器,然后从 SSH 到另一台服务器。 I have credentials for both servers on my client.我的客户端上的两台服务器都有凭据。

The commands will be passed automatically from within the app as regular strings (no user input).命令将在应用程序内作为常规字符串自动传递(无需用户输入)。 I need to be able to run those custom commands on the second server and be able to decide what commands to issue during runtime, based on the output and some simple logic.我需要能够在第二台服务器上运行这些自定义命令,并能够根据 output 和一些简单的逻辑来决定在运行时发出哪些命令。

Can I use JSch to do that and if yes, where should I start look into?我可以使用 JSch 来做到这一点吗?如果可以,我应该从哪里开始研究? (Examples, info) (示例,信息)

============================================================= ==================================================== ===========

ADDED:添加:

Exception in thread "main" com.jcraft.jsch.JSchException: UnknownHostKey: host.net.线程“主”com.jcraft.jsch.JSchException 中的异常:UnknownHostKey:host.net。 RSA key fingerprint is 'blahblahblah' RSA 密钥指纹是“blahblahblah”

as till now, I am solving this problem by modifying the known_hosts file and adding host manually in there.到目前为止,我正在通过修改 known_hosts 文件并在其中手动添加主机来解决这个问题。 Can I bypass this little problem by settings an option somewhere telling the JSch to press YES automatically when this YES-NO question is asked?我可以通过在某处设置一个选项来绕过这个小问题,告诉 JSch 在询问这个 YES-NO 问题时自动按 YES 吗?

To connect to a second server behind a firewall, there are in principle two options.要连接到防火墙后面的第二台服务器,原则上有两种选择。

The naive one would be to call ssh on the first server (from an exec channel), indicating the right server.天真的方法是在第一台服务器上调用ssh (来自 exec 通道),指示正确的服务器。 This would need agent forwarding with JSch, and also doesn't provide the JSch API to access the second server, only the ssh command line.这需要使用 JSch 进行代理转发,并且不提供 JSch API 来访问第二个服务器,仅提供 ssh 命令行。

The better one would be to use the connection to the first server to build up a TCP Tunnel, and use this tunnel to connect to the second server.更好的方法是使用与第一台服务器的连接建立一个 TCP 隧道,并使用此隧道连接到第二台服务器。 The JSch Wiki contains a ProxySSH class (together with some example code) which allows to use a JSch session as a tunnel for a second JSch session. JSch Wiki 包含一个ProxySSH class (连同一些示例代码),它允许使用 JSch session 作为第二个 JSch Z21D6F40CFB511982E4424E0E250A95 的隧道。 (Disclaimer: This class was written mainly by me, with some support from the JSch author.) (免责声明:此 class 主要由我编写,并得到了 JSch 作者的一些支持。)

When you have your connection to the second server, use either a shell channel or a series of exec channels to execute your commands.当您连接到第二台服务器时,使用shell通道或一系列exec通道来执行您的命令。 (See Shell, Exec or Subsystem Channel in the JSch Wiki for an overview, and the Javadocs for details.) (有关概述,请参阅 JSch Wiki 中的Shell、Exec 或子系统通道,有关详细信息,请参阅Javadocs 。)


For your unknown-host-key problem:对于您的未知主机密钥问题:

The secure version would be to collect all host keys (in a secure way) before and put them in the known_hosts file.安全版本是在之前收集所有主机密钥(以安全方式)并将它们放入 known_hosts 文件中。 (If you simply trust the key which is presented to you, you are vulnerable to a man-in-the-middle attack. If these are of no concern in your network, since it is physically secured, good for you.) (如果您只是信任提供给您的密钥,那么您很容易受到中间人攻击。如果这些在您的网络中无关紧要,因为它是物理安全的,对您有好处。)

The convenient version is setting the configuration option StrictHostKeyChecking to no - this will add unknown host keys to the host keys file:方便的版本是将配置选项StrictHostKeyChecking设置为no - 这会将未知的主机密钥添加到主机密钥文件中:

JSch.setConfig("StrictHostKeyChecking", "no");

(You can also set it individually on the sessions, if you only want to set it for the proxied sessions and not for the tunnel session. Or override it for the tunnel session with yes or ask - there the MITM danger might be greater.) (您也可以在会话中单独设置它,如果您只想为代理会话而不是隧道 session 设置它。或者用yesask为隧道 session 覆盖它 - 中间人危险可能更大。)

A middle way would be to enable actually asking the user (which then should compare the fingerprints to some list) - for this, implement the UserInfo interface and provide the object to the session.一种中间方法是启用实际询问用户(然后应该将指纹与某个列表进行比较) - 为此,实现UserInfo接口并将 object 提供给 session。 (The JSch Wiki contains an example implementation using Swing JOptionPanes , which you can simply use if your client program runs on a system with GUI.) (JSch Wiki 包含一个使用 Swing JOptionPanes 的示例实现,如果您的客户端程序在具有 GUI 的系统上运行,您可以简单地使用它。)

For the saving of accepted host keys to work, you must use the JSch.setKnownHosts method with a file name argument, not the one with an InputStream argument - else your accepting will have to be repeated for each restart of your client.为了保存已接受的主机密钥,您必须使用带有文件名参数的JSch.setKnownHosts方法,而不是带有 InputStream 参数的方法 - 否则每次重新启动客户端时都必须重复接受。

Use an SSH tunnel , aka local port forwarding , to open an SSH/SFTP connection to B via A.使用SSH 隧道,即本地端口转发,通过 A 打开到 B 的 SSH/SFTP 连接。

Session sessionA = jsch.getSession("usernameA", "hostA");
// ...
sessionA.connect();

int forwardedPort = 2222; // any port number which is not in use on the local machine
sessionA.setPortForwardingL(forwardedPort, "hostB", 22);

Session sessionB = jsch.getSession("usernameB", "localhost", forwardedPort);
// ...
sessionB.connect();

// Use sessionB here for shell/exec/sftp

You may need to deal with UnknownHostKey exception .您可能需要处理UnknownHostKey异常

This can help anyone.这可以帮助任何人。 Works fine:工作正常:

 public static void sesionA(){
     try {
        Session sessionA = jSch.getSession(username, hostA);  
        Properties config = new Properties(); 
        config.put("StrictHostKeyChecking", "no");
        sessionA.setConfig(config);
        sessionA.setPassword(passwordA);
        sessionA.connect();


        if(sessionA.isConnected()) {
            System.out.println("Connected host A!");
            forwardedPort = 2222;
            sessionA.setPortForwardingL(forwardedPort, hostB, 22);      
        }

    } catch (JSchException e) {
        e.printStackTrace();
    }
 }

 public static void sesionB(){


        try {
            Session sessionB = jSch.getSession(username, "localhost", forwardedPort);

            Properties config = new Properties(); 
            config.put("StrictHostKeyChecking", "no");
            sessionB.setConfig(config);
            sessionB.setPassword(passwordB);
            sessionB.connect();

          if(sessionB.isConnected()) {
             System.out.println("Connected host B!");
          }
     }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android和JSch:另一台SSH服务器后面的SSH - Android and JSch: SSH behind another SSH server JSch对SSH服务器上的用户进行身份验证 - JSch authenticate user on SSH server 在远程服务器上执行 ssh 以跳转到另一台服务器并使用 Java 和 JSch 在那里执行进一步的命令 - Executing ssh on remote server to jump to another server and execute further commands there using Java and JSch 使用 Java - JSch 通过 SSH 连接到服务器并发出 shell 命令 - Connecting to server via SSH using Java - JSch and issuing shell commands 使用 JSch 从 SSH 服务器读取命令输出时获取不需要的字符 - Getting unwanted characters when reading command output from SSH server using JSch 为使用 JSch 在 SSH 服务器上执行的命令提供多行输入 - Provide multiple lines of input to command executed on SSH server with JSch 使用 JSch 从 Java 连接到 SSH 服务器时出现“JSchException:reject HostKey” - "JSchException: reject HostKey" when connecting to SSH server from Java using JSch Java JSch SSH隧道将HTTP或HTTPs请求发送到远程服务器 - Java JSch SSH tunneling send HTTP or HTTPs requests to remote server 在Java中将命令(Jsch)发送到SSH服务器时,如何转义双引号而不导致“ quot”? - How do I escape double quotes and NOT get “quot” when sending a command (Jsch) to an SSH server in Java? 在JSch(ssh)中使用root命令 - Using root Commands with JSch (ssh)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM