Ident connection fails via psycopg2 but works via command line - python

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.

Related

How to connect to a mongo DB via SSH using Python?

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)

Connection to remote mysql server through ssh using python mysqldb connector passwordless

Python 3.8
Mysql 8.0.23-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu))
Hi,
I want to connect to a distant mysql server using python's mysqldb connector and paramiko's sshtunnelforwarder.
I can connect to the database remotely without any problems by executing the following:
Connecting to database using mysql password authentication
server = new_ssh_server(config)
with server:
print('Connection', server.local_bind_address)
cnx = MySQLdb.connect(host = '127.0.0.1',
port = server.local_bind_port,
user = config['user'],
passwd = config['password'],
db = config['db'])
Queries work, I can read/write to database, no problem.
I would like to connect to database without supplying mysql password, by using mysql auth_socket authentication method, through ssh.
My attempts at this can be resumed by the following code:
Connecting to database using mysql auth_socket authentication
with server as tunnel:
print('Tunnel:', tunnel.local_bind_address)
cnx = MySQLdb.connect(host = 'localhost', user = 'hillbilly', password = '', db='tutut')#, unix_socket="/tmp/mysql.sock")
res = pd.read_sql('select * from users;', cnx)
print(res)
Which throws the following error:
File "connect_ssh_mysql_auth_socket.py", line 12, in <module>
cnx = MySQLdb.connect(host = 'localhost', user = 'hillbilly', password = '', db='rsotest2')#, unix_socket="/tmp/mysql.sock")
File "...../lib/python3.8/site-packages/MySQLdb/__init__.py", line 84, in Connect
return Connection(*args, **kwargs)
File "...../lib/python3.8/site-packages/MySQLdb/connections.py", line 179, in __init__
super(Connection, self).__init__(*args, **kwargs2)
MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)")
I have and existing mysqld.sock on the distant server that I symlinked to /tmp/mysql.sock, but the error remains. I have also added the next line to /etc/mysql/mysql.conf.d/mysql.cnf:
socket=/run/mysqld/mysqld.sock
But I still get the same error when trying to connect remotely.
Specifying the unix_socket='/run/mysqld/mysqld.sock' to mysqldb connector (commented in Connecting to database using mysql auth_socket authentication) does not fix the issue.
I seem to misunderstand the use of mysql.sock, mysqld.sock.
I was not able to find nor create a mysql.sock socket.
Is what I am trying to do possible? I remember reading somewhere that unix sockets only work locally, does this mean it is not achievable?
Any help/explanation would be appreciated.
(EDIT AND CLOSING)
So this is not possible. Following this thread, auth_socket needs local access to the socket file (usually /tmp/mysql.sock) to run autentication tests, so not accessible through ssh tunneling.
Authentication to remote mysql server using auth_socket plugin is not possible through sshtunnel, as the plugin requires local access to the socket file. See this thread for more information.

Django setting : psycopg2.OperationalError: FATAL: Peer authentication failed for user "indivo"

I am getting problem in Django project setting with POSTGRESQL.
Here is my setting.py database setting
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql_psycopg2', # '.postgresql_psycopg2', '.mysql', or '.oracle'
'NAME':'indivo', # Required to be non-empty string
'USER':'indivo', # Required to be non-empty string
'PASSWORD':'ritvik',
'HOST':'', # Set to empty string for localhost.
'PORT':'', # Set to empty string for default.
},
}
Now in postgres backend what I have done is .
rohit#rohit-desktop:~$ sudo su - postgres
postgres#rohit-desktop:~$ createuser --superuser indivo # create a super user indivo
postgres#rohit-desktop:~$ psql # open psql terminal
psql (9.1.8)
Type "help" for help.
postgres=# \password indivo # set the password ritvik
Enter new password:
Enter it again:
postgres=# \q #logout
postgres#rohit-desktop:~$ createdb -U indivo -O indivo indivo #create db indivo
Unfortunately when i am trying to syncdb I am getting the error .
psycopg2.OperationalError: FATAL: Peer authentication failed for user "indivo"
Please help me out what might I am doing wrong here .
I have similar problem and solved it with this answer by adding localhost to the database HOST settings in settings.py, so your database settings should look like this:
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql_psycopg2', # '.postgresql_psycopg2', '.mysql', or '.oracle'
'NAME':'indivo', # Required to be non-empty string
'USER':'indivo', # Required to be non-empty string
'PASSWORD':'ritvik',
'HOST':'localhost', # <- Changed from empty string to localhost
'PORT':'', # Set to empty string for default.
},
}
By default in many Linux distros, client authentication is set to "peer" for Unix socket connections to the DB. This is set in the pg_hba.conf config file for postgresql. The psycopg2 python library documentation states:
- *host*: database host address (defaults to UNIX socket if not provided)
So if you leave the host option blank, your script will try to connect and use the Unix username:password for authentication. To fix, you can either:
set the "host" option explicitly to 127.0.0.1 into the config code you pasted into your question.
Modify the pg_hba.conf file to use md5 for socket connections so it uses usernames and passwords stored in the postrgres DB user store (not recommended as this may break authentication for system users)
You need to set pg_hba.conf to use md5 authentication for the user, db and source IP of interest. See the client authentication chapter of the documentation.
Search for pg_hba.conf on Stack Overflow for tons more information.
I too was facing similar problem during setting up postgresql database with Django project.
My System is running RHEL CentOS 7 with postgresql version 10. I search a lot but couldnot find actually what is happening until I saw log at /var/lib/pqsql/10/data/log/postgresql*.log
2017-11-10 00:31:40.499 IST [14129] DETAIL: Connection matched pg_hba.conf line 85: "host all all ::1/128 ident"
So I just changed that particular line in file /var/lib/pgsql/10/data/pg_hba.conf :
from
host all all ::1/128 ident
to
host all all ::1/128 md5
with that I am able to create database & table using manage.py migrate
Thanks for all who has helped me to find this solution. especially #juliocesar and official documentation for postgresql client authentication

