Python: Unable to connect SSH with paramiko - python

This is my first time using paramiko. I'm trying to establish an SSH session to a test Amazon Linux 2 instance where I've enabled password authentication, since that doesn't come enabled by default and restarted the SSH daemon on the box. I also made sure that I could connect with SSH via the normal SSH program using the username / password I put in the Python program.
When I run the Python code below, everything looks good and it waits for input and keeps the program running, but when I'm logged into the Amazon instance, I don't see the paramiko user logged in (I did a "w" and a "who" command). In fact, I have no evidence server-side that Paramiko ever connects successfully to begin with.
#!/usr/bin/env python3
import pprint
import boto3
import os
import paramiko
os.system('clear')
pp = pprint.PrettyPrinter(indent=4)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('X.X.X.X',username='the_username',password='the_password',port=22)
get_input = input("Preventing program from closing and keeping SSH connectiion alive...")

who shows interactive shell sessions only.
Your code only connects. It does not start a shell, let alone an interactive shell.
See List all connected SSH sessions?

Related

Paramiko can't find keys from ssh-agent on Windows

I am trying to connect to a test device on my local network using paramiko and SSH. If I specify the filename of my key and its passphrase, I can connect to the device without a problem. However, since my script is meant to run on any machine that has the key added to the ssh-agent, I am trying to find a way around that.
ssh-add -l shows me that the key is active in my ssh-agent, but if I use the get_keys() method from the paramiko.Agent-class, there's just an empty list, meaning to me that Paramiko either can't connect to the ssh-agent or doesn't have the permissions to get the keys.
From shell, I can just connect to the device with ssh root#IPADDRESS. When I try to connect to device with Paramiko without specifying the path to the key and its passphrase, I'm just getting the "Authentication failed" error.
import paramiko
import os
def createSSHClient(server, port, user):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, username=user)
return client
ssh = createSSHClient('IPADDRESS', 22, 'root')
Checking SSH_AUTH_SOCK in os.environ gives me back False, but as far as I know, SSH on Windows doesn't quite work like on Unix/Linux.
Paramiko can talk to Windows OpenSSH ssh-agent since 2.10 only (and it was buggy in 2.10.3). Make sure you have the latest version of Paramiko.
Older versions could talk to PuTTY Pageant only.

Python script to SSH into a jumphost and sftp from within that box

I'm currently trying to write an airflow job that will allow me to ssh into an EC2 instance and then start an sftp session with another host from within this EC2 box. My current code that I have is as follows:
def run_ssh():
hook = SSHHook(ssh_conn_id='xyz').get_conn() #returns an ssh client
stdin, stdout, stderr = hook.exec_command('sftp user#host.com;')
# This next step prompts me for password so i provide it
stdin.write('password')
logging.info(stdout.readlines())
stdin, stdout, stderr = hook.exec_command('ls')
logging.info(stdout.readlines())
When i print the final line i should be seeing some folders but instead just see ['a\n']... so it seems I'm not actually able to sftp. Are there better ways to sftp from a remote host through a python script running locally.
Any help with this is appreciated. The answer can be geared towards a simple python script as opposed to airflow.
For your literal question, see:
Pass input/variables to command/script over SSH using Python Paramiko
Though implementing an SFTP over jump host this way is not a good solution.
Use port forwarding instead:
Nested SSH using Python Paramiko
Port forwarding and the open SFTP using Python Paramiko

Using paramiko when a unix server is using VShell

Use case
On a unix server , when login manually ,opens a command shell of its own to run the command.
I am trying to automate this by using paramiko , however , somehow i am not able to execute the command on command shell using paramiko
What i have done ?
I created a simple script which is able to make connection, but its not executing command on Vshell as the ouput is always coming empty.
import paramiko
import sys
ssh_client=paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=sys.argv[1],port=sys.argv[2],username=sys.argv[3],password=sys.argv[4])
command="show hwid"
stdin,stdout,stderr=ssh_client.exec_command(command)
out=stdout.read()
print out
err=stderr.read()
print err
ssh_client.close()
The same script runs perfectly fine , when its used on server where vshell is not being used
Anyhelp or suggestion on this?
stdin,stdout,stderr=ssh_client.exec_command(command)
Regarding this line of code, I suspect that the SSH server is not properly configured to allow commands to be executed in this way (this is the equivalent of ssh myserver show hwid, rather than typing it into the terminal after login).
You might want to imitate the behaviour of typing the command in after logging into the server, and for that I think this is appropriate:
shell = ssh_client.invoke_shell()
stdin, stdout, stderr = shell.exec_command(command)

Send ctrl-C to OSX Terminal in an SSH Session in Python

This solution requires me to run Python on the same machine as the process I am trying to terminate.
However, I'm running Python locally and have the process running over SSH in Terminal. How do I send the terminate command in this situation?
SSH using pexpect after setting up ssh-keygen with the server so that it doesn't require a password from your machine:
import pexpect
ssh_command = 'ssh user#your.server.com'
child = pexpect.spawn(ssh_command)
default_prompt = 'user#server:~/# '
child.expect(default_prompt)
kill_command = 'killall process_name'
child.sendline(kill_command)
If you don't use ssh-keygen, you will need to work your password login into the pexpect script before the default_prompt line.
Just attach this script to a hotkey (e.g. ctrl+alt+c) using Alfred.

Start a script on a remote machine through ssh with python - but in reverse?

Here's what I need to do:
The user is on a remote machine and connects to a server via ssh. He runs a python script on the server. The script running on the server starts a script on the user's remote machine as a subprocess and opens a pipe to it for communication.
First, is this at all possible?
Second, is this possible in such a way that the user does not need to do anything fancy, like open up a reverse ssh tunnel? If they do have to open up a reverse ssh tunnel, can I figure out which port they are using?
First, is this at all possible?
With simple user --SSH--> server - no, its not.
is this possible in such a way that the user does not need to do anything fancy
User will have to run sshd on his machine, add a user for your server and somehow let you to connect to it, bypassing NAT if any. So no, there is no such way with SSH.
I'd go with client-side application. Give script to user and let him run the script instead of SSH'ing. If you need to communicate with server, you can use something like paramiko on client side to connect to server from script. Then, script can launch other applications on client's computer based on data it receives from server.

Categories

Resources