java 里面的开源 ssh lib
1、
2、
JSCH 里面的概念
1、Linux OpenSSH 验证方式对应的 jsch auth method
在/etc/sshd_config
文件中
# Authentication:PubkeyAuthentication //对应的是 publickey 公钥认证PasswordAuthentication yes //对应的是 password 密码验证ChallengeResponseAuthentication yes //对应的是 keyboard-interactive 键盘交互# Kerberos options KerberosAuthentication yes //对应的是kerberos 验证#KerberosOrLocalPasswd yes#KerberosTicketCleanup yes#KerberosGetAFSToken no# GSSAPI optionsGSSAPIAuthentication yes //对应的 gssapi-with-mic 验证#GSSAPICleanupCredentials yes#GSSAPIStrictAcceptorCheck yes#GSSAPIKeyExchange no
OpenSHH 文档中写到
The methods available for authentication are:
GSSAPI-based authentication
,host-based authentication
,public key authentication
,challenge-response authentication
, andpassword authentication
. Authentication methods are tried in the order specified above, thoughPreferredAuthentications
can be used to change the default order.
我们在使用jsch 的时候就要注意几点
//StrictHostKeyChecking 选项可用于控制对主机密钥未知或已更改的计算机的登录。session.setConfig("StrictHostKeyChecking", "no");//设置首选的Auth Methodsession.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password");
我们如果使用sshj
就可以这样
//调用 sshClient 的这个方法,里面可以实现多个验证方式public void auth(String username, AuthMethod... methods) throws UserAuthException, TransportException { checkConnected(); auth(username, Arrays.asList(methods)); }//例子 DefaultConfig defaultConfig = new DefaultConfig(); final SSHClient client = new SSHClient(defaultConfig); String host = "127.0.0.1"; String user = "king"; String password = "123456"; client.setTimeout(60000); client.loadKnownHosts(); client.addHostKeyVerifier(new PromiscuousVerifier()); client.connect(host); PasswordFinder pwdf = PasswordUtils.createOneOff(password.toCharArray()); PasswordResponseProvider provider = new PasswordResponseProvider(pwdf); //键盘交互 AuthKeyboardInteractive authKeyboardInteractive = new AuthKeyboardInteractive(provider); //密码验证 AuthPassword authPassword = new AuthPassword(pwdf); client.auth(user, authKeyboardInteractive, authPassword);
jsch 例子
JSch jSch = new JSch(); //设置JSch 的日志,可以看到具体日志信息 JSch.setLogger(new Logger() { @Override public boolean isEnabled(int level) { return true; } @Override public void log(int level, String message) { System.out.println("logger:" + message); } }); com.jcraft.jsch.Session session = jSch.getSession("king", "127.0.0.1"); session.setPassword("123456"); //忽略第一次连接时候 hostkey 检查 session.setConfig("StrictHostKeyChecking", "no"); //设置首选的身份验证方式 session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password"); session.connect(60000); //开启shell,shell 具有上下文交互,执行命令不会马上退出 ChannelShell shell = (ChannelShell) session.openChannel("shell"); //开始 exec 类似linux bash -c exec 执行完命令马上退出 //ChannelExec exec = (ChannelExec)session.openChannel("exec"); //exec.setCommand(""); shell.setPtyType("dumb"); shell.setPty(true); shell.connect(60000); boolean connected = shell.isConnected(); OutputStream outputStream = shell.getOutputStream(); InputStream inputStream = shell.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); //通过流写入命令 outputStream.write("pwd\n cd /home\nls\npwd\n".getBytes()); outputStream.flush(); String line; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); }
sshj 例子
DefaultConfig defaultConfig = new DefaultConfig(); final SSHClient client = new SSHClient(defaultConfig); String host = "127.0.0.1"; String user = "king"; String password = "123456"; client.setTimeout(60000); client.loadKnownHosts(); client.addHostKeyVerifier(new PromiscuousVerifier()); client.connect(host); try { client.authPassword(user, password); final SessionChannel session = (SessionChannel) client.startSession(); session.allocateDefaultPTY(); //这里的session 类似 jsch 里面的exec ,可以直接执行命令。 //session.exec("pwd"); SessionChannel shell = (SessionChannel) session.startShell(); try { OutputStream outputStream = shell.getOutputStream(); outputStream.write("pwd\n".getBytes()); outputStream.flush(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(shell.getInputStream(), "utf-8")); String line; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } } catch (InterruptedException e) { e.printStackTrace(); } } finally { client.disconnect(); }