Search code examples
pythonsshkeyparamikosocks

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.


Solution

  • 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)