Translate Oracle SQL Developer SSH Host w/ Local Port Forward Connection to Python

岁酱吖の 提交于 2020-12-30 04:45:49

问题


I'm trying to create a Python connection to a remote server through an SSH Jump Host (one I've successfully created in Oracle SQL Developer) but can't replicate in Python. Can connect to SSH Host successfully but fail to forward the port to the remote server due to timeout or error opening tunnels. Safe to assume my code is incorrect rather than server issues. Also need a solution that doesn't use the "with SSHTunnelForwarder() as server:" approach because I need a continuous session similar to OSD/cx_Oracle session rather than a batch processing function.

Similar examples provided here (and elsewhere) using paramiko, sshtunnel, and cx_Oracle haven't worked for me. Many other examples don't require (or at least clearly specify) separate login credentials for the remote server. I expect the critical unclear piece is which local host + port to use, which my SQL Developer connection doesn't require explicitly (although I've tried using the ports OSD chooses, not at the same time).

Closest match I think was best answer from paramiko-port-forwarding-around-a-nat-router

OSD Inputs

SSH Host
- host = proxy_hostname
- port = proxy_port = 22
- username = proxy_username
- password = proxy_password

Local Port Forward
- host = remote_hostname
- port = remote_port = 1521
- automatically assign local port = True

Connection
- username = remote_username
- password = remote_password
- connection type = SSH
- SID = remote_server_sid

Python Code

i.e., analogous code from paramiko-port-forwarding-around-a-nat-router

import paramiko
from paramiko import SSHClient

# Instantiate a client and connect to the proxy server
proxy_client = SSHClient()
proxy_client.connect(
    proxy_hostname,
    port=proxy_port,
    username=proxy_username,
    password=proxy_password)

# 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 = (remote_hostname,remote_port)
local_addr = ('localhost',55587)
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.connect(
    'localhost',
    port=55587, 
    username=remote_username, 
    password=remote_password,
    sock=channel)

Rather than a connection to the remote server I get

transport.py in start_client()
SSHException: Error reading SSH protocol banner

回答1:


Solution

Finally figured out a solution! Analogous to OSD's automatic local port assignment and doesn't require SSHTunnelForwarder's with statement. Hope it can help someone else- use the question's OSD input variables with...

from sshtunnel import SSHTunnelForwarder
import cx_Oracle 

server=SSHTunnelForwarder(
    (proxy_hostname,proxy_port),
    ssh_username=proxy_username,
    ssh_password=proxy_password,
    remote_bind_address=(remote_hostname,remote_port))

server.start()
db=cx_Oracle.connect('%s/%s@%s:%s/%s'%(remote_username,remote_password,'localhost',server.local_bind_port,remote_server_sid))
# do something with db
server.close()


来源:https://stackoverflow.com/questions/56279028/translate-oracle-sql-developer-ssh-host-w-local-port-forward-connection-to-pyth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!