如何使用jsch与ProxyCommands进行端口转发

我想ssh到一个代理后面的机器,然后在我的java程序中执行一个portforwarding。 (为了能够ssh到盒子我应该首先ssh’ed到代理机器)。 我通常在〜/ .ssh / config文件中包含以下条目:

ProxyCommand ssh proxyhost.com -t nc %h %p IdentityFile /home/username/username_dsa_key 

然后我运行以下命令来执行portforwarding以将hostmachine.com:54321映射到我的localhost:12345:

 ssh -A -L12345:localhost:54321 hostmachine.com 

现在我想用Jsch库做这些,但是在打开会话中的通道后我无法弄清楚如何连接到第二个主机:

  String proxyHost = "proxyhost.com"; String host = "hostmachine.com"; int lport = 12345; String rhost = "localhost"; int rport = 54321; JSch jsch=new JSch(); jsch.setKnownHosts("/home/{user}/.ssh/known_hosts"); jsch.addIdentity("/home/{user}/.ssh/{user}_dsa_key",passphrase); Session session1 = jsch.getSession(user,proxyHost,22); session1.connect(3000); System.out.println(session1.isConnected()); Channel channel = session1.openChannel("shell"); ////// Now what? :) channel.disconnect(); session1.disconnect(); 

任何想法?

ps:我已经在www.jcraft.com/jsch/examples/上阅读了样本,但不幸的是,他们在这种情况下没有帮助。

谢谢!

我建议你试试

 http://www.jcraft.com/jsch/examples/JumpHosts.java.html 

,但是如果使用本机“ssh”命令很重要,你会在jsch-0.1.50的Session.java的注释中找到类ProxyCommand,

 /* // setProxyCommand("ssh -l user2 host2 -o 'ProxyCommand ssh user1@host1 nc host2 22' nc %h %p") public void setProxyCommand(String command){ setProxy(new ProxyCommand(command)); } class ProxyCommand implements Proxy { String command; Process p = null; InputStream in = null; OutputStream out = null; ProxyCommand(String command){ this.command = command; } public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception { String _command = command.replace("%h", host); _command = _command.replace("%p", new Integer(port).toString()); p = Runtime.getRuntime().exec(_command); in = p.getInputStream(); out = p.getOutputStream(); } public Socket getSocket() { return null; } public InputStream getInputStream() { return in; } public OutputStream getOutputStream() { return out; } public void close() { try{ if(p!=null){ p.getErrorStream().close(); p.getOutputStream().close(); p.getInputStream().close(); p.destroy(); p=null; } } catch(IOException e){ } } } */ 

我在JSch上面编写了一个能够“模拟” ProxyCommand配置的抽象: https : //github.com/cronn-de/ssh-proxy

这可以帮到你。 您已经注意到密钥validation设置为“否”,因此如果您的网络不安全,则会出现安全问题(MITM攻击)。

  public static void sesionA(){ try { 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 { 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!"); Channel channel = sessionB.openChannel("exec"); 

您还可以使用JSCH官方示例并执行以下操作以避免有关键和其他内容的提示消息:

  UserInfo ui = new MyUserInfo(){ public void showMessage(String message){ JOptionPane.showMessageDialog(null, message); } @SuppressWarnings("unused") public boolean promptYesNo(String message){ Object[] options={ "yes", "no" }; int foo = 0; return foo==0; // promptYesNo library method. Return 0 to avoid message } }; 

您必须考虑MITM攻击,如果您确定自己是网络,请使用此代码。 如果您不validation密钥,专家脚本小子可以偷走您的证书。