Jsch and sudo command

安稳与你 提交于 2019-12-30 13:52:06

问题


I am trying to automate some operations and one of such an operation is switching to a technical user on a remote Linux machine. The procedure looks like this: log in with a "normal" user and then switch with

sudo /bin/rootsh -i -u techUser

to the technical user.

Here's my Groovy code example that I am working on:

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())
        }
    }
}

The result is:

RESULT:  code: 1, text: ""

When I set to

((ChannelExec) channel).setPty(false)

the result is:

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

When I remove the password from the following line:

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

The result is:

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

And when I set the following command:

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

There is no response at all as the process is running all the time (the process is waiting for password maybe)

If someone has already solved such an issue or a similar one, I would really appriciate any help.


回答1:


You cannot pass a password to sudo with input redirection, at least not with the default configuration.

Hence, this cannot work:

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

Did you even try it in the interactive terminal? I assume it would not work there either.


You have to write the password to the channel input stream (called "output stream" in JSch).

See the official JSch Sudo example.

You may need to enable TTY/PTY. See Use JSch sudo example and Channel.setPty for running sudo command on remote host.



来源:https://stackoverflow.com/questions/43467747/jsch-and-sudo-command

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!