How to connect to remote mysql server in python

Hi i have a requirement where i need to connect to remote mysql server. My application shall be running on local machine and my mysql will be running on remote server.I have tried the following code:
DB = 'gts'
DB_HOST = 'ps95074.dreamhost.com'
DB_USER = 'root'
DB_PASSWORD = 'dbadminpassword'
conn = MySQLdb.Connection(db=DB, host=DB_HOST, user=DB_USER,passwd=DB_PASSWORD)
cursor = conn.cursor()
But i am getting the following error
OperationalError: (2005, "Unknown MySQL server host 'ps95074.dreamhost.com' (1)")
Instead if i use
DB_HOST='localhost'
Everything works fine. How can same be possible with remote host.Any help shall be appreciated.
Check your firewall. That server is online and available from any machines:
> mysql -h ps95074.dreamhost.com
ERROR 1045 (28000): Access denied for user 'myuser'#'myhost' (using password: NO)
However, even if you can connect chances are good that your database user only allows local connections.
Update: I just tried it again and now it also fails using the commandline client. So clearly something is wrong with your server.

PyMySQL can't connect to MySQL on localhost

I'm trying to connect to MySQL on localhost using PyMySQL:
import pymysql
conn = pymysql.connect(db='base', user='root', passwd='pwd', host='localhost')
but (both on Python 2.7 and Python 3.2) I get the error:
socket.error: [Errno 111] Connection refused
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (111)")
I'm sure mysqld is running because I can connect using mysql command or phpMyAdmin. Moreover, I can connect using MySQLdb on Python 2 with nearly the same code:
import MySQLdb
conn = MySQLdb.connect(db='base', user='root', passwd='pwd', host='localhost')
It seems that the problem is on PyMySQL side rather than MySQL but I have no idea how to solve it.
Two guesses:
Run mysqladmin variables | grep socket to get where the socket is located, and try setting up a connection like so:
pymysql.connect(db='base', user='root', passwd='pwd', unix_socket="/tmp/mysql.sock")
Run mysqladmin variables | grep port and verify that the port is 3306. If not, you can set the port manually like so:
pymysql.connect(db='base', user='root', passwd='pwd', host='localhost', port=XXXX)
Seems like changing localhost to 127.0.0.1 fixes the error, at least in my configuration.
If it doesn't, I would look for errors in tcp sockets connection and, of course, post it as a bug in pymysql bugtrack.
I solved the issue by replacing localhost with 127.0.0.1 and changing the password to my MYSQL database password as shown below;
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
passwd = 'XXXXXXXXX',
db = 'mysql'
)
I met the same question and my solution is as follows:
Run ssh -fN -L 3307:mysql_host:3306 ssh_user#ssh_host in my terminal.
Then input your ssh password
conn = pymysql.connect(db='base', user='root', passwd='pwd', host='localhost')
This error occurs because database does not support link directly.
I asked why socket worked but not TCP and the answer was that bind-address in /etc/my.cnf was not set correctly. This could be your problem too since the socket methods works just fine but the TCP one does not.
Those who are strugging to connect localhost MySQL from dockerised flask-sqlalchemy or using pymysql, pls look into this thread, very usefull How to connect locally hosted MySQL database with the docker container
This worked for me:
import pymysql
db = pymysql.connect(host="localhost",port=8889,user="root",passwd="root")
cursor=db.cursor()
cursor.execute("SHOW DATABASES")
results=cursor.fetchall()
for result in results:
print (result)
if you want to find the port # go to mysql in terminal, and type:
SHOW VARIABLES WHERE Variable_name = 'hostname';
SHOW VARIABLES WHERE Variable_name = 'port';
I had this same problem on AWS - and turns out that my security group was blocking the connection. I temporarily opened up all connections and voila! It connected!
Do you have any type of FW or host-based FW that could be blocking the connection? I thought it was my code and all was fine. Also check the port you are connecting on.
If you are using Docker, you might need to use host.docker.internal instead of localhost.
I managed to solve my issue by using the port without any quotation like so:
port = 3306,
You need to add the port to the connection as well. Try this and it works fine.
pymysql(Module Name).connect(host="localhost", user="root", passwd="root", port=8889, db="db_name")

Categories

Resources