Using python 3.10.10 on Windows 10 I am trying to connect to a mongo database via ssh ideally. On the command line I just do
ssh myuser#111.222.333.444
mongo
and I can query the mongo DB. With the following python code
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
HOST = "111.222.333.444"
USER = "myuser"
class Mongo:
def __init__(self):
self.host = HOST
self.user = USER
self.uri = f"mongodb://{self.user}#{self.host}"
def connection(self):
try:
client = MongoClient(self.uri)
client.server_info()
print('Connection Established')
except ConnectionFailure as err:
raise(err)
return client
mongo = Mongo()
mongo.connection()
however I get an error
pymongo.errors.ConfigurationError: A password is required.
But as I am able to just login via ssh using my public key I do not require a password. How can this be solved in python?
I also tried to run a command on the command line using ssh alone like
ssh myuser#111.222.333.444 "mongo;use mydb; show collections"
but this does not work like that either.
You do two different things. In the first command you connect via ssh (using port 22) to the remote server. On the remote server you start the mongo shell. In the second command, you try to connect directly to the mongod server (default port 27017).
In your case myuser is the user on remote server operating system, not the user on the MongoDB.
You can (almost) always connect to a MongoDB without username/password, however when you provide a username then you also need a password. Try
self.uri = f"mongodb://{self.host}"
It is not fully clear what you try to achieve. You can configure MongoDB to logon with x509 certificate instead of username/password, see Use x.509 Certificates to Authenticate Clients. These connections are also encrypted via TLS/SSL.
Or are you looking to configure a SSH-Tunnel? See https://serverfault.com/questions/597765/how-to-connect-to-mongodb-server-via-ssh-tunnel
Here is the solution that I found in the end, as simple as possible, and it can be run from within python, and without any special module to install, from a windows powershell:
import json
import subprocess
cmd_mongo = json.dumps('db.units.find({"UnitId": "971201065"})')
cmd_host = json.dumps(f"mongo mydb --eval {cmd_mongo}")
cmd_local = f"ssh {USER}#{HOST} \"{cmd_host}\""
output = subprocess.check_output(cmd_local, shell=True)
print(output)
Related
I have tried this on both Python2 and Python3, with the same result.
My goal is to ssh into a machine, create a screen session, then ssh into that same machine from within there without being prompted for a password. I'm using localhost currently for testing. When I try this manually, it works as expected. I've tried to reproduce this in code:
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
sshHostConfig = {
"hostname": "localhost"
}
ssh.connect(**sshHostConfig)
s = ssh.get_transport().open_session()
paramiko.agent.AgentRequestHandler(s)
s.exec_command("screen -dmS test")
But when the code is done executing and I connect to the screen session, then try to ssh to localhost, it asks me for a password.
I can see that when I manually ssh, it's using the key from .ssh/authorized_keys. In the debug logging for paramiko, I see
DEBUG:paramiko.transport:Debug msg: b'.ssh/authorized_keys:1: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding'
So I don't understand why I'm seeing a different result if I'm agent forwarding with both and they're both using the key from authorized_keys.
I am trying to ssh to a test cisco router in a test environment using python paramiko, and run cisco commands in that test router.
Everything works great except for 1 small detail.
After running the script I want the ssh session to remain open. (so I can run other commands manually).
I want to keep the ssh session open until I type "exit"
I found another link with a similar issue but I cant understand the solution.
(See here Python ssh - keep connection open after script terminates)
I would appreciate if someone can help me out here
My code
import paramiko
import time
def ssh_session(ip):
try:
session = paramiko.SSHClient() #Open the session
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
session.connect(ip, username = "ciscouser1", password = "password")
connection = session.invoke_shell()
####Running Cisco IOS commands###
connection.send("enable\n")
connection.send("password1") #sending
connection.send("\n")
connection.send("configure terminal\n\n")
time.sleep(1)
connection.send("do show ip int brief\n")
time.sleep(1)
except paramiko.AuthenticationException:
print "wrong credentials"
ssh_session("10.10.10.1")
The session timeout would be controlled by the SSH server. To the best of my knowledge, the only way to keep your session alive on the client side is to not be inactive, which can be accomplished by sending null packets. As to how to do this specifically with paramiko I am not certain. Perhaps you could send some kind of dummy command (or maybe even an empty string?) every so often?
When I try to connect to my postgres server via psycopg2 with a bit of code like this (running python as "username"):
psycopg2.connect(database="apis_master")
I get an error
psycopg2.OperationalError: FATAL: Ident authentication failed for user "username"
But when I run psql straight from the command line (as user "username") like so:
psql -d apis_master
I connect with no problem.
I can't see what is different between these two connection methods. Am I missing some configuration option with psycopg2?
Your command line user and your python user are different. When you instantiate psycopg2 object, pass user credentials:
db = psycopg2.connect(
host = 192.168.0.1, # example IP, use 'localhost' if local, otherwise the IP of the server where Postgre is located.
database = 'apis_master'
user = 'my_db_user',
password = 'my_db_password'
)
This should solve your connection problem.
The problem was that there were two PGSQL instances running on this system. One was 8.4 and not configured to ident with my username, the other was 9.1 and had my username. Command line psql was automatically picking 9.1 running on a non-standard port while psycopg2 was using the default port. Specifying the port in the psycopg2 connection line fixed the problem.
I'm getting a 'need to login' error when trying to interact with my MongoHQ database through python console on heroku:
...
File "/app/.heroku/venv/lib/python2.7/site-packages/pymongo/helpers.py", line 128, in _check_command_response
raise OperationFailure(msg % response["errmsg"])
pymongo.errors.OperationFailure: command SON([('listDatabases', 1)]) failed: need to login
My applicable code
app/init.py:
from mongoengine import connect
import settings
db = connect(settings.DB, host=settings.DB_HOST, port=settings.DB_PORT, username=settings.DB_USER, password=settings.DB_PASS)
app/settings.py:
if 'MONGOHQ_URL' in os.environ:
url = urlparse(os.environ['MONGOHQ_URL'])
DB = url.path[1:]
DB_HOST = url.hostname
DB_PORT = url.port
DB_USER = url.username
DB_PASS = url.password
os.environ['MONGOHQ_URL'] looks like:
'mongodb://[username]:[password]#[host]:[port]/[db-name]'
This code works (connects and can read and write to mongodb) both locally and from the heroku web server.
According to the docs (http://www.mongodb.org/display/DOCS/Connections), it should at make a 'login' attempt on connection to the server as long as the username and password params are passed to Connection or parseable from the URI. I couldn't think of a way to see if the login attempt was being made and failing silently.
I've tried bypassing mongoengine and using pymongo.Connection and got the same result. I tried all of the several patterns of using the Connection method. I created a new database user, different from the one mongoHQ creates for heroku's production access -> same same.
It's a flask app, but I don't think any app code is being touched.
Update
I found a solution, but it will cause some headaches. I can manually connect to the database by
conn = connect(settings.DB, host=settings.DB_HOST, port=settings.DB_PORT, username=settings.DB_USER, password=settings.DB_PASS)
db = conn[settings.DB]
db.authenticate(settings.DB_USER, settings.DB_PASS)
Update #2
Mongolab just worked out of the box.
Please use the URI method for connecting and pass the information to via the host kwarg eg:
connect("testdb_uri", host='mongodb://username:password#localhost/mongoenginetest')
MongoHQ add-on uses password hashes not actual passwords and that's perhaps the error.
You should change the environment variable MONGOHQ_URL to a real password with the following command:
heroku config:set MONGOHQ_URL=mongodb://...
Once set, you may restart your applications (heroku apps) so the change gets picked up. If you're in the directory of the failing application, config:seting the config var will restart the application.
I am trying to connect to MSSQL server using pyodbc. I can connect to the server and query it using the basic authentication mode as:
connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=**;PWD=****")
Connection to MSSQL can also be done using Windows Authentication where it takes the parameters
DOMAIN
USERNAME
PASSWORD
I don't know how to use this sort of credential from pyodbc to connect to the MSSQL Server.
Furthermore, the ODBC driver I am using (Easysoft ODBC-SQL Server) needs licensing. Don't we get such drivers for free?
The Easysoft SQL Server driver parameters to use NTLM authentication are
Trusted_Domain=<domain name>
NTLMv2=Yes|No
Trusted_Connection=Yes|No
And UID, PWD as usual.
NTLM can also be triggered simply using a UID that looks like
DOMAIN\USER
If you want to use Kerberous, the following can be set
ServerSPN=SPN
Its all the the user guide for the driver
connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=;PWD=**")
The string part of the connection is what is known as a DSN-Less connection so you can pass in any of the attributes required for example :-
connection = pyodbc.connect("DRIVER={Easysoft ODBC-SQL Server};SERVER=192.168.2.119;DATABASE=dbame;UID=MyWindowsUserName;PWD=MyPassword;Trusted_Domain=MyWindowsDomainName;Trusted_Connection=1")
Trusted_Connection = 1 tells the Easysoft driver that you intend to use the Trusted_Domain, user ( UID ) and password ( PWD ) to login to SQL Server.
For a full list of all the attributes available within the Easysoft ODBC-SQL Server Driver please read the Attributes section of the manual.