Executing Command Using "Su -L" in Ssh Using Python

Providing input to command (su) executed using Python Paramiko Transport class due to special authentication needs

The low-level Channel.exec_command does not return anything (unlike the high-level SSHClient.exec_command).

If you want to obtain the I/O, you have to call Channel's makefile* methods.

This is simplified code of what SSHClient.exec_command does internally:

chan = transport.open_session()
chan.exec_command(command)
stdin = chan.makefile_stdin("wb", bufsize)
stdout = chan.makefile("r", bufsize)
stderr = chan.makefile_stderr("r", bufsize)

Running a python script on a remote server with sudo privileges

The problems in the above script were:

  1. i = child.expect(['[sudo] password for zod1:'])

    Here, [sudo] was not escaped like \[sudo\] hence, pexpect was not able to
    find match since it expects a pattern.

  2. child = pexpect.spawn('sudo su') spawned a new independent process
    instead of continuing with the already spawned process. Using
    child.sendline('sudo su') resolved the issue.

How to execute 'su' command using parallel-ssh

It turns out that what I am trying to do is not achievable.

The first problem

I found in this post that all commands are in their own channel. That means that even if su would be successful it wouldn't affect the second command. The author of the post recommends running

su -c whoami - root

The second problem

I managed to debug the problem even further by changing host_output.stdout to host_output.stderr It turned out that I receive an error which previously was not being shown on the terminal:

standard in must be a tty

Possible solutions to this problem are here . They didn't work for me but might work for you.

For me workaround was to allow on all my hosts root login. And then in parallel-ssh I log in as a root already with all the rights in place.

using subprocess to ssh and execute commands

I figured the solution by using univerio's comment

The command needs to be

command = 'ssh -t -t buildMachine.X.lan \'sudo su - buildbot  \'build-set sets/set123\'\''

Individual commands are like argument to previous command. This works.

Execute a Command on a Remote Server That Requires Sudo with password input - Paramiko

A few years ago I have had similar issues, and it turns out that there might be a few reasons for that.

One possible option is that the call waits to get a shell prompt in order to return. However, in the case of a command that requires sudo, the behavior might change: In some cases, it will require you to enter the password first. In other cases (e.g., if you have just used sudo and it was not timed out yet), it will not require the password again. This inconsistency might cause problems.

Take a look here - using -k might solve your problem.

In order to solve that, you have to define (if possible) that sudo will always require a password, thus make it consistent.

Another issue that might raise is the definition of the shell prompt (some shells use >, others use $); the same might be true for the sudo - it might print Password:, which contains no shell prompt and might not be recognized by the remote-command agent, and it might print something else, e.g. password.

Executing su user (without password) on paramiko ssh connection

Each exec_command() call happens in a new shell, so there is no state carried over from previous commands. If commands rely on a previous command to execute, you have to send them in a single statement, or as a script. If you want an interactive shell, there is the invoke_shell command, but then you need to parse the shell output to simulate interactive use (the pexpect library can be used here).

You can use the sudo command, or su -c to execute the command.. However, I would suggest configuring a secure login for the needed user, and connecting as that user directly.



Related Topics



Leave a reply



Submit