Jsch и команда sudo

Я пытаюсь автоматизировать некоторые операции, и одна из таких операций — переключение на технического пользователя на удаленной машине с Linux. Процедура выглядит так: войдите в систему как «обычный» пользователь, а затем переключитесь с

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")

Ответа нет вообще, так как процесс работает все время (возможно, процесс ждет пароль)

Если кто-то уже решил такую ​​проблему или аналогичную, я бы очень признателен за любую помощь.


person Brandon X.    schedule 18.04.2017    source источник


Ответы (1)


Вы не можете передать пароль sudo с перенаправлением ввода, по крайней мере, не с конфигурацией по умолчанию.

Следовательно, это не может работать:

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

Вы даже пробовали это в интерактивном терминале? Думаю, там тоже не получится.


Вы должны записать пароль во входной поток канала (называемый «выходным потоком» в JSch).

См. официальный пример JSch Sudo.

Возможно, вам потребуется включить TTY/PTY. См. раздел Использование примера JSch sudo и Channel.setPty для запуска команды sudo на удаленном хосте.

person Martin Prikryl    schedule 18.04.2017
comment
Большое спасибо за исчерпывающее объяснение. Проект был закрыт, чтобы я не продолжил расследование по этому вопросу. Я полагаю, что советы, которые вы дали, помогут мне в этом, поэтому я отметил ваш ответ как решение этой проблемы. Надеюсь, ваши советы помогут другим пользователям. - person Brandon X.; 28.08.2018