我的网络跃点是 A(本地)-> B -> C -> D(在端口 3306 上为本地主机打开了数据库)。
我需要从 A 访问 D 上的那个数据库。
我正在使用织物进行 ssh 连接
我的代码如下所示:
import socket
from contextlib import closing
from fabric import Connection
import mysql.connector
def _connect_to_middleware_database(self, port):
return mysql.connector.connect(
user="DB-USER",
password="MYPASS",
host="127.0.0.1",
port=port,
database="tasks",
connection_timeout=10)
def get_free_port():
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind(("localhost", 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
def _get_connection(self, ip, port, user, pw):
return Connection(
host=ip,
port=port,
user=user,
connect_kwargs={
"password": pw,
"allow_agent": False,
"look_for_keys": False,
},
)
res = {}
local_port = get_free_port()
local_port_1 = get_free_port()
local_port_2 = get_free_port()
c1 = self._get_connection(
"IP-B",
22,
"USER-B",
"PASS-B",
)
c2 = self._get_connection(
"127.0.0.1",
local_port,
"USER-C",
"PASS-C",
)
c3 = self._get_connection(
"127.0.0.1",
local_port_1,
"USER-D",
"PASS-D",
)
with c1.forward_local(
local_port=local_port,
remote_port=22,
local_host="127.0.0.1",
remote_host="IP-C",
):
with c2.forward_local(
local_port=local_port_1,
remote_port=22,
local_host="127.0.0.1",
remote_host="IP-D",
):
with c3.forward_local(
local_port=local_port_2,
remote_port=3306,
local_host="127.0.0.1",
remote_host="127.0.0.1",
):
cnx = _connect_to_middleware_database(
local_port_2
)
if cnx:
cursor = cnx.cursor()
cursor.execute("show tables")
sql_result = cursor.fetchall()
print(str(sql_result))
问题是它只会真正不一致。在某些尝试中它有效,但在大多数情况下我得到:
Traceback (most recent call last):
File "tunnel_test.py", line 78, in <module>
remote_host="IP-D",
File "/usr/lib/python3.6/contextlib.py", line 159, in helper
return _GeneratorContextManager(func, args, kwds)
File "/usr/lib/python3.6/contextlib.py", line 60, in __init__
self.gen = func(*args, **kwds)
File "<decorator-gen-6>", line 2, in forward_local
File "/usr/local/lib/python3.6/dist-packages/fabric/connection.py", line 29, in opens
self.open()
File "/usr/local/lib/python3.6/dist-packages/fabric/connection.py", line 634, in open
self.client.connect(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/paramiko/client.py", line 368, in connect
raise NoValidConnectionsError(errors)
paramiko.ssh_exception.NoValidConnectionsError: [Errno None] Unable to connect to port 59235 on 127.0.0.1
事实上它在某些情况下有效,而且我使用的是绝对可以访问的主机。
我很感谢所有的答案。