Java 如何将jsch与ProxyCommand一起用于端口转发
我想用ssh连接到代理后面的机器,然后在java程序中进行端口转发。(为了能够ssh到box,我应该先ssh到代理机器)。我通常通过在~/.ssh/config文件中包含以下条目来实现这一点:Java 如何将jsch与ProxyCommand一起用于端口转发,java,ssh,jsch,portforwarding,Java,Ssh,Jsch,Portforwarding,我想用ssh连接到代理后面的机器,然后在java程序中进行端口转发。(为了能够ssh到box,我应该先ssh到代理机器)。我通常通过在~/.ssh/config文件中包含以下条目来实现这一点: ProxyCommand ssh proxyhost.com -t nc %h %p IdentityFile /home/username/username_dsa_key 然后我运行以下操作来执行端口转发,以将hostmachine.com:54321映射到本地主机:12345: ssh -A -L
ProxyCommand ssh proxyhost.com -t nc %h %p
IdentityFile /home/username/username_dsa_key
然后我运行以下操作来执行端口转发,以将hostmachine.com:54321映射到本地主机: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();
有什么想法吗
p、 s:我已经在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配置:这可以帮助您。您已经注意到密钥验证设置为“否”,因此,如果您的网络不安全,这将是一个安全问题(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攻击,如果你确定你在网络中,请使用此代码。如果你不验证密钥,一个专业脚本的孩子可以偷走你的密码 谢谢!我认为它最终会工作,但我最终只是从java执行shell ssh命令。不幸的是,对于这个案例,jsch有点太复杂了,我找不到一个不需要完全传递dsa_密钥和不要求密码短语的好例子。上面的代码不完整。forwardedPort未被调用到sessionB()。