Proxycommand in paramiko - python

I'm trying to do a simple proxycommand using paramiko in python.
Basically I'm trying to replicate the behaviour of this ssh command:
ssh -i ~/.ssh/destination_key user#destination.test.internal -o 'ProxyCommand ssh -i ~/.ssh/jumpbox_key -W %h:%p user#jumpbox.test.internal'
The above works as expected amd connects to destination.test.internal.
I'm trying to do the same thing in python with the following on the same box:
#!/usr/bin/python3
import paramiko
import argparse
addresses = ["destination.test.internal"];
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy = paramiko.ProxyCommand("ssh -i ~/.ssh/jumpbox_key -W %h:%p user#jumpbox.test.internal")
for address in addresses:
#Connect over ssh to each server
try:
ssh.connect(address , username='user', key_filename="~/.ssh/destination_key", sock = proxy )
except paramiko.AuthenticationException:
print ("Authentication Failed")
except paramiko.SSHException:
print ("Connection Failed")
stdin,stdout,stderr = ssh.exec_command('ls -l')
print (stdout.readlines())
ssh.close()
Needless to say this isn't working. It's failing with:
Traceback (most recent call last):
Exception: Error reading SSH protocol banner
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 1893, in _check_banner
buf = self.packetizer.readline(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 331, in readline
buf += self._read_timeout(timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 501, in _read_timeout
raise socket.timeout()
socket.timeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 1749, in run
self._check_banner()
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 1897, in _check_banner
raise SSHException('Error reading SSH protocol banner' + str(e))
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
Connection Failed
Traceback (most recent call last):
File "./log_file_fix.py", line 31, in <module>
stdin,stdout,stderr = ssh.exec_command('ls -l')
File "/usr/local/lib/python3.5/dist-packages/paramiko/client.py", line 436, in exec_command
chan = self._transport.open_session(timeout=timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 716, in open_session
timeout=timeout)
File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 800, in open_channel
raise SSHException('SSH session not active')
paramiko.ssh_exception.SSHException: SSH session not active
However I'm not sure where I'm going wrong.

Instead of %h:%p, Specify host and port inside paramiko.ProxyCommand()
proxy = paramiko.ProxyCommand("ssh -i ~/.ssh/jumpbox_key -W DESTINATION_HOST_ADDRESS:22 user#jumpbox.test.internal")
You have to change your code like below:
#!/usr/bin/python3
import paramiko
import argparse
addresses = ["destination.test.internal"];
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for address in addresses:
proxy_jump_command='ssh -i ~/.ssh/jumpbox_key -W {HOST}:{PORT} user#jumpbox.test.internal'.format(HOST=address, PORT=22)
proxy = paramiko.ProxyCommand(proxy_jump_command)
#Connect over ssh to each server
try:
ssh.connect(address , username='user', key_filename="~/.ssh/destination_key", sock = proxy )
except paramiko.AuthenticationException:
print ("Authentication Failed")
except paramiko.SSHException:
print ("Connection Failed")
stdin,stdout,stderr = ssh.exec_command('ls -l')
print (stdout.readlines())
ssh.close()

Related

How to run a program in Paramiko's SSH ProxyCommand

I'm pretty new with Paramiko and python in general. I'm trying to connect to a server and execute some commands on it by ssh through the use of Paramiko's API and a program called Pomerium. My ssh config file is as shown below
Host *.stg-id-proxy.lab.com
ProxyCommand pomerium-cli tcp --listen - %h:%p
User placeholder
and my python code in file "ssh4.py" is as follows
import paramiko
host = "place.stg-id-proxy.lab.com"
port = 22
username = "placeholder"
password = "pass#!#"
command = "pwd"
proxy = paramiko.ProxyCommand("pomerium-cli tcp --listen - %h:%p")
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password, allow_agent=False, look_for_keys=False, sock=proxy, banner_timeout=60)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
print(lines)
but when I tried running:
python3 ssh4.py
I keep getting the following error
Exception (client): Error reading SSH protocol banner
Traceback (most recent call last):
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2271, in _check_banner
buf = self.packetizer.readline(timeout)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/packet.py", line 380, in readline
buf += self._read_timeout(timeout)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/packet.py", line 622, in _read_timeout
raise socket.timeout()
socket.timeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2094, in run
self._check_banner()
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2275, in _check_banner
raise SSHException(
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
Traceback (most recent call last):
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2271, in _check_banner
buf = self.packetizer.readline(timeout)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/packet.py", line 380, in readline
buf += self._read_timeout(timeout)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/packet.py", line 622, in _read_timeout
raise socket.timeout()
socket.timeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "ssh4.py", line 11, in <module>
ssh.connect(host, port, username, password, allow_agent=False, look_for_keys=False, sock=proxy, banner_timeout=60)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/client.py", line 406, in connect
t.start_client(timeout=timeout)
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 699, in start_client
raise e
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2094, in run
self._check_banner()
File "/Users/placeholder/Library/Python/3.8/lib/python/site-packages/paramiko/transport.py", line 2275, in _check_banner
raise SSHException(
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
So, any help would be appreciated. Also documentation for Pomerium can be found here:
https://github.com/pomerium/cli
Thank you in advance.

Connect to SSH server through SOCKS5 proxy

how to connect via ssh using shared key with socks in python?
I have tested several ways, any suggestions?
Thank you very much in advance ...
Imports:
import paramiko
from paramiko import RSAKey
import socket
import socks
import base64
Script:
def createSSHClient(server, port, user):
sock=socks.socksocket()
sock.set_proxy(
proxy_type=socks.SOCKS5,
addr='10.0.0.2',
port=1080,
username=base64.b64decode('dXNlcg==').decode("utf-8"),
password=base64.b64decode('cGFzc3dvcmQ=').decode("utf-8")
)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
privkey = paramiko.RSAKey.from_private_key_file('/home/my-user/.ssh/id_rsa')
ssh.connect(server, port, user, privkey, sock)
return ssh
outputsocks = []
ssh = createSSHClient('192.168.1.23', 22, 'my-user')
outputsocks.append((ssh.exec_command('ls -ltr')[1]).read().decode('ascii'))
ssh.close()
print(outputsocks)
Output:
Traceback (most recent call last):
File "/home/my-user/teste2.py", line 26, in <module>
ssh = createSSHClient('192.168.1.23', 22, 'my-user')
File "/home/my-user/teste2.py", line 22, in createSSHClient
ssh.connect(server, port, user, privkey, sock)
File "/usr/local/lib/python3.6/site-packages/paramiko/client.py", line 349, in connect
retry_on_signal(lambda: sock.connect(addr))
File "/usr/local/lib/python3.6/site-packages/paramiko/util.py", line 283, in retry_on_signal
return function()
File "/usr/local/lib/python3.6/site-packages/paramiko/client.py", line 349, in <lambda>
retry_on_signal(lambda: sock.connect(addr))
TimeoutError: [Errno 110] Connection timed out
Note: The same script works if you remove the connection via socks and use a host that does not need a VPN, the socks credentials are correct and the shared key works.
The error was in not opening the connection via sock before starting SSH, this was resolved with sock.connect()
More info: socket connect() vs bind()
Bug fix:
def createSSHClient(server, port, user):
sock=socks.socksocket()
sock.set_proxy(
proxy_type=socks.SOCKS5,
addr='10.0.0.2',
port=1080,
username=base64.b64decode('dXNlcg==').decode("utf-8"),
password=base64.b64decode('cGFzc3dvcmQ=').decode("utf-8")
)
sock.connect(('192.168.1.20',22))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
privkey = paramiko.RSAKey.from_private_key_file('/home/my-user/.ssh/id_rsa')
ssh.connect(server, port, user, privkey, sock)
return ssh
outputsocks = []
ssh = createSSHClient('192.168.1.23', 22, 'my-user')
outputsocks.append((ssh.exec_command('ls -ltr')[1]).read().decode('ascii'))
ssh.close()
sock.close()
print(outputsocks)

Paramiko stuck on for loop

I need to perform a remote software update for a Linux device.
I'm able to upload via SSH and SFTP to /tmp/ folder the .bin file and perform the sysupgrade.
I want to do this on multiple device, so I added a for loop in order to do it.
But, when I run the ssh.exec_command("sysupgrade /tmp/myfile.bin"), something stucks.
Here's my code:
import paramiko
# paths to file
local_path="C:/Users/Desktop/myfile.bin"
remote_path="/tmp/myfile.bin"
# IP
ip_list = ["my_ip_1","my_ip_2"]
password_list=["passw_1","passw_2"]
#Start SSH
ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# loop for IP and password
for i,n in zip(ip_list,password_list):
print(i,n)
try:
print("Open session in: " + i + "...")
ssh.connect(i, username='root', password=n)
except paramiko.SSHException:
print("Connection Failed")
quit()
# Upload file to /tmp/
print("Uploading file to " + str(i) + " in /tmp/...")
sftp = ssh.open_sftp()
sftp.put(local_path, remote_path)
try:
# Here something stucks
stdin, stdout, stderr = ssh.exec_command("sysupgrade /tmp/myfile.bin", timeout=30)
sysupgrade_response=stdout.readlines()
print(sysupgrade_response)
sftp.close()
ssh.close()
except paramiko.SSHException:
print("Continue with others IP in list...")
sftp.close()
ssh.close()
continue
sftp.close()
ssh.close()
print("\n\n***********************End execution***********************\n\n")
This is the errors I got:
Traceback (most recent call last):
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\channel.py", line 699,
in recv
out = self.in_buffer.read(nbytes, self.timeout)
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\buffered_pipe.py",
line 164, in read
raise PipeTimeout()
paramiko.buffered_pipe.PipeTimeout
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Python Scripts\myscript.py", line 73, in <module>
sysupgrade_response=stdout.readlines()
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\file.py", line 349,
in readlines
line = self.readline()
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\file.py", line 291,
in readline
new_data = self._read(n)
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\channel.py", line 1361,
in _read
return self.channel.recv(size)
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\paramiko\channel.py", line 701,
in recv
raise socket.timeout()
After the "sysupgrade" command, I would like to close the connection with the first ip in the list ( or handling some errors ) and go on with the for loop and connect to the second ip in the list.
Hope is clear enough
I assume that the sysupgrade restarts the machine or at least the SSH server or networking.
I would guess that if you execute sysupgrade in your SSH client, it will also lose the connection, won't it?

Python SSH Paramiko EOFError

I have just simple script like that to connect via SSH on Nokia router and execute command "show time":
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('adres ip', port=22, username='username', password='password')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('show time')
output = stdout.readlines()
print '\n'.join(output)
ssh.close()
Login to the node is successful. I see myself on the router, but executing command are not gonna work. I get error like that:
Traceback (most recent call last): File "C:\Users\pkudalsk\Desktop\pyt.py", line 6, in <module>
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('show time') File "C:\Users\pkudalsk\Desktop\paramiko\client.py", line 479, in exec_command
chan.exec_command(command) File "C:\Users\pkudalsk\Desktop\paramiko\channel.py", line 63, in _check
return func(self, *args, **kwds) File "C:\Users\pkudalsk\Desktop\paramiko\channel.py", line 241, in exec_comman d
self._wait_for_event() File "C:\Users\pkudalsk\Desktop\paramiko\channel.py", line 1198, in
_wait_for_ event
raise e EOFError
Does anyone know what can cause this problem? I tried on python 3.6 and 2.7. The same result.
Thanks

Python Script Pexpect SSH

I'm trying to do a Python script (with a loop) to connect in SSH,it works if everything is good ( password and route) but stop when it's not working(wrong password or no routes to host ).Here is the important part of the script, how can I control if everything is working ?
connexion = pexpect.spawn("ssh -o StrictHostKeyChecking=no "+user+"#" + ip )
index=connexion.expect(':')
connexion.sendline(password + "\r")
connexion.expect('>')
connexion.sendline('show clock \r')
connexion.expect('>')
connexion.sendline('exit')
connexion.close()
I get the error :
Traceback (most recent call last):
File "script.py", line 21, in <module>
connexion.expect('>')
File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1418, in expect
timeout, searchwindowsize)
File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1433, in expect_list
timeout, searchwindowsize)
File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1521, in expect_loop
raise EOF(str(err) + '\n' + str(self))
pexpect.EOF: End Of File (EOF). Exception style platform.
<pexpect.spawn object at 0x7fcfeecee750>
version: 3.1
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-o', 'StrictHostKeyChecking=no', 'username#10.9.128.5']
searcher: <pexpect.searcher_re object at 0x7fcfeecee850>
buffer (last 100 chars): ''
before (last 100 chars): ' connect to host 10.9.128.5 port 22: No route to host\r\r\npassword\r\n\r\n'
Thanks
The problem is that the host 10.9.128.5 was not reachable at the moment.
ssh has returned this message:
connect to host 10.9.128.5 port 22: No route to host
And not that, what was expected.
You are getting an exception which needs to be handled correctly. Below is some code that you can use as an example to pass the exception and log it.
def ignore_exception_out(conn, text, timeout=10):
try:
conn.expect(text, timeout)
except Exception as e:
logging.log("Exception reached {0}".format(e))
pass

Categories