2017-04-18 141 views
0

我正在嘗試自動化一些操作,其中一項操作是切換到遠程Linux機器上的技術用戶。該過程如下所示:使用「普通」用戶登錄,然後使用Jsch和sudo命令

sudo /bin/rootsh -i -u techUser

切換到技術用戶。

這裏是我的,我的工作Groovy的代碼示例:

import com.jcraft.jsch.JSch 
import com.jcraft.jsch.Session 
import com.jcraft.jsch.Channel 
import com.jcraft.jsch.ChannelExec 
import com.jcraft.jsch.JSchException 

class Main { 
    static void main(String[] args) { 
     int responseCode = 0 
     String responseText = "" 
     def targetHost = "targetHost" 
     def targetUser = "targetUser" 
     def technicalUser= "technicalUser" 
     def targetPass = "targetPass" 
     def targetPort = 22 
     Properties configConnection = new Properties() 
     configConnection.put("StrictHostKeyChecking", "no") 
     configConnection.put("PreferredAuthentications", "publickey,keyboard-interactive,password") 
     JSch jsch = new JSch() 
     try { 
      Session targetSession = jsch.getSession(targetUser, targetHost, targetPort) 
      targetSession.setPassword(targetPass) 
      targetSession.setConfig(configConnection) 
      targetSession.connect() 
      Channel channel = targetSession.openChannel("exec") 
      ((ChannelExec) channel).setCommand("echo 'targetPass' | sudo -S -p /bin/rootsh -i -u technicalUser") 
      ((ChannelExec) channel).setPty(true) 
      final ByteArrayOutputStream baos = new ByteArrayOutputStream() 
      ((ChannelExec) channel).setErrStream(baos) 
      channel.setInputStream(null) 
      InputStream is = channel.getInputStream() 
      channel.connect() 
      byte[] tmp = new byte[1024] 
      while (true) { 
       while (is.available() > 0) { 
        int i = is.read(tmp, 0, 1024) 
        if (i < 0) 
         break 
        responseText = new String(tmp, 0, i) 
       } 
       if (channel.isClosed()) { 
        responseText = new String(baos.toByteArray()) 
        responseCode = channel.getExitStatus() 
        break 
       } 
       try { 
        Thread.sleep(1000); 
       } catch (Exception ee) { 
        println("[ERROR] " + ee.getMessage()) 
       } 
      } 
      channel.disconnect() 
      targetSession.disconnect() 
      println("RESULT: code: " + responseCode + ", text: \"" + responseText + "\"") 
     } catch (JSchException e) { 
      println("[ERROR] Exception, problem with connection: " + e.getMessage()) 
     } 
    } 
} 

結果是:

RESULT: code: 1, text: "" 

當我設置爲

((ChannelExec) channel).setPty(false) 

結果是:

RESULT: code: 1, text: "/bin/rootshSorry, user targetUser is not allowed to execute '/bin/bash' as technicalUser on targetHost." 

當我從以下行刪除密碼:

((ChannelExec) channel).setCommand("echo '' | sudo -S -p /bin/rootsh -i -u technichalUser") 

結果是:

RESULT: code: 1, text: "/bin/rootsh/bin/rootsh 
Sorry, try again. 
/bin/rootsh 
/bin/rootsh 
sudo: pam_authenticate: Authentication information cannot be recovered" 

當我設置以下命令:

((ChannelExec) channel).setCommand("sudo -S -p /bin/rootsh -i -u technichalUser") 

沒有響應畢竟隨着進程一直在運行(進程正在等待密碼)

如果有人已經解決了這個問題或類似的問題,我會真正appriciate任何幫助。

回答

0

您無法通過輸入重定向將密碼傳遞給sudo,至少不會使用默認配置。

因此,這不能工作:

echo 'targetPass' | sudo -S -p /bin/rootsh -i -u technicalUser` 

你甚至嘗試它在交互式終端?我認爲它也不會在那裏工作。


您必須將密碼寫入通道輸入流(在JSch中稱爲「輸出流」)。

查看官方JSch Sudo example

您可能需要啓用TTY/PTY。請參閱Use JSch sudo example and Channel.setPty for running sudo command on remote host