当前位置: 首页 > 知识库问答 >
问题:

带跳转主机和远程数据库的SSH隧道转发

赵华彩
2023-03-14

我有一个远程MySQL数据库托管在Amazon RDS(“D”)上。出于安全目的,它只能通过远程服务器(“C”)访问。C可以通过一个跳转主机“B”通过ssh访问。我需要一个双ssh隧道来访问远程SQL主机。

[A: local host] -> [B: jump host] -> [C: target host] => [D: RDS MySQL host]

我想通过Python访问D,使用paramiko和/或sshtunnel。我能找到的所有信息包括:

  • 单个ssh隧道和远程SQL主机(例如A->C=>D,无跳转主机)
    • 在Python中首先使用mysqldb ssh
    • Python mysql通过SSH连接
      null
    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
    

    我正在寻找这样的东西(从sshtunnel文档中的示例2修改):

    import paramiko
    from sshtunnel import SSHTunnelForwarder
    
    with SSHTunnelForwarder(
        intermediate = {
            ("B_host", 22),
            ssh_username = "B_username",
            ssh_password = "B_password")},
        remote = {
            ("C_host", 12345),
            ssh_username = "C_username",
            ssh_password = "C_password")},
        remote_bind_address=("D_host_rds", 3306),
        local_bind_address=("0.0.0.0", 3307)) as server:
    
        conn = MySQLdb.connect(
            user = "D_username",
            passwd = "D_password",
            db = "my_database",
            host = "127.0.0.1",
            port = 3307)
    

    TL;DR:在Python中,我如何通过两个ssh跳转来转发端口?

共有1个答案

景翰音
2023-03-14

我想通了。它结合使用ssh配置设置和sshtunnel库中的SSHTunnelForwarder上下文管理器。

使用以下模型和命名约定:

[A:本地主机]->[B:跳转主机]->[C:目标主机]=>[D:RDS MySQL主机]

Host C_ssh_shortcut
    HostName C_host
    User C_user
    Port 22
    ForwardAgent yes
    ProxyCommand ssh B_user@B_host -W %h:%p
ssh-add
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
 类似资料:
  • 我正在使用IntelliJ社区版和JPA Buddy开发一个Java项目(基于Spring Boot 2.6.x)。我想使用JPA Buddy进行实体实用程序和Liquibase集成。 生产数据库(MySQL 5.7)只能通过ssh隧道访问。 有没有办法使用ssh隧道配置数据库连接?如何从生产数据库生成变更日志? 谢谢米奇

  • 问题内容: 使用ubuntu tusty,在远程计算机上运行了一项服务,我可以通过SSH隧道通过端口转发访问该服务。 我正在运行一个Docker容器。我需要通过主机的隧道从容器内部访问该远程服务。 我尝试使用进行从容器到主机的隧道传输,然后从容器内部通过访问服务失败。为了检查端口映射是否打开,我尝试了 在此之后,parag。2,但即使 在集装箱处也没有察觉的交流 我还尝试通过映射端口,但是这报告绑

  • 我有一个码头集装箱在运行。我需要通过主机的隧道从容器内访问远程服务。 我尝试用从容器中隧道到主机,然后通过从容器中访问服务失败。为了检查端口映射是否打开,我尝试 接下来,帕拉格。2但是,即使在容器上执行也没有感觉到通信 2-测试连接是否正常的快速方法是什么?最好是通过巴什。 谢了。

  • 我希望使用jmx或JSTATD通过ssh隧道(到EC2机器)使用visualvm应用程序。我该怎么做?下面是已经尝试(和失败)的列表:(顺便说一句:如果visual vm不合适,如何在远程计算机上查找内存泄漏?) 我在EC2机器上设置了jstatd服务器(应用程序已经在上面运行),然后在VisualVM中设置了一个将本地端口3333映射到远程端口1099的隧道,我试图在端口3333上使用jstat

  • 我想通过SSH隧道访问jupyter笔记本,并遵循以下方法 要总结-: 1.登录远程机器 2.在新航站楼: 3.然后转到浏览器,然后转到 现在我的问题是:我只能在两个步骤中访问远程机器 jupyter笔记本电脑只安装在我的电脑上。 当我用较长的登录过程替换第一步的第一行时,第二步应该写什么? 当我插入remote_user=username和remote_user=my_pc_name时,我从ju