【问题标题】:Python SSHTunnel w/ Paramiko - CLI works, but not in script带有 Paramiko 的 Python SSHTunnel - CLI 有效,但不在脚本中
【发布时间】:2017-02-18 02:34:40
【问题描述】:

上下文:
我正在尝试通过 SSH 和 Python 连接到远程 MySQL 安装。我正在使用 paramiko 和 SSHTunnel,目前在 py 2.7 上。

我已经成功地使用 bash shell、paramiko 的 forward.py 甚至 SSHTunnel 的 CLI 命令连接和查询远程数据库中的记录。

问题:
在尝试将其迁移到将创建隧道并查询结果的单个脚本时,我遇到了问题。问题似乎与我对 SSHTunnel 语法的格式/结构有关。

这是我用来在shell上打开隧道的:

ssh -p SSH_PORT SSH_USER@SERVER_IP -L 33060:127.0.0.1:3306

这是我用 paramiko 的 forward.py 打开的:

python t_forward.py SERVER_IP:SSH_PORT -r 3306 -u SSH_USER -p 33060 -K "/PATH/TO/PRIVATE/KEY"

注意:我目前使用的密钥没有密码(用于测试/开发目的)

这是我以前用SSHTunnel的命令行打开的:

python -m sshtunnel -U SSH_USER -L :33060 -R 127.0.0.1:3306 -p SSH_PORT SERVER_IP -K "/PATH/TO/PRIVATE/KEY"

如上所述,所有这些都正常工作,并且我使用 MySQLdb 连接到数据库并检索记录的 py 脚本工作正常。

当我尝试将 SSH 连接字符串添加到脚本中时,事情就出现了问题。这是它目前的样子:

server = SSHTunnelForwarder(
    ('SERVER_IP', SSH_PORT),
    ssh_username='SSH_USER',
    ssh_pkey='/PATH/TO/PRIVATE/KEY',
    remote_bind_address=('127.0.0.1', 3306),
    local_bind_address=('0.0.0.0', 33060)
)

MYSQL 连接线如下所示:

con = MySQLdb.connect(user='MYSQLDBUSER',passwd='MYSQLDBUSERPASS',db='DATABASE',host='127.0.0.1', port=33060)

鉴于我能够通过 BASH 以及 forward.py 和 SSHTunnel 的 CLI 进行连接,这似乎不是服务器上的问题,而是我的 SSHTunnelForwarder 格式不正确。

错误信息:

Could not establish connection from ('127.0.0.1', 33060) to remote side of the tunnel

查看服务器上的 var/log/auth.log,我看到它能够连接,只是当 MySQLDB.connect 启动时它似乎崩溃了。

收到此错误时的 auth.log 消息:

Oct  9 17:36:31 HOSTSERVER sshd[21141]: Accepted publickey for SSH_USER from SOURCE_IP port 32918 ssh2: RSA <LONG KEY>
Oct  9 17:36:31 HOSTSERVER sshd[21141]: pam_unix(sshd:session): session opened for user SSH_USER by (uid=0)
Oct  9 17:36:31 HOSTSERVER systemd-logind[1217]: New session 144 of user SSH_USER.
Oct  9 17:36:32 HOSTSERVER sshd[21141]: pam_unix(sshd:session): session closed for user SSH_USER

我使用 SSHTunnel CLI 时的 auth.log 消息(并且结果有效):

Oct  9 17:39:33 HOSTSERVER sshd[21625]: Accepted publickey for SSH_USER from SOURCE_IP port 44132 ssh2: RSA <LONG KEY>
Oct  9 17:39:33 HOSTSERVER sshd[21625]: pam_unix(sshd:session): session opened for user SSH_USER by (uid=0)
Oct  9 17:39:33 HOSTSERVER systemd-logind[1217]: Removed session 144.
Oct  9 17:39:33 HOSTSERVER systemd-logind[1217]: New session 145 of user SSH_USER.

我似乎在这里遗漏了一些非常基本的东西......任何帮助将不胜感激。

【问题讨论】:

  • "正在查看服务器上的 var/log/auth.log..." 与此相关的服务器端日志中出现了哪些实际消息?请edit你的问题包括他们。
  • 谢谢肯斯特。我添加了日志中的结果。唯一不同的是,在它不起作用的情况下,连接会关闭。我不知道在 MySQLDB 连接器尝试连接到数据库之前是否会发生这种情况。

标签: python mysql ssh


【解决方案1】:

找到答案了!

原来脚本在连接建立之前继续执行。因此 MySQLDB 会在隧道完全建立之前尝试连接到端口映射。

一个简单的:

import time
...
sleep(1)
...

成功了。

就我而言,我在“server.start()”之后和需要访问远程数据库的代码之前添加了 sleep(1)。

感谢 @kenster 让我更仔细地查看 auth.log,这让我更仔细地考虑时间安排。

【讨论】:

  • 对 SEO 的一点评论。使用多处理库时我遇到了同样的问题。连接发生得如此之快,以至于单个端口被分配给多个隧道,因此产生了连接错误。我用你提到的方法解决了。谢谢!
猜你喜欢
  • 2021-09-09
  • 2017-10-12
  • 2017-10-29
  • 2022-12-10
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 2013-02-07
相关资源
最近更新 更多