如何使用2FA进行python SSH隧道?

问题描述 投票:4回答:1

我正在尝试编写一个连接到数据库的python脚本,但只有在首次SSH到堡垒主机时才能访问该数据库。从命令行,这是我设置隧道所要做的:

$ ssh -i /path/to/my/key/file.pem -A -L 3307:mydb1.fsd23rqr.us-east-1.rds.amazonaws.com:3306 [email protected]
[ec2-user@ip-X-X-X-X ~]$ 

我用这个sshtunnel library创建了一个python脚本来做同样的事情。有用:

#!/usr/bin/env python
from sshtunnel import SSHTunnelForwarder
import MySQLdb as db
import pandas as pd

print('\nAbout to try connecting')
with SSHTunnelForwarder(
    ('my-ssh-host.without.2fa', 22),
    ssh_username='my_ssh_username1',
    ssh_pkey='/path/to/my/key/file.pem',
    remote_bind_address=('mydb1.fsd23rqr.us-east-1.rds.amazonaws.com', 3306),
    local_bind_address=('0.0.0.0', 3307)
) as tunnel:
    print "Connection Established"
    print pd.read_sql_query(
        "select 'Hello' from dual",
        db.connect(
            host='127.0.0.1',
            port=tunnel.local_bind_port,
            user='my_db_username1',
            passwd='****************',
            db='my_db_instance_1'
        )
    )

生产:

About to try connecting
Connection Established
   Hello
0  Hello

但现在我需要使用不同的DB和堡垒组合。这个堡垒有2因素认证(2FA)设置,所以当我ssh到它时,它会问我选择2FA的哪种方法。如果我选择方法#1,它会向我的Android手机发送推送通知,我必须批准:

$ ssh -i /path/to/my/key/rsa -A -L 3307:mydb2.fsd23rqr.us-east-1.rds.amazonaws.com:3306 [email protected]
Duo two-factor login for my_ssh_username2

Enter a passcode or select one of the following options:

 1. Duo Push to XXX-XXX-9671
 2. Phone call to XXX-XXX-9671
 3. SMS passcodes to XXX-XXX-9671 (next code starts with: 1)


Passcode or option (1-3): 1

<WAIT FOR ME TO CLICK APPROVE ON MY ANDROID>

Success. Logging you in...
[my_ssh_username2@ip-X-X-X-1X ~]$

但是当我尝试使用sshtunnel设置隧道时,与启用2FA的堡垒完全相同,它失败了:

About to try connecting
Connection Established
Enter DB password:
2018-08-29 15:31:43,985| ERROR   | Could not establish connection from ('127.0.0.1', 3307) to remote side of the tunnel
Traceback (most recent call last):
  <stack-trace snipped>
  File "python2.7/site-packages/MySQLdb/__init__.py", line 81, in Connect
    return Connection(*args, **kwargs)
  File "python2.7/site-packages/MySQLdb/connections.py", line 193, in __init__
    super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (2013, "Lost connection to MySQL server at 'reading initial communication packet', system error: 0")

如果sshing到该主机需要2FA,我怎么能写一个python脚本通过SSH隧道连接到Mysql数据库?

python ssh-tunnel multi-factor multi-factor-authentication
1个回答
0
投票

您需要设置交互式SSH会话才能输入启用2fa的服务器提供的选项。简要介绍一下sshtunnel库的代码 - 似乎他们使用paramiko library连接到网关以及设置隧道。实现这两者的方法没有为用户输入提供交互式tty的选项。

例如,执行网关连接的方法说:

def _connect_to_gateway(self):
    Open connection to SSH gateway
     - First try with all keys loaded from an SSH agent (if allowed)
     - Then with those passed directly or read from ~/.ssh/config
     - As last resort, try with a provided password

如您所见,此处无法执行交互式ssh会话命令。

因此,您可以选择使用paramiko扩展代码以设置交互式会话,或使用paramiko编写自己的代码来管理网关连接和隧道设置。例如,paramiko提供this example来执行交互式会话。

© www.soinside.com 2019 - 2024. All rights reserved.