Paramiko equivalent of ssh host -t bash - python

In my Python3 script, I am trying to use Paramiko to ssh into remote devices. I can do that just fine. The issue is that ssh dumps me into a proprietary shell. I need to add -t bash to the .connect command to dump me into a bash shell. Here is what I have that is working:
ssh_tranfer = paramiko.SSHClient()
ssh_transfer.set_missing_host_key_policy(paramiko.AutoAddPolicy)
ssh.connect(hostname=device, port=22, username=username, key_filename=private_key_name)
With this I can connect just fine, but like I said, I am in the proprietary shell and can't pass it commands. I am not even sure that I can do it this way.
I define all the parameters that I am using (ie - device, username, and the private key) prior to the ssh.connect shown above.
If I was to ssh into the device directly from my computer to go straight to the bash shell, I would use:
ssh username#device.com -t bash
I would like to find a way to do this using paramiko.
Thanks for the help!

The -t + bash in ssh do two things:
Starts command bash in "exec" channel (instead of starting "shell" channel, what ssh does by default).
For that, see Python Paramiko - Run command
The -t forces an interactive session, what would be the default for "shell", but is by default disabled for "exec".
For that, pass get_pty=True to SSHClient.exec_command.
Obligatory warning: Do not use AutoAddPolicy this way – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".

Related

Using paramiko to execute "virsh list --all" command, can't get remote server's real output [duplicate]

I am trying to use Paramiko to SSH into a Brocade switch and carry out remote commands. The code is as given below:
def ssh_connector(ip, userName, passWord, command):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=userName, password=passWord, port=22)
stdin, stdout, stderr = ssh.exec_command(command)
print stdout.readlines()
ssh_connector(ip, userName, passWord, 'show running-config')
While trying to run the code, I encounter a strange error which is as given below.
Protocol error, doesn't start with scp!
I do not know the cause of the error or whether the SSH connection was successful. Could you please help me with this?
If the SSHClient.exec_command does not work, the first thing to test is to try (on one line):
ssh user#host command
That will use the same SSH API (the "exec" channel) as SSHClient.exec_command. If you are on Windows, you can use plink (from PuTTY packages) instead of ssh. If ssh/plink fails too, it indicates that your device does not support the SSH "exec" channel.
In your case, it seems that the "exec" channel on Brocade SSH server is implemented to support the scp command only.
As you claim to be able to "SSH" to the switch, it seems that the "shell" channel is fully working.
While it is generally not recommended to use the "shell" channel for command automation, with your server you won't have other option. Use the SSHClient.invoke_shell and write the commands to the channel (= to the shell) using the Channel.send.
channel = ssh.invoke_shell()
channel.send('ls\n')
channel.send('exit\n')
See also What is the difference between exec_command and send with invoke_shell() on Paramiko?
A similar question on C#/SSH.NET: SSH.NET is not executing command on device.
Obligatory warning: Do not use AutoAddPolicy – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".

Using Paramiko (or similar) to send commands to python program via ssh [duplicate]

I am trying to use Paramiko to SSH into a Brocade switch and carry out remote commands. The code is as given below:
def ssh_connector(ip, userName, passWord, command):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=userName, password=passWord, port=22)
stdin, stdout, stderr = ssh.exec_command(command)
print stdout.readlines()
ssh_connector(ip, userName, passWord, 'show running-config')
While trying to run the code, I encounter a strange error which is as given below.
Protocol error, doesn't start with scp!
I do not know the cause of the error or whether the SSH connection was successful. Could you please help me with this?
If the SSHClient.exec_command does not work, the first thing to test is to try (on one line):
ssh user#host command
That will use the same SSH API (the "exec" channel) as SSHClient.exec_command. If you are on Windows, you can use plink (from PuTTY packages) instead of ssh. If ssh/plink fails too, it indicates that your device does not support the SSH "exec" channel.
In your case, it seems that the "exec" channel on Brocade SSH server is implemented to support the scp command only.
As you claim to be able to "SSH" to the switch, it seems that the "shell" channel is fully working.
While it is generally not recommended to use the "shell" channel for command automation, with your server you won't have other option. Use the SSHClient.invoke_shell and write the commands to the channel (= to the shell) using the Channel.send.
channel = ssh.invoke_shell()
channel.send('ls\n')
channel.send('exit\n')
See also What is the difference between exec_command and send with invoke_shell() on Paramiko?
A similar question on C#/SSH.NET: SSH.NET is not executing command on device.
Obligatory warning: Do not use AutoAddPolicy – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".

How to configure an equivalent of ssh StrictHostKeyChecking=no in Python Paramiko

I am using Paramiko for sshing from Python script. My ssh command is listed below:
ssh -A -o strictHostKeyChecking=no <hostname>
I need same Paramiko code for Python.
In Paramiko, an equivalent of OpenSSH StrictHostKeyChecking=no is the default behaviour of MissingHostKeyPolicy, which implements missing_host_key to simply do nothing.
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
client.connect(hostname, ...)
Though you should not do this (and neither StrictHostKeyChecking=no). You are losing a protection against Man-in-the-middle attacks this way. For correct solution, see Paramiko "Unknown Server".

Identical command sent over paramiko and ssh works over ssh but not paramiko [duplicate]

I am connecting to SSH via terminal (on Mac) and run a Paramiko Python script and for some reason, the two sessions seem to behave differently. The PATH environment variable is different in these cases.
This is the code I run:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='myuser',password='mypass')
stdin, stdout, stderr =ssh.exec_command('echo $PATH')
print (stdout.readlines())
Any idea why the environment variables are different?
And how can I fix it?
The SSHClient.exec_command by default does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced (particularly for non-interactive sessions, .bash_profile is not sourced). And/or different branches in the scripts are taken, based on an absence/presence of TERM environment variable.
To emulate the default Paramiko behavior with the ssh, use the -T switch:
ssh -T myuser#host
See the ssh man:
-T Disable pseudo-tty allocation.
Contrary, to emulate the default ssh behavior with Paramiko, set the get_pty parameter of the exec_command to True:
def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):
Though rather than working around the issue by allocating the pseudo terminal in Paramiko, you should better fix your startup scripts to set the same PATH for all sessions.
For that see Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command.
Working with the Channel object instead of the SSHClient object solved my problem.
chan=ssh.invoke_shell()
chan.send('echo $PATH\n')
print (chan.recv(1024))
For more details, see the documentation

Unable to import module when using paramiko sshclient [duplicate]

I am connecting to SSH via terminal (on Mac) and run a Paramiko Python script and for some reason, the two sessions seem to behave differently. The PATH environment variable is different in these cases.
This is the code I run:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='myuser',password='mypass')
stdin, stdout, stderr =ssh.exec_command('echo $PATH')
print (stdout.readlines())
Any idea why the environment variables are different?
And how can I fix it?
The SSHClient.exec_command by default does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced (particularly for non-interactive sessions, .bash_profile is not sourced). And/or different branches in the scripts are taken, based on an absence/presence of TERM environment variable.
To emulate the default Paramiko behavior with the ssh, use the -T switch:
ssh -T myuser#host
See the ssh man:
-T Disable pseudo-tty allocation.
Contrary, to emulate the default ssh behavior with Paramiko, set the get_pty parameter of the exec_command to True:
def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):
Though rather than working around the issue by allocating the pseudo terminal in Paramiko, you should better fix your startup scripts to set the same PATH for all sessions.
For that see Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command.
Working with the Channel object instead of the SSHClient object solved my problem.
chan=ssh.invoke_shell()
chan.send('echo $PATH\n')
print (chan.recv(1024))
For more details, see the documentation

Categories

Resources