I'm trying to access a remote server to and pull down data using PyMySQL cursor object. This remote server is on a vendor's AWS account, and is reachable via a Transit Gateway connection to one of my company's public subnets. I have the credentials for the SQL server instance, I have an EC2 that has been whitelisted and the remote network has an access rule that allows connection. Using this EC2 I can successfully execute the an ELT python code and bring over the data that I need.
What I'm trying to do now is use that EC2 as a jump server to connect to the remote sql server from my local machine, but am receiving an error. After feedback in the comments to my original post from @Martin Prikryl, I was directed to Connect to database through double SSH tunnel using Python Paramiko. This code is failing when I try to implement. The first part is to initialize a bastion host via:
from sshtunnel import SSHTunnelForwarder
private_key_path = 'c:\\Users\\*****\\Documents\\****.pem'
private_key = paramiko.RSAKey(filename=private_key_path)
print("Before SSHTunnelForwarder")
with SSHTunnelForwarder(
'bastion_host',
ssh_username="ec2-user", ssh_pkey=private_key,
remote_bind_address=('**.***.***.***', 22),
ssh_private_key_password="") as bastion:
print("Inside SSHTunnelForwarder")
bastion.start()
With the following printed to the terminal:
2023-12-20 12:00:39,390| ERROR | Password is required for key C:\Users\****/.ssh\id_ed25519
Before SSHTunnelForwarder
2023-12-20 12:00:41,698| ERROR | Could not resolve IP address for bastion_host, aborting!
And the following exception raised:
---------------------------------------------------------------------------
BaseSSHTunnelForwarderError Traceback (most recent call last)
Cell In[9], line 9
5 private_key = paramiko.RSAKey(filename=private_key_path)
7 print("Before SSHTunnelForwarder")
----> 9 with SSHTunnelForwarder(
10 'bastion_host',
11 ssh_username="ec2-user", ssh_pkey=private_key,
12 remote_bind_address=('**.***.***.***', 22),
13 ssh_private_key_password="") as bastion:
14 print("Inside SSHTunnelForwarder")
15 bastion.start()
File c:\Users\USERNAME\pyenvironments\DataEng\Lib\site-packages\sshtunnel.py:1608, in SSHTunnelForwarder.__enter__(self)
1606 def __enter__(self):
1607 try:
-> 1608 self.start()
1609 return self
1610 except KeyboardInterrupt:
File c:\Users\USERNAME\pyenvironments\DataEng\Lib\site-packages\sshtunnel.py:1331, in SSHTunnelForwarder.start(self)
1329 self._create_tunnels()
1330 if not self.is_active:
-> 1331 self._raise(BaseSSHTunnelForwarderError,
1332 reason='Could not establish session to SSH gateway')
1333 for _srv in self._server_list:
1334 thread = threading.Thread(
1335 target=self._serve_forever_wrapper,
1336 args=(_srv, ),
1337 name='Srv-{0}'.format(address_to_str(_srv.local_port))
1338 )
File c:\Users\USERNAME\pyenvironments\DataEng\Lib\site-packages\sshtunnel.py:1174, in SSHTunnelForwarder._raise(self, exception, reason)
1172 def _raise(self, exception=BaseSSHTunnelForwarderError, reason=None):
1173 if self._raise_fwd_exc:
-> 1174 raise exception(reason)
1175 else:
1176 self.logger.error(repr(exception(reason)))
BaseSSHTunnelForwarderError: Could not establish session to SSH gateway
Note:
ssh -i "***.pem" ec2-user@ec2-**-***-***-***.compute-1.amazonaws.com
The sshtunnel
discovered another key in the ~/.ssh
folder and it tried to use. As the key is encrypted, and you didn't specify any passphrase, the connection fails. Imo that's wrong behaviour of the library.
To workaround it, set host_pkey_directories
to empty list, to avoid the sshtunnel
automatically trying the keys in the ~/.ssh
folder.
with SSHTunnelForwarder(
'bastion_host',
ssh_username="ec2-user", ssh_pkey=private_key,
remote_bind_address=('**.***.***.***', 22),
ssh_private_key_password="",
host_pkey_directories=[]) as bastion:
From the other error message, it looks like the bastion_host
is not a valid/routable hostname.