我正在尝试编写一个连接数据库的python脚本,但是仅当您首先通过SSH连接到堡垒主机时,该数据库才可访问。在命令行中,这是设置隧道所要做的:
$ ssh -i /path/to/my/key/file.pem -A -L 3307:mydb1.fsd23rqr.us-east-1.rds.amazonaws.com:3306 my_ssh_username1@my-bastion-host.without.2fa
[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
但是现在我需要使用不同的数据库和堡垒组合。该堡垒具有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 my_ssh_username2@my-bash-host.with.2fa
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")
如果通过SSH隧道连接到主机需要2FA,我如何编写python脚本以通过SSH隧道连接到Mysql DB?
答案 0 :(得分: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来执行交互式会话。