您的位置:首页 > 运维架构 > Shell

ssh远程执行shell实例

2016-02-02 20:28 621 查看

基本原理

SSH(Secure Shell)是一个提供数据通信安全、远程登录、远程指令执行等功能的安全网络协议。SSH发展了两个大版本SSH-1和SSH-2,目前主流的是SSH-2协议。SSH的主要特性,避免数据内容泄漏,数据被篡改,以及发送或接受地址伪装。SSH登录中主要分为认证阶段和传输阶段。由于非对称加密解密(公钥私钥)时间较慢,所以只在登录认证阶段使用。认证成功后通信双方使用在认证阶段两者约定的对称加密算法对传输内容进行加密解密。下面介绍客户端认证的两种主要登录方式,Password和Public Key。

Password

Password方式既客户端提供用户和密码,服务端对用户和密码进行匹配,完成认证。类Unix系统中,如OpenSSH的框架,一般通过系统的本地接口完成认证。Password的优势是简单,无需任何而外的配置就可以使用。缺点密码不便于记忆。

Public Key

Public Key认证的基本原理是基于非对称加密,分别在服务端对一段数据通过公钥进行加密,如果客户端能够证明其可以使用私钥对这段数据进行解密,则可以说明客户端的身份。因为服务端需要使用客户端生成的密钥对的公钥对数据首先加密,所以需要先将公钥存储到服务端的密钥库(Auhtorized Key)。关于非对称加密,本质来说就是利用数学上因式分解难度的非对称性。

实践例子

Java客户端

JSch 是SSH2的一个纯Java实现。它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等。maven如下。

<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.50</version>
</dependency>


远程执行shell

import static java.lang.String.format;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

/**
* 远程登录ssh,并执行shell
*/
public final class SshExecuter implements Closeable {
private static final Logger logger = LoggerFactory.getLogger(SshExecuter.class);
private SshInfo sshInfo = null;
private JSch jsch = null;
private Session session = null;

private SshExecuter(SshInfo info) throws Exception {
sshInfo = info;
jsch = new JSch();
jsch.addIdentity(sshInfo.getKey());
session = jsch.getSession(sshInfo.getUser(), sshInfo.getHost(), sshInfo.getPort());
UserInfo ui = new SshUserInfo(sshInfo.getPassPhrase());
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setUserInfo(ui);
session.connect();
}

/**
* 执行shell
*/
public int exec(String cmd) throws Exception {
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
channelExec.setCommand(cmd);
channelExec.setInputStream(null);
channelExec.setErrStream(System.err);
InputStream in = channelExec.getInputStream();
channelExec.connect();
int res = -1;
StringBuffer buf = new StringBuffer(1024);
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
buf.append(new String(tmp, 0, i));
}
if (channelExec.isClosed()) {
res = channelExec.getExitStatus();
logger.info(format("Exit-status: %d", res));
break;
}
}
logger.info(buf.toString());
channelExec.disconnect();
return res;
}

/**
* 构造执行实例
*/
public static SshExecuter newInstance(String host) throws Exception {
//        String host = "10.10.160.155";
logger.debug("key:{},passPhrase:{}", key, passPhrase);
Integer port = 22;
String user = "search";
SshInfo se = null;
se = new SshInfo(host, port, user, key, passPhrase);
return new SshExecuter(se);
}

public Session getSession() {
return session;
}

/**
* 关闭
*
* @throws IOException IOException
*/
public void close() throws IOException {
getSession().disconnect();
}
}

/**
* SshInfo
*/
class SshInfo {
private String host = null;
private Integer port = 22;
private String user = null;
private String key = null;
private String passPhrase = null;
SshInfo(String host, Integer port, String user, String key, String passPhrase) {
super();
this.host = host;
this.port = port;
this.user = user;
this.key = key;
this.passPhrase = passPhrase;
}
public String getHost() {
return host;
}
public Integer getPort() {
return port;
}
public String getUser() {
return user;
}
public String getKey() {
return key;
}
public String getPassPhrase() {
return passPhrase;
}
}

class SshUserInfo implements UserInfo {
private String passphrase = null;
SshUserInfo(String passphrase) {
super();
this.passphrase = passphrase;
}
public String getPassphrase() {
return passphrase;
}
public String getPassword() {
return null;
}
public boolean promptPassphrase(String pass) {
return true;
}
public boolean promptPassword(String pass) {
return true;
}
public boolean promptYesNo(String arg0) {
return true;
}
public void showMessage(String m) {
System.out.println(m);
}
}


更多内容

Jsch更多例子

密码学笔记

SSH原理与运用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: