java shell ssh

用JAVA调用SSH命令(转)
2009-10-10 22:28
SSH命令使用手册

SSH 的详细使用方法如下:

ssh [-l login_name] [hostname | user@hostname] [command] ssh [-afgknqtvxCPX246] [-c blowfish | 3des] [-e escape_char] [-i identity_file] [-l login_name] [-o option] [-p port] [-L port:host:hostport] [-R port:host:hostport] [hostname | user@hostname] [command]

sshd

为执行 ssh 的 daemon,在读者使用 ssh 之前必须去激活 sshd,在此建议把它加在 /etc/init/rc.local 中,在每次开机时激活。

在执行 sshd 之前可以指定它的 port,例如:sshd –p 999

若有安装 SSL,可以指定 SSL 的 port 443,例如:sshd –p 443

这样就可以经过 SSL 及 SSH 双重的保护,但必须去指明使用的 port

ssh –l user –p 443 mouse.oit.edu.tw 才行,若不指明则仍然使用预设的port 22

ssh

选项:

-l login_name

指定登入于远程机器上的使用者,若没加这个选项,而直接打 ssh lost 也是可以的,它是以读者目前的使用者去做登入的动作。例如: ssh –l shie mouse.oit.edu.tw

-c blowfish|3des

在期间内选择所加密的密码型式。预设是3des,3des(作三次的资料加密) 是用三种不同的密码键作三次的加密-解密-加密。 blowfish 是一个快速区块密码编制器,它比3des更安全以及更快速。

-v

Verbose 模式。使ssh 去印出关于行程的除错讯息,这在连接除错,认 证和设定的问题上有很的帮助。

-V

显示版本。

-a

关闭认证代理联机。

-f

要求ssh 在背景执行命令,假如ssh要询问密码或通行证,但是使用者 想要它在幕后执行就可以用这个方式,最好还是加上-l user 例如在远程场所上激活 X11,有点像是 ssh –f host xterm 。

-e character

设定跳脱字符。

-g

允许远程主机去连接本地指派的 ports。

-i identity_file

选择所读取的 RSA 认证识别的档案。预设是在使用者的家目录 中的 .ssh/identity 。

-n

重导 stdin 到 /dev/null (实际上是避免读取 stdin)。必须当 ssh 在幕后执行时才使用。常见的招数是使用这选项在远程机器上去执行 X11 的程序 例如,ssh -n shadows.cs.hut.fi emacs &,将在 shadows.cs.hut.fi 上激活 emace,并且 X11 连接将自动地在加密的信道上发送。ssh 程序将把它放 在幕后。(假如ssh需要去询问密码时,这将不会动作)

-p port

连接远程机器上的 port。

-P

使用非特定的 port 去对外联机。如果读者的防火墙不淮许从特定的 port去联机时,就可以使用这个选项。注意这个选项会关掉 RhostsAuthentication 和 RhostsRSAAuthentication。

-q

安静模式。把所有的警告和讯息抑制,只有严重的错误才会被显示。

-t

强制配置 pseudo-tty。这可以在远程机器上去执行任意的 screen-based 程 式,例如操作 menu services。

-C

要求压缩所有资料(包含 stdin, stdout,stderr 和 X11 和 TCP/IP 连接) 压缩演算规则与 gzip 相同,但是压缩的等级不能控制。在调制解调器或 联机速度很慢的地方,压缩是个很好的选择,但如果读者的网络速路很 快的话,速度反而会慢下来。

-L listen-port:host:port

指派本地的 port 到达端机器地址上的 port。

-R listen-port:host:port

指派远程上的 port 到本地地址上的 port。

-2 强制 ssh 去使用协议版本 2。

-4 强制 ssh 去使用 IPv4 地址。

-6 强制 ssh 去使用 IPv6 地址。

scp

使用 scp 在远程机器上 copy 档案

例如:

copy 本地的档案到远程的机器上

scp /etc/lilo.conf k@net67.ee.oit.edu.tw:/home/k

会将本地的 /etc/lilo.conf 这个档案 copy 到 net67.ee.oit.edu.tw,使用者 k 的家目录下。

copy远程机器上的档案到本地来

scp k@net67.ee.oit.edu.tw:/etc/lilo.conf /etc

会将 net67.ee.oitdu.tw 中 /etc/lilo.conf 档案 copy 到本地的 /etc 目录下。

保持从来源 host 档案的属性

scp –p k@net67.ee.tw:/etc/lilo.conf /etc

在此必须注意使用者的权限是否可读取远程上的档案,若想知道更多关于 scp 的使用方法,可去看看 scp 的使用手册。

ssh-keygen

产生公开钥 (pulib key) 和私人钥 (private key),以保障 ssh 联机的安性, 当 ssh 连 shd 服务器,会交换公开钥上,系统会检查 /etc/ssh_know_hosts 内储存的 key,如果找到客户端就用这个 key 产生一个随机产生的session key 传给服务器,两端都用这个 key 来继续完成 ssh 剩下来的阶段。

它会产生 identity.pub、identity 两个档案,私人钥存放于identity,公开钥存放于 identity.pub 中,接下来使用 scp 将 identity.pub copy 到远程机器的家目录下.ssh下的authorized_keys。 .ssh/authorized_keys(这个 authorized_keys 档案相当于协议的 rhosts 档案),之后使用者能够不用密码去登入。RSA的认证绝对是比 rhosts 认证更来的安全可靠。

执行:

scp identity.pub k@linux1.ee.oit.edu.tw:.ssh/authorized_keys

若在使用 ssh-keygen 产生钥匙对时没有输入密码,则如上所示不需输入密码即可从 net67.ee.oit.edu.tw 去登入 linux1.ee.oit.edu.tw。在此,这里输入的密码可以跟帐号的密码不同,也可以不输入密码。

(2) JAVA与SSH的交互

由于在使用SSH命令时,中间要求输入用户密码,在设计JAVA程序时如果用Runtime的exec方法进行交互,经查证不可行。不过http://www.ganymed.ethz.ch/ssh2/提供了调用ssh和scp命令的jar,通过把用户名和密码传入api中就不需要用户介入输入密码。

从http://www.cjsdn.net/post/view?bid=6&id=173625&tpg=1&ppg=1&sty=1&age=0#173625得到一份示例代码如下:

package com.corp.prj.util;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import org.apache.log4j.Logger;

import ch.ethz.ssh2.Connection;

import ch.ethz.ssh2.SCPClient;

import ch.ethz.ssh2.Session;

import ch.ethz.ssh2.StreamGobbler;

/**

* Provides static methods for running SSH, scp as well as local commands.

*

*/

public class CommandRunner {

private static final Logger logger = Logger.getLogger(CommandRunner.class);

private CommandRunner() {

}

/**

* Get remote file through scp

* @param host

* @param username

* @param password

* @param remoteFile

* @param localDir

* @throws IOException

*/

public static void scpGet(String host, String username, String password,

String remoteFile, String localDir) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("spc [" + remoteFile + "] from " + host + " to " + localDir);

}

Connection conn = getOpenedConnection(host, username, password);

SCPClient client = new SCPClient(conn);

client.get(remoteFile, localDir);

conn.close();

}

/**

* Put local file to remote machine.

* @param host

* @param username

* @param password

* @param localFile

* @param remoteDir

* @throws IOException

*/

public static void scpPut(String host, String username, String password,

String localFile, String remoteDir) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("spc [" + localFile + "] to " + host + remoteDir);

}

Connection conn = getOpenedConnection(host, username, password);

SCPClient client = new SCPClient(conn);

client.put(localFile, remoteDir);

conn.close();

}

/**

* Run SSH command.

* @param host

* @param username

* @param password

* @param cmd

* @return exit status

* @throws IOException

*/

public static int runSSH(String host, String username, String password,

String cmd) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("running SSH cmd [" + cmd + "]");

}

Connection conn = getOpenedConnection(host, username, password);

Session sess = conn.openSession();

sess.execCommand(cmd);

InputStream stdout = new StreamGobbler(sess.getStdout());

BufferedReader br = new BufferedReader(new InputStreamReader(stdout));

while (true) {

// attention: do not comment this block, or you will hit NullPointerException

// when you are trying to read exit status

String line = br.readLine();

if (line == null)

break;

if (logger.isDebugEnabled()) {

logger.debug(line);

}

}

sess.close();

conn.close();

return sess.getExitStatus().intValue();

}

/**

* return a opened Connection

* @param host

* @param username

* @param password

* @return

* @throws IOException

*/

private static Connection getOpenedConnection(String host, String username,

String password) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("connecting to " + host + " with user " + username

+ " and pwd " + password);

}

Connection conn = new Connection(host);

conn.connect(); // make sure the connection is opened

boolean isAuthenticated = conn.authenticateWithPassword(username,

password);

if (isAuthenticated == false)

throw new IOException("Authentication failed.");

return conn;

}

/**

* Run local command

* @param cmd

* @return exit status

* @throws IOException

*/

public static int runLocal(String cmd) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("running local cmd [" + cmd + "]");

}

Runtime rt = Runtime.getRuntime();

Process p = rt.exec(cmd);

InputStream stdout = new StreamGobbler(p.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(stdout));

while (true) {

String line = br.readLine();

if (line == null)

break;

if (logger.isDebugEnabled()) {

logger.debug(line); SSH命令使用手册

SSH 的详细使用方法如下:

ssh [-l login_name] [hostname | user@hostname] [command] ssh [-afgknqtvxCPX246] [-c blowfish | 3des] [-e escape_char] [-i identity_file] [-l login_name] [-o option] [-p port] [-L port:host:hostport] [-R port:host:hostport] [hostname | user@hostname] [command]

sshd

为执行 ssh 的 daemon,在读者使用 ssh 之前必须去激活 sshd,在此建议把它加在 /etc/init/rc.local 中,在每次开机时激活。

在执行 sshd 之前可以指定它的 port,例如:sshd –p 999

若有安装 SSL,可以指定 SSL 的 port 443,例如:sshd –p 443

这样就可以经过 SSL 及 SSH 双重的保护,但必须去指明使用的 port

ssh –l user –p 443 mouse.oit.edu.tw 才行,若不指明则仍然使用预设的port 22

ssh

选项:

-l login_name

指定登入于远程机器上的使用者,若没加这个选项,而直接打 ssh lost 也是可以的,它是以读者目前的使用者去做登入的动作。例如: ssh –l shie mouse.oit.edu.tw

-c blowfish|3des

在期间内选择所加密的密码型式。预设是3des,3des(作三次的资料加密) 是用三种不同的密码键作三次的加密-解密-加密。 blowfish 是一个快速区块密码编制器,它比3des更安全以及更快速。

-v

Verbose 模式。使ssh 去印出关于行程的除错讯息,这在连接除错,认 证和设定的问题上有很的帮助。

-V

显示版本。

-a

关闭认证代理联机。

-f

要求ssh 在背景执行命令,假如ssh要询问密码或通行证,但是使用者 想要它在幕后执行就可以用这个方式,最好还是加上-l user 例如在远程场所上激活 X11,有点像是 ssh –f host xterm 。

-e character

设定跳脱字符。

-g

允许远程主机去连接本地指派的 ports。

-i identity_file

选择所读取的 RSA 认证识别的档案。预设是在使用者的家目录 中的 .ssh/identity 。

-n

重导 stdin 到 /dev/null (实际上是避免读取 stdin)。必须当 ssh 在幕后执行时才使用。常见的招数是使用这选项在远程机器上去执行 X11 的程序 例如,ssh -n shadows.cs.hut.fi emacs &,将在 shadows.cs.hut.fi 上激活 emace,并且 X11 连接将自动地在加密的信道上发送。ssh 程序将把它放 在幕后。(假如ssh需要去询问密码时,这将不会动作)

-p port

连接远程机器上的 port。

-P

使用非特定的 port 去对外联机。如果读者的防火墙不淮许从特定的 port去联机时,就可以使用这个选项。注意这个选项会关掉 RhostsAuthentication 和 RhostsRSAAuthentication。

-q

安静模式。把所有的警告和讯息抑制,只有严重的错误才会被显示。

-t

强制配置 pseudo-tty。这可以在远程机器上去执行任意的 screen-based 程 式,例如操作 menu services。

-C

要求压缩所有资料(包含 stdin, stdout,stderr 和 X11 和 TCP/IP 连接) 压缩演算规则与 gzip 相同,但是压缩的等级不能控制。在调制解调器或 联机速度很慢的地方,压缩是个很好的选择,但如果读者的网络速路很 快的话,速度反而会慢下来。

-L listen-port:host:port

指派本地的 port 到达端机器地址上的 port。

-R listen-port:host:port

指派远程上的 port 到本地地址上的 port。

-2 强制 ssh 去使用协议版本 2。

-4 强制 ssh 去使用 IPv4 地址。

-6 强制 ssh 去使用 IPv6 地址。

scp

使用 scp 在远程机器上 copy 档案

例如:

copy 本地的档案到远程的机器上

scp /etc/lilo.conf k@net67.ee.oit.edu.tw:/home/k

会将本地的 /etc/lilo.conf 这个档案 copy 到 net67.ee.oit.edu.tw,使用者 k 的家目录下。

copy远程机器上的档案到本地来

scp k@net67.ee.oit.edu.tw:/etc/lilo.conf /etc

会将 net67.ee.oitdu.tw 中 /etc/lilo.conf 档案 copy 到本地的 /etc 目录下。

保持从来源 host 档案的属性

scp –p k@net67.ee.tw:/etc/lilo.conf /etc

在此必须注意使用者的权限是否可读取远程上的档案,若想知道更多关于 scp 的使用方法,可去看看 scp 的使用手册。

ssh-keygen

产生公开钥 (pulib key) 和私人钥 (private key),以保障 ssh 联机的安性, 当 ssh 连 shd 服务器,会交换公开钥上,系统会检查 /etc/ssh_know_hosts 内储存的 key,如果找到客户端就用这个 key 产生一个随机产生的session key 传给服务器,两端都用这个 key 来继续完成 ssh 剩下来的阶段。

它会产生 identity.pub、identity 两个档案,私人钥存放于identity,公开钥存放于 identity.pub 中,接下来使用 scp 将 identity.pub copy 到远程机器的家目录下.ssh下的authorized_keys。 .ssh/authorized_keys(这个 authorized_keys 档案相当于协议的 rhosts 档案),之后使用者能够不用密码去登入。RSA的认证绝对是比 rhosts 认证更来的安全可靠。

执行:

scp identity.pub k@linux1.ee.oit.edu.tw:.ssh/authorized_keys

若在使用 ssh-keygen 产生钥匙对时没有输入密码,则如上所示不需输入密码即可从 net67.ee.oit.edu.tw 去登入 linux1.ee.oit.edu.tw。在此,这里输入的密码可以跟帐号的密码不同,也可以不输入密码。

(2) JAVA与SSH的交互

由于在使用SSH命令时,中间要求输入用户密码,在设计JAVA程序时如果用Runtime的exec方法进行交互,经查证不可行。不过http://www.ganymed.ethz.ch/ssh2/提供了调用ssh和scp命令的jar,通过把用户名和密码传入api中就不需要用户介入输入密码。

从http://www.cjsdn.net/post/view?bid=6&id=173625&tpg=1&ppg=1&sty=1&age=0#173625得到一份示例代码如下:

package com.corp.prj.util;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import org.apache.log4j.Logger;

import ch.ethz.ssh2.Connection;

import ch.ethz.ssh2.SCPClient;

import ch.ethz.ssh2.Session;

import ch.ethz.ssh2.StreamGobbler;

/**

* Provides static methods for running SSH, scp as well as local commands.

*

*/

public class CommandRunner {

private static final Logger logger = Logger.getLogger(CommandRunner.class);

private CommandRunner() {

}

/**

* Get remote file through scp

* @param host

* @param username

* @param password

* @param remoteFile

* @param localDir

* @throws IOException

*/

public static void scpGet(String host, String username, String password,

String remoteFile, String localDir) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("spc [" + remoteFile + "] from " + host + " to " + localDir);

}

Connection conn = getOpenedConnection(host, username, password);

SCPClient client = new SCPClient(conn);

client.get(remoteFile, localDir);

conn.close();

}

/**

* Put local file to remote machine.

* @param host

* @param username

* @param password

* @param localFile

* @param remoteDir

* @throws IOException

*/

public static void scpPut(String host, String username, String password,

String localFile, String remoteDir) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("spc [" + localFile + "] to " + host + remoteDir);

}

Connection conn = getOpenedConnection(host, username, password);

SCPClient client = new SCPClient(conn);

client.put(localFile, remoteDir);

conn.close();

}

/**

* Run SSH command.

* @param host

* @param username

* @param password

* @param cmd

* @return exit status

* @throws IOException

*/

public static int runSSH(String host, String username, String password,

String cmd) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("running SSH cmd [" + cmd + "]");

}

Connection conn = getOpenedConnection(host, username, password);

Session sess = conn.openSession();

sess.execCommand(cmd);

InputStream stdout = new StreamGobbler(sess.getStdout());

BufferedReader br = new BufferedReader(new InputStreamReader(stdout));

while (true) {

// attention: do not comment this block, or you will hit NullPointerException

// when you are trying to read exit status

String line = br.readLine();

if (line == null)

break;

if (logger.isDebugEnabled()) {

logger.debug(line);

}

}

sess.close();

conn.close();

return sess.getExitStatus().intValue();

}

/**

* return a opened Connection

* @param host

* @param username

* @param password

* @return

* @throws IOException

*/

private static Connection getOpenedConnection(String host, String username,

String password) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("connecting to " + host + " with user " + username

+ " and pwd " + password);

}

Connection conn = new Connection(host);

conn.connect(); // make sure the connection is opened

boolean isAuthenticated = conn.authenticateWithPassword(username,

password);

if (isAuthenticated == false)

throw new IOException("Authentication failed.");

return conn;

}

/**

* Run local command

* @param cmd

* @return exit status

* @throws IOException

*/

public static int runLocal(String cmd) throws IOException {

if (logger.isDebugEnabled()) {

logger.debug("running local cmd [" + cmd + "]");

}

Runtime rt = Runtime.getRuntime();

Process p = rt.exec(cmd);

InputStream stdout = new StreamGobbler(p.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(stdout));

while (true) {

String line = br.readLine();

if (line == null)

break;

if (logger.isDebugEnabled()) {

logger.debug(line);

}

}

return p.exitValue();

}

}


}

}

return p.exitValue();

}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值