PyMongo MongoClient SSH Connection - python

I'm trying to establish a connection with a MongoDB database via an SSH connection programmatically from python. I can create a MongoClient object to connect locally but I can't see how to establish an SSH connection for my MongoClient to use.
How would I do this?

First make sure you have no local MongoDB running on your machine, then ssh to the server where MongoDB is running:
ssh -L 27017:MYHOST:27017 MYUSER#MYHOST
Replace MYUSER and MYHOST with your username and host. Then, in another terminal window, run the "mongo" shell from your local computer. By default it connects to localhost:27017, which you've port-forwarded to the remote host. The "mongo" shell should connect correctly.
Then, create a PyMongo connection normally in Python:
>>> from pymongo import MongoClient
>>> c = MongoClient()
>>> c.test.command('buildinfo')
...
More info about SSH tunneling here:
https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding
This is not MongoDB-specific at all, any network protocol can be tunneled with SSH port-forwarding.

Related

Fabric2 throws `paramiko.ssh_exception.AuthenticationException` during nested SSH to localhost (port 2022) on an AWS EC2 instance

Here is what I am trying to achieve:
SSH into an EC2 instance Node1.
Public IP is available for Node1.
I am using a .pem file to create Connection with Node1.
From Node1 ssh into localhost on port 2022: ssh admin#localhost -p 2022
Now execute a command, while inside localhost.
Here is the code snippet I am using:
from fabric2 import Connection
jump_host_ip = "A.B.C.D"
user = "root_user"
pem_key = "example.pem"
with Connection(jump_host_ip, user=user, connect_kwargs={"key_filename": pem_key}) as jump_host:
with Connection('localhost', user='dummy_user', port=2022,
connect_kwargs={'password': 'password'}, gateway=jump_host) as local_host:
local_host.run('ls -la')
This code is hosted on another EC2 server. And when executed from the EC2 server it throws the following exception:
paramiko.ssh_exception.AuthenticationException: Authentication failed.
But this code works when executed from a local machine (not from EC2 server).
Is it possible EC2 could be blocking the Connection to localhost through gateway ?
If yes, what should be the fix for this ?

PyMongo - can't connect to localhost?

I have tried running the following:
import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client.test_database
collection = db.test_collection
collection.find_one()
but I get
ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused
Any suggestions on how to fix this? I am running this behind a corporate proxy, but have already set environment variables for that in .bashrc.
EDIT
If I run mongo from the terminal, I get
$ mongo
MongoDB shell version v4.0.13
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2019-10-16T10:30:23.269+0100 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect#src/mongo/shell/mongo.js:344:17
#(connect):2:6
exception: connect failed
Its look like you didn't run any mongo instance on your machine
run the command mongod -f <config_file> and then test it again (this may needs a sudo permissions)

Connecting to Amazon rds with Python

Using MySQL Workbench, I can connect mysql running on amazon rds. I supply SSH Hostname, SSH Username, SSH Password, SSH Key File, MySQL Hostname, MySQL Server Port, Username, and Password.
However, I have a python script with which I'd like to connect to this same database. I tried using ssh tunneling:
with SSHTunnelForwarder(
(SSH Hostname, 22),
ssh_password=SSH Password,
ssh_username=SSH Username,
ssh_pkey= SSH Key File path,
remote_bind_address=(MySQL Hostname, MySQL Port) as server:
conn = MySQLdb.connect(
host = MySQL Hostname,
port = MySQL Port,
user = Username,
passwd = Password)
When I run the script, it hangs for about a minute, then says
'Can't connect to MySQL server on ~MySQL Hostname~'
I am unsure about the remote_bind_address. Since I don't supply that info when successfully connecting from MySQLWorkbench, is there a way to connect from Python without specifying remote_bind_address?
Additionally, I tried using the scripting tool in MySQL Workbench. I am able to load my python script, but then an error occurs at one of my imports, specifically 'import module requests'. The error indicates there is no module named requests. However, this module has been installed for a while, and I have imported and successfully used it outside of MySQL Workbench.

Connection Error while connecting to PostgreSQL as postgres user?

I am not able connect to PostgreSQL remotely using python and psycopg2:
Here is my code.
>>> import psycopg2
>>> conn_string = "host='localhost' dbname='mydb' user='postgres'"
>>> print "Connecting to database\n ->%s" % (conn_string)
Connecting to database
->host='localhost' dbname='mydb' user='postgres'
>>> conn = psycopg2.connect(conn_string)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/tools/lib/python2.7/site-packages/psycopg2/__init__.py", line 164, in connect
conn = _connect(dsn, connection_factory=connection_factory, async=async)
psycopg2.OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
The password is not set for postgres user.
Generally, I can connect to database by running following method on host.
1. SSH to box
2. su - postgres
3. psql
4. \c mydb
The server runs PostgreSQL 9.1.
You're trying to connect to PostgreSQL on localhost using a script running on your computer, but there's no PostgreSQL server running there.
For this to work, you'd have to ssh to the remote server, then run your Python script there, where the PostgreSQL server is "local" relative to the Python script.
(That's why running psql works - because you're running it on the remote server, where PostgreSQL is "local" relative to psql).
Alternately, you could:
Use an SSH tunnel to forward the PostgreSQL port from the local computer to the remote one; or
Connect directly over TCP/IP to the remote PostgreSQL server using its host name or IP address, after enabling remote connections on the server.
Note that just putting the server's IP address or host name into the connection string instead of localhost will not work unless you also configure the server to accept remote connections. You must set listen_addresses to listen for non-local connections, add any required firewall rules, set pg_hba.conf to permit connections from remote machines, and preferably set up SSL. All this is covered in the Client Authentication chapter of the PostgreSQL user manual.
You'll probably find an SSH tunnel simpler and easier to understand.

How to define same MongoClient for local and docker application?

In order to communicate with MongoDB from Flask, I use the following code to define the connection :
CLIENT = pymongo.MongoClient('mongodb://localhost:27017/')
Everything works fine but once I'm trying to deploy my application on Docker I get the following error:
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused
To solve this problem, I can replace the previous code by:
import os
client = MongoClient(os.environ['DB_PORT_27017_TCP_ADDR'],27017)
But then it only works on Docker and not on my local machine.
How can I define the connection in order to make it work on both Docker and my local machine ?
You can specify that if DB_PORT_27017_TCP_ADDR environment variable is present, use that; else use localhost using something like this:
import os
client = MongoClient(os.environ.get('DB_PORT_27017_TCP_ADDR') or 'localhost', 27017)

Categories