ble*_*lep 6 python sql ssh sqlalchemy paramiko
我有一个托管在 Amazon RDS(“D”)上的远程 MySQL 数据库。出于安全目的,它只能通过远程服务器(“C”)访问。C 可通过跳转主机“B”通过 ssh 访问。我需要一个双 ssh 隧道来访问远程 SQL 主机。
[A: local host] -> [B: jump host] -> [C: target host] => [D: RDS MySQL host]
Run Code Online (Sandbox Code Playgroud)
我想通过 Python 访问 D,使用 paramiko 和/或 sshtunnel。我能找到的所有信息都涉及:
到目前为止,我使用 paramiko 和一个代理命令来从 A 到 C。我可以通过在 C 上执行命令来访问 D,但不能通过连接 mysqldb 或 sqlalchemy(我的最终目标)。
我目前的代码:
[A: local host] -> [B: jump host] -> [C: target host] => [D: RDS MySQL host]
Run Code Online (Sandbox Code Playgroud)
我正在寻找这样的东西(从sshtunnel 文档中的示例 2 修改):
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy = paramiko.ProxyCommand("ssh -A B_username@B_host -W C_host:12345")
ssh.connect("C_host", username="C_username", sock=proxy)
stdin, stdout, stderr = ssh.exec_command("mysql -u D_username -p D_password -h D_host_rds")
print("STDOUT:\n{}\n\nSTDERR:\n{}\n".format(stdout.read(), stderr.read()))
# successfully prints out MySQL welcome screen
Run Code Online (Sandbox Code Playgroud)
tl; dr:如何通过 Python 中的两次 ssh 跳转来转发端口?
我想到了。它结合了 ssh 配置设置和sshtunnel库中的 SSHTunnelForwarder 上下文管理器。
[A: local host] -> [B: jump host] -> [C: target host] => [D: RDS MySQL host]
我将 ~/.ssh/config 设置为从 A 到 C 通过 B:
Host C_ssh_shortcut
HostName C_host
User C_user
Port 22
ForwardAgent yes
ProxyCommand ssh B_user@B_host -W %h:%p
Run Code Online (Sandbox Code Playgroud)
我将用于登录 B 和 C 的密钥/密钥添加到我的 ssh-agent:
ssh-add
Run Code Online (Sandbox Code Playgroud)
最后我设置了 SSHTunnelForwarder:
import sqlalchemy
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(
"C_ssh_shortcut", # The SSHTunnelForwarder "ssh_address_or_host" argument, which takes care of bypassing B through the ProxyCommand set up in ~/.ssh/config
remote_bind_address=(D_host, 3306), # Points to your desired destination, ie. database host on 3306, which is the MySQL port
local_bind_address=('', 1111) # Gives a local way to access this host and port on your machine. '' is localhost / 127.0.0.1, 1111 is an unused port
) as server:
connection_string = "mysql+pymysql://D_user:D_password@localhost:1111/D_dbname" # note that D_host and D_port were replaced by the host and port defined in "local_bind_address"
engine = sqlalchemy.create_engine(connection_string)
# do your thing
Run Code Online (Sandbox Code Playgroud)
从这里,我可以像往常一样使用我的引擎与我的数据库进行交互。
| 归档时间: |
|
| 查看次数: |
7527 次 |
| 最近记录: |