Я пытаюсь написать скрипт на python, который подключается к базе данных, но эта база данных доступна только в том случае, если вы впервые подключитесь к хосту бастиона. Из командной строки вот что мне нужно сделать для настройки туннеля:
$ 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 ~]$
Я создал скрипт Python, используя эту библиотеку sshtunnel , чтобы сделать то же самое. Работает:
#!/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, он отправит push-уведомление на мой телефон 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")
Как мне написать скрипт на python для подключения к базе данных MySQL через SSH-туннель, если для sshing на этот хост требуется 2FA ??