2016-11-16 1 views
1

Amazon RDS ("D")에서 호스팅되는 원격 MySQL 데이터베이스가 있습니다. 보안을 위해 원격 서버 ("C")를 통해서만 액세스 할 수 있습니다. C는 점프 호스트 "B"를 통해 ssh를 통해 액세스 할 수 있습니다. 원격 SQL 호스트에 액세스하려면 이중 ssh 터널이 필요합니다.점프 호스트 및 원격 데이터베이스를 사용하는 SSH 터널 전달

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

내가 paramiko 및/또는 sshtunnel를 사용하여, 파이썬을 통해 D에 접근하고 싶습니다. 내가 찾을 수있는 모든 정보는 포함한다 :

지금까지 내가 C. A에서 얻을 수있는 프록시 명령 paramiko을 사용하고 내가 명령을 실행하여 D에 액세스 할 수 있습니다 mysqldb 또는 sqlalchemy (내 궁극적 인 목표)로 연결하는 것이 아니라 C에서.

내 현재 코드 :

import paramiko 

ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
proxy = paramiko.ProxyCommand("ssh -A [email protected]_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 docs 예 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 : 어떻게 앞으로 내가 할 파이썬에서 두 개의 ssh 점프를 통한 포트?

답변

2

나는 그것을 알아 냈다. 이것은 sshtunnel 라이브러리의 ssh 구성 설정과 SSHTunnelForwarder 컨텍스트 관리자의 조합으로 작동합니다.

Using the following model and naming conventions :

내가 B를 통해 C A에서 얻을 수있는 내 ~/스푸핑/설정을 설정

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

:

I 키를 추가
Host C_ssh_shortcut 
    HostName C_host 
    User C_user 
    Port 22 
    ForwardAgent yes 
    ProxyCommand ssh [email protected]_host -W %h:%p 

/키는 내가 사용 B와 C에 내 ssh-agent에 로그인하십시오.

ssh-add 

그리고 마지막으로 저는 P는 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:[email protected]: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 

, 내 데이터베이스와 상호 작용하는 평소와 같이 나의 엔진을 사용할 수있게되었습니다.

0

해결책을 찾아 냈습니까? 그렇다면 게시 할 수 있습니까?

저는 현재 이와 같은 작업을하고 있으며 포트 포워딩과 관련된 몇 가지 아이디어가 있습니다. 예를 들어 ~ ~ .ssh/config 파일에는 다음과 같은 내용이 있습니다. 이렇게하면 포트 전달을 사용하여 즉 중간에서 처음으로 ssh 할 필요없이 중간을 통해 내 로컬에서 원격으로 직접 ssh 할 수 있습니다.

이제 터미널에서 ssh를 통해 내 로컬에서 원격으로 연결할 수 있습니다. 이제 프로그래밍 방식으로 내 로컬에서 원격으로 직접 터널링 작업을하고 있습니다. 파이썬과 내 ssh 설정 파일이 훌륭하게 작동하고 포트 포워딩 트릭을 사용할 수 있기를 바라고 있습니다. 이 코드를 작동 시키면 코드를 따르게됩니다.

은 (난 당신이 리눅스 나 맥 OS에. 나는 윈도우가 SSH 키와 설정 파일을 처리하는 방법을 모르겠어요있어 가정합니다.)

Host remote 
    HostName <remote_host.org> 
    User <username> 
    Port 22 
    ForwardAgent yes 
    ProxyCommand ssh <intermediate> nc %h %p 

Host intermediate 
    HostName <intermediate_host.org> 
    User <username> 
# IdentityFile ~/.ssh/id_rsa 
    ControlMaster auto 
    ControlPath ~/.ssh/master-%[email protected]%h:%p 
    ControlPersist 30m 
+1

[대답] (https://stackoverflow.com/a/44739471/6412017)을 알아 냈습니다. – blep

관련 문제