4

I have been attempting to SSH tunnel into an EC2 instance and connect to DocumentDB that is located in the same VPC. I've tried all of the solutions I could dig up online with no luck. I am using the ssh_pymongo module, which wraps SSHTunnelForwarder. I am able to SSH directly into the EC2 instance and connect to the DocumentDB cluster. I'm trying to achieve this same thing via python.

Example code:

from ssh_pymongo import MongoSession

session = MongoSession(
    host='ec2-x-x-x-x.region.compute.amazonaws.com',
    port=22,
    user='ec2-user', # The user ec2-user is specific to EC2 instance OS Amazon Linux 2
    key='key.pem',
    uri='mongodb://<username>:<password>@xxxxx-docdb-cluster.cluster-xxxxxxxxxxxxx.region.docdb.amazonaws.com:27017'
)

# Note for the above function call: I've also tried various combinations of the to_host and to_port params without success.

db = session.connection['db-name']

print(db.collection_names())

Error:

Could not establish connection from local ('127.0.0.1', 36267) to remote ('xxxxx-docdb-cluster.cluster-xxxxxxxxxxxx.region.docdb.amazonaws.com', 27017) side of the tunnel: open new channel ssh error: Timeout opening channel.
4
  • What exactly have you tried? What errors do you get? Commented Nov 13, 2020 at 21:34
  • @Marcin Ah my apologies, let me add that info to the original question. Commented Nov 13, 2020 at 21:35
  • Timeout often means problem with security groups. Can you double check them or show them? Commented Nov 13, 2020 at 21:55
  • @Marcin Security groups aren't the issue, as SSH is open to all, additionally I'm able to SSH manually from the same system. Commented Nov 13, 2020 at 22:05

2 Answers 2

4

I also tried the ssh_pymongo module but was unsuccessful. However I tried directly with the sshtunnel module and I was able to query my database.

Here is my code

from sshtunnel import SSHTunnelForwarder
from pymongo import MongoClient

# VM IP/DNS - Will depend on your VM
EC2_URL = '''*.*.compute.amazonaws.com'''

# Mongo URI Will depende on your DocDB instances
DB_URI = '''dbname.*.*.docdb.amazonaws.com'''

# DB user and password
DB_USER = 'dbuser'
DB_PASS = 'dbpassword'

# Create the tunnel
server = SSHTunnelForwarder(
    (EC2_URL, 22),
    ssh_username='ubuntu',                # I used an Ubuntu VM, it will be ec2-user for you
    ssh_pkey='~/.ssh/keypair.pem',   # I had to give the full path of the keyfile here
    remote_bind_address=(DB_URI, 27017),
    local_bind_address=('127.0.0.1', 27017)
)
# Start the tunnel
server.start()

# Connect to Database
client = MongoClient(
    host='127.0.0.1',
    port=27017,
    username='DB_USER',
    password='DB_PASS'
)


# Close the tunnel once you are done
server.stop()
Sign up to request clarification or add additional context in comments.

Comments

1

kept getting this error

pymongo.errors.ServerSelectionTimeoutError: SSL handshake failed: document_db_server:27017: 
[Errno 54] Connection reset by peer,SSL handshake failed: document_db_server:27017: 
[Errno 54] Connection reset by peer, Timeout: 2.0s, Topology Description: 
<TopologyDescription id: 63121b21cc3688a700cc86f9, topology_type: ReplicaSetNoPrimary, 
servers: [<ServerDescription ('document_db_server', 27017) server_type: Unknown, rtt: None>, 
<ServerDescription ('document_db_server', 27017) 
server_type: Unknown, rtt: None, error=AutoReconnect('SSL handshake failed: document_db_server:27017: 
[Errno 54] Connection reset by peer')>, <ServerDescription ('document_db_server', 27017) 
server_type: Unknown, rtt: None, error=AutoReconnect('SSL handshake failed: document_db_server:27017: 
[Errno 54] Connection reset by peer')>]>

the solution was to add directConnection=True to MongoClient

port = 27017
server = SSHTunnelForwarder(
            (ec2_ip, 22),
            ssh_username=ec2_user,
            ssh_pkey=ec2_pem_key,
            remote_bind_address=(document_db_server, port),
            local_bind_address=('127.0.0.1', port)

        )
server.skip_tunnel_checkup = False
server.start()
server.check_tunnels()
print(f"Tunnel is Up {server.tunnel_is_up}")
print(f"Local is up {server.local_is_up(('0.0.0.0', port))}")
print('---------------TUNNEL IS ESTABLISHED----------------')

"""DOCUMENT DB CONNECTION"""
client = pymongo.MongoClient(
        host="mongodb://127.0.0.1:27017/?",
        tls=True,
        username=documentdb_user,
        password=documentdb_password,
        authMechanism="SCRAM-SHA-1",
        tlsCAFile=document_db_ca_pem_file,
        tlsAllowInvalidHostnames=True,
        timeoutMS=10000,
        directConnection=True
      )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.