iproxy and paramiko give connection error - python

I am attempting to use paramiko with iproxy to ssh to an iOS host, after Catalina seemingly killed my other method.
Firstly I forward local port to device port
iproxy 2222 22 -u <UUIDxxxxxx>
This can be seen on netstat that its listening
tcp6 0 0 ::1.2222 *.* LISTEN
tcp4 0 0 127.0.0.1.2222 *.* LISTEN
However with paramiko, I always get a NoValidConnections error
File "/usr/local/lib/python2.7/site-packages/paramiko/client.py", line 368, in connect raise NoValidConnectionsError(errors)
paramiko.ssh_exception.NoValidConnectionsError: [Errno None] Unable to connect to port 2222 on 127.0.0.1
Current python code is:
sshIP = "127.0.0.1"
sshPort = 2222
ssh_client =paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=sshIP,username='root',password=sshPass,port=sshPort)
stdin,stdout,stderr = ssh_client.exec_command("sw_vers")
prodver = stdout.readlines()
SSHing manually from cli works fine.
####IPROXY OUTPUT
New connection for 2222->22, fd = 5
waiting for connection
Requesting connecion to USB device handle 571 (serial: UUIDXXXXX), port 22
# CLI SSH
$ ssh root#127.0.0.1 -p 2222
Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
root#127.0.0.1's password:
Last login: Tue May 25 11:41:30 2021 from 127.0.0.1
iPhone-Black:~ root#

Not too sure what was the overall fix, but I added a time.sleep(3) after calling iproxy to ensure that it had started successfully before calling paramiko.
I also changed the order of the paramiko options, and added port= after hostname= as per paramiko documentation.
connect(hostname, port=port, username=None, password=None,
Both of these seem to have helped and connections are now made correctly.
ssh_client =paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=sshIP,port=sshPort,username='root',password=sshPass)

Related

SFTP Connection From Python [duplicate]

I have executed commands on server using ssh. Now I have to do another ssh to different IP while keeping old ssh active.
This new IP is port forward which will then used to do SFTP.
Issue I am facing is both ssh connections are on same port so not able to do second ssh.
Which is failing the SFTP.
Any support for same will be helpful.
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=username, password=password, port=22)
time.sleep(3)
#Invoke shell to open multiple channel with in one SSH
chan = ssh.invoke_shell()
chan.send(ip1+'\n')
time.sleep(5)
chan.send(pass1+'\n')
time.sleep(10)
chan.send("ssh "+ip2+'\n')
time.sleep(10)
chan.send(pass2+'\n')
time.sleep(5)
#Execute command
chan.send(cmd)
#connect to another ip to do sftp
ssh1 = paramiko.SSHClient()
ssh1.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("127.0.0.4", username=usr2, password=pass2, port=22)
sftp=ssh.open_sftp()
It looks like misunderstanding. Your code does not do any port forwarding.
For the correct code, see Nested SSH using Python Paramiko.
If you need SFTP, not shell, just do:
jhost.open_sftp()
instead of
jhost.exec_command(command)
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".

Connect to a host that doesn't answer to ping

I am trying to connect to a smtp port to automatically send emails through it. The problem is that when trying to connect to it with python smtplib it gives an error that it can't connect to the host. When trying to run nmap with the command
nmap -T4 -p 25,587,465
I get the following output:
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 2.12 seconds
When I add the -Pn option I get the following output:
Host is up.
PORT STATE SERVICE
25/tcp filtered smtp
465/tcp filtered smtps
587/tcp filtered submission
The python script that I have used is:
import smtplib, ssl
port = 465
password = "password"
email = "my#mail"
hostname = "hostname"
context = ssl.create_default_context()
with smtplib.SMTP_SSL(hostname, port, context=context) as server:
server.login(email, password)
And this is the error I get:
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I am running the code on a Windows 10 machine and using Python 3.7.5.
Is there any way for me to connect to one of the email ports and send emails through it through python or c/c++?

SSH to server through middle server using python

I'm trying to do ssh through middle server with python.
I tried to work as written at this example : SSH to machine through a middle host
but when I'm running the code, I'm getting the following exception paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
When I'm opens the terminal that executes the program password authentication is required in order to proceed
I also edited the ~/.ssh/config as follows:
Host cybnode13
ProxyCommand ssh root#cybhead1.lnx.biu.ac.il nc %h %p
My code is attached below
proxy_command = 'ssh -p %s %s#%s nc %s %s' % (password, proxy_user, proxy_host, host, 22)
proxy = paramiko.ProxyCommand(proxy_command)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username=proxy_user, password=password, sock=proxy)
stdin, stdout, stderr = client.exec_command('echo HELLO')

paramiko.ssh_exception.ProxyCommandFailure: 'Broken pipe')

I am trying to ssh tunnel from PC --> server1 ---> server2 ----> switch1
This is possible through a regular terminal with a simple: ssh switch1 it references my ssh_config which reads:
Host server1
user bill
Hostname server1
ForwardAgent yes
IdentityFile ~/.ssh/id_rsa
ProxyCommand none
Host server2
user bill
Hostname server2
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh server1 /usr/bin/nc %h %p
Host switch1
user bill
Hostname %h.omniture.com
ProxyCommand ssh server2 /usr/bin/nc %h %p
Not a problem from regular terminal. But trying to build a python script to do it has proven to be difficult.
Script is as follows:
import paramiko
import subprocess
import getpass
import os
def ssh_command(ip, user, passwd, command):
client = paramiko.SSHClient()
client.load_host_keys('/Users/bill/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
config = paramiko.SSHConfig()
if os.path.exists('/etc/ssh/ssh_config'):
config.parse(open('/etc/ssh/ssh_config'))
if os.path.exists(os.path.expanduser('~/.ssh/config')):
config.parse(open(os.path.expanduser('~/.ssh/config')))
host = config.lookup(ip)
if 'proxycommand' in host:
proxy = paramiko.ProxyCommand(
subprocess.check_output(
[os.environ['SHELL'], '-c', 'echo %s' %
host['proxycommand']]
).strip()
)
else:
proxy = None
client.connect(host['hostname'], username='bill',
password=getpass.getpass(), sock=proxy)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
ssh_session.exec_command(command)
print ssh_session.recv(1024)
return
ssh_command('sw-a-102.sin2', 'bill', getpass.getpass(), 'show ver')
The error I get is:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "/Users/bill/git/tools/python/dns-check/proxy-test.py", line 34, in <module>
ssh_command('switch1', 'bill', getpass.getpass(), 'show ver')
File "/Users/bill/git/tools/python/dns-check/proxy-test.py", line 28, in ssh_command
client.connect(host['hostname'], username='bill', password=getpass.getpass(), sock=proxy)
File "/Library/Python/2.7/site-packages/paramiko/client.py", line 265, in connect
t.start_client()
File "/Library/Python/2.7/site-packages/paramiko/transport.py", line 406, in start_client
raise e
paramiko.ssh_exception.ProxyCommandFailure: ('ssh server2 /usr/bin/nc switch1 22', 'Broken pipe')
If I can get this to work using paramiko that would be great, if someone knows a better way, that would be good too. Thank you for your time.
There is a better way, still with Paramiko but without ProxyCommand configuration.
Reason being paramiko's proxy command support is buggy and prone to race conditions, which is the cause of the error above.
OTOH, SSH has native support for tunneling in the protocol itself and does not require external tools to achieve it.
import paramiko
# Make clients
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
server2_client = paramiko.SSHClient()
server2_client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
switch1_client = paramiko.SSHClient()
switch1_client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
# Connect to server1 normally
client.connect('server1')
# Make channel server1 -> server2
server2_chan = client.get_transport().open_channel('direct-tcpip', ('<server2 ip>', 22,), ('127.0.0.1', 0))
# Connect to server2 via server1's channel
server2_client.connect('<server2 ip>', sock=server1_chan)
# Make channel server2 -> switch1
switch1_chan = server2_client.get_transport().open_channel('direct-tcpip', ('<switch1 ip>', 22,), ('127.0.0.1', 0))
# Finally connect to switch1 via server2 channel
switch1_client.connect('switch1', sock=server2_chan)
switch1_client.exec_command(<command>)
Substitute server and switch names with their IP addresses.
See also a parallel SSH client based on paramiko with support for native SSH tunneling.

Paramiko: Port Forwarding Around A NAT Router

Configuration
LOCAL: A local machine that will create an ssh connection and issue commands on a REMOTE box.
PROXY: An EC-2 instance with ssh access to both LOCAL and REMOTE.
REMOTE: A remote machine sitting behind a NAT Router (inaccessible by LOCAL, but will open a connection to PROXY and allow LOCAL to tunnel to it).
Port Forwarding Steps (via command line)
Create an ssh connection from REMOTE to PROXY to forward ssh traffic on port 22 on the REMOTE machine to port 8000 on the PROXY server.
# Run from the REMOTE machine
ssh -N -R 0.0.0.0:8000:localhost:22 PROXY_USER#PROXY_HOSTNAME
Create an ssh tunnel from LOCAL to PROXY and forward ssh traffic from LOCAL:1234 to PROXY:8000 (which then forwards to REMOTE:22).
# Run from LOCAL machine
ssh -L 1234:localhost:8000 PROXY_USER#PROXY_HOSTNAME
Create the forwarded ssh connection from LOCAL to REMOTE (via PROXY).
# Run from LOCAL machine in a new terminal window
ssh -p 1234 REMOTE_USER#localhost
# I have now ssh'd to the REMOTE box and can run commands
Paramiko Research
I have looked at a handful of questions related to port forwarding using Paramiko, but they don't seem to address this specific situation.
My Question
How can I use Paramiko to run steps 2 and 3 above? I essentially would like to run:
import paramiko
# Create the tunnel connection
tunnel_cli = paramiko.SSHClient()
tunnel_cli.connect(PROXY_HOSTNAME, PROXY_PORT, PROXY_USER)
# Create the forwarded connection and issue commands from LOCAL on the REMOTE box
fwd_cli = paramiko.SSHClient()
fwd_cli.connect('localhost', LOCAL_PORT, REMOTE_USER)
fwd_cli.exec_command('pwd')
A detailed explanation of what Paramiko is doing "under the hood" can be found at #bitprohet's blog here.
Assuming the configuration above, the code I have working looks something like this:
from paramiko import SSHClient
# Set up the proxy (forwarding server) credentials
proxy_hostname = 'your.proxy.hostname'
proxy_username = 'proxy-username'
proxy_port = 22
# Instantiate a client and connect to the proxy server
proxy_client = SSHClient()
proxy_client.load_host_keys('~/.ssh/known_hosts/')
proxy_client.connect(
proxy_hostname,
port=proxy_port,
username=proxy_username,
key_filename='/path/to/your/private/key/'
)
# Get the client's transport and open a `direct-tcpip` channel passing
# the destination hostname:port and the local hostname:port
transport = proxy_client.get_transport()
dest_addr = ('0.0.0.0', 8000)
local_addr = ('127.0.0.1', 1234)
channel = transport.open_channel("direct-tcpip", dest_addr, local_addr)
# Create a NEW client and pass this channel to it as the `sock` (along with
# whatever credentials you need to auth into your REMOTE box
remote_client = SSHClient()
remote_client.load_host_keys(hosts_file)
remote_client.connect('localhost', port=1234, username='remote_username', sock=channel)
# `remote_client` should now be able to issue commands to the REMOTE box
remote_client.exec_command('pwd')
Is the point solely to bounce SSH commands off PROXY or do you need to forward other, non SSH ports too?
If you just need to SSH into the REMOTE box, Paramiko supports both SSH-level gatewaying (tells the PROXY sshd to open a connection to REMOTE and forward SSH traffic on LOCAL's behalf) and ProxyCommand support (forwards all SSH traffic through a local command, which could be anything capable of talking to the remote box).
Sounds like you want the former to me, since PROXY clearly already has an sshd running. If you check out a copy of Fabric and search around for 'gateway' you will find pointers to how Fabric uses Paramiko's gateway support (I don't have time to dig up the specific spots myself right now.)

Categories