PostgreSQL/psycopg2 Password Authentication using SSH Tunneling - django

I am trying to connect to a PostgreSQL Database via ssh tunnel. It is set up to listen on port 3333 and forward to port 5432 on the machine with the database. I am able to connect using the psql command with password authentication via the tunnel, but for some reason when I attempt to connect using psycopg2 via the tunnel, I get the error FATAL: password authentication failed for user database_user. I have tried putting quotes around user names and passwords to no avail.
Successful psql command:
psql -h localhost -p 3333 -U database_name database_user
#This command brings up password prompt
Failed pscyopg2 command:
psycopg2.connect("dbname='database_name' user='database_user' host='localhost' password='database_password' port=3333")
Output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/database_user/.local/share/virtualenvs/project-QNhT-Vzg/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: FATAL: password authentication failed for user "database_user"
FATAL: password authentication failed for user "database_user"
Here is part of my pg_hba.conf for reference:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5

When debugging a connection issue it is always worthy to remember what layers we must go through before reaching the service. When you connect PostgreSQL service there will be at least three layers:
Networking: Firewall, NAT, Port Forwarding
PostgreSQL ACL
PostgreSQL login
It is important to understand what layer cause the issue, the PostgreSQL client (wrapped in psycopg2 in your scenario) error will help you to resolve this by issuing an ad-hoc error message:
Network issue will generally raise a typical: Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?which means you did not succeed to connect the PostgreSQL service at all, problem relies before the service;
ACL issue will generally raise a typical: No pg_hba.conf entry for host <hostname>, user <username>, database <database> which means you did connect the PostgreSQL service but the connection is not referenced as valid in ACL;
Login issue will generally raise the error you have got: password authentication failed for user "<user>" which means you did connect the PostgreSQL service and the connection complies with an ACL entry but the authentication failed.
In the later scenario, it is important to know which entry triggered, because it defines the authentication mode. In your case, it was a md5 entry (because there is no password in peer mode and your SSH tunnel should map the localhost so you are seen as host instead of local for a postgreSQL perspective):
host all all 127.0.0.1/32 md5
Apparently your password is not what you expect it to be. To solve this, ensure:
you have set the password to the postgreSQL user and checked the LOGIN privileges (not the unix/SSH user, there are different concepts);
you use the same password in your psycopg2 connection, then you must be able to connect;
Reading your comment, it seems you may have ' quote in your password as well. So your password in your connection might be:
psycopg2.connect("dbname='database_name' user='database_user' host='localhost' password="'database_password'" port=3333")
Or if the quote are required it may indicate that you use some special characters that need to be escaped. You can also try simpler password to debug and then fallback on a stronger one.

Related

I can't connect to postgresql database in deployment

Hello I just want to deploy my django project in python anywhere .... and when I run the command python manage.py migrate
it shows this error message django.db.utils.OperationalError: connection to server at "<Host name>" (<IP address>), port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections?
I think that the problem in python anywhere because when I connect to the server in pgadmin using the same info in the settings.py file I don't get any error messages and you have to know that I am using neon.tech for my postgresql database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '<the database>',
'USER':'<User>',
'PASSWORD':'<Password>',
'HOST':'<Host>',
'PORT':5432,
}
}
and I am sure that all information is right because I used it to connect to the server in pgadmin in my local machiene
If you are having trouble connecting to a PostgreSQL database in a deployment environment, there are a few things you can check:
Verify that the database is running: Make sure that the PostgreSQL database is running and accessible from the deployment environment. You can check this by attempting to connect to the database using the 'psql' command-line tool.
Check the connection settings: Ensure that the connection settings in your deployment configuration are correct, including the database host, port, database name, user, and password.
Check firewall settings: If you are connecting to a remote PostgreSQL database, ensure that the necessary firewall ports are open to allow incoming connections to the database server.
Check for network issues: Check for any network issues that may be preventing the deployment environment from connecting to the database. For example, if you are deploying to a virtual private cloud, ensure that the network settings are configured correctly.
Check for authentication issues: Make sure that the user and password specified in the connection settings have the necessary permissions to access the database.
Check logs for errors: Check the logs for any error messages that may indicate the cause of the connection issue.
By investigating the above points, you should be able to narrow down the cause of the connection issue and take the necessary steps to resolve it.

How to Access Remote PostgreSQL Database Server Through VPN

I'm currently working with my office server, when i want to connect to the server, i have to use their VPN. I have installed PostgreSQL database in their server and have succesfully migrate data to database from Django project. But, when i want to remote access from HeidiSQL, it always gives me Connection Timed Out Error eventhough i have already connected to their VPN.
I've tried to this code below
/var/lib/pgsql/14/data/pg_hba.conf
host all all 0.0.0.0/0 md5
host all all ::/0 md5
/var/lib/pgsql/14/data/postgresql.conf
listen_addresses = '*'
i have tried to refresh everytime i change files and see if i'm in the correct port but it still gives me Connection Timed Out Error
this is the full error message
could not connect to server: Connection Timed out (0x0000274C/10060). Is the server running on host "xxx.xxx.xxx.xxx" and accepting TCP/IP connections on port 5432 ?
NOTES
OS : CentOS 8
DB : PostgreSQL 14

connection to server at "localhost" (127.0.0.1), port 5432 failed: FATAL: Ident authentication failed for user "postgres"

I'm trying to set up Django PostgreSQL in Django application. I created the db, user and password for the user and when I run \l I can see the db. When I run the django app with python manage.py runserver i get the following error messages.
ON PURE START UP
USER TABLE NOT EXIST
connection to server at "localhost" (127.0.0.1), port 5432 failed: could not initiate GSSAPI security context: Unspecified GSS failure. Minor code may provide more information: Server not found in Kerberos database
connection to server at "localhost" (127.0.0.1), port 5432 failed: FATAL: Ident authentication failed for user "postgres"
What am I missing

Connecting Django on Ubuntu EC2 to AWS RDS MySQL: pymysql tries to connect to localhost instead of foreign server

I am in the process of deploying a Django project on an Ubuntu EC2. It should connect to a MySQL server on AWS RDS. The project works fine on the built-in Django development server you start with runserver and it also connects to the RDS instance properly there. However, if I try running it in production, it throws a 500 Internal Server Error that creates the following output in the error log:
mod_wsgi (pid=18656): Exception occurred processing WSGI script '/home/ubuntu/mysite/mysite/wsgi.py'.
Traceback (most recent call last):
File "/home/ubuntu/mysite/mysite_venv/lib/python3.8/site-packages/pymysql/connections.py", line 613, in connect
sock = socket.create_connection(
File "/usr/lib/python3.8/socket.py", line 808, in create_connection
raise err
File "/usr/lib/python3.8/socket.py", line 796, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
...
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
This socket error occurs both with my custom views and with the mydomain.com/admin view. The relevant snippet of views.py looks like this:
# get environment variables
db_host = os.environ.get('DB_HOST')
db_user = os.environ.get('DB_USER')
db_pass = os.environ.get('DB_PASS')
# connect to db
conn = pymysql.connect(host=db_host,
user=db_user,
password=db_pass)
c = conn.cursor()
c.execute('''USE mysitedatabase''')
The file is generally executed properly, log statements I inserted as a test before the database connection are created without errors. I have already tried removing all inbound traffic rules from my RDS security group, setting it to all IPv4 traffic with 0.0.0.0/0 but the error persisted. I assume that the socket error and the localhost error are connected since I don’t think it would make sense to connect via a unix socket when not being on localhost.
How do I stop pymysql from trying to connect on localhost when it should connect to RDS?
I use Ubuntu 20.04, Django 4.0, Apache/2.4.41 (Ubuntu) and Python 3.8.
The environment variables were not configured in production, thank you #Mark B for pointing me in the right direction. There are multiple ways of going about this. I decided to take an easy route and add the database credentials to settings.py like so:
DB_HOST = 'your_rds_endpoint'
DB_PASS = 'your_secure_password'
DB_USER = 'your_username'
Then just import settings.py into views.py and access the variable you need. In views.py:
from django.conf import settings as my_settings
db_host = my_settings.DB_HOST
db_user = my_settings.DB_USER
db_pass = my_settings.DB_PASS
However, this is not the best way to do it because from what I could find, you should reference the settings file as little as possible because of security concerns.
Better alternatives to this problem are probably django-environ (which, contrary to intuition, also works outside of Django) and python-decouple.
What you probably experiencing is that the RDS has a Host Address that you need to point to shown on the Image.
The possible reason why it's working on your development environment (Assuming it local) is because you have set
db_host = localhost
so try setting
DB_HOST = rds_address
DB_USER = rds_access_username
DB_PASS = rds_access_password

Remote PostgreSQL connection with pgAdmin

I'm trying to set up a remote connection through PostgreSQL running on my server , based on Ubuntu 16.04. So far, when I click on the Save button on pgAdmin, it sort of freezes, does nothing. After typing .../manage.py runserver My_droplet_IP:5432, I try the webpage, and it is accessible.
I followed this tutorial after creating my droplet.
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-16-04
Then I edited the settings.py; pg_hba.conf; postgresql.conf files
settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresqlpsycopg2',
'NAME': '.....',
'USER': '....',
'PASSWORD': '....',
'HOST': '127.0.0.1',
'PORT': '5432',
STATICROOT = os.path.join(BASE_DIR, 'static/') - at the end of the page
And, ofcourse changed the ALLOWED HOSTS = ['....'] with my droplet ip aswell.
postgresql.conf listen_address is set to '*'
pg_hba.conf file:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 0.0.0.0/0 md5
# IPv6 local connections:
host all all ::1/128 md5
Also allowed firewall, and made an exception to 5432 to be allowed.
Any ideas?
First of all test if you can connect to the database via psql:
psql -h ip_address -d name_of_the_database -U username
If you get connection refused error you had to set up something wrong and check the What should I check if remote connect to PostgreSQL not working?
psql: could not connect to server: Connection refused Is the server running on host ip_address
What should I check if remote connect to PostgreSQL not working?
Check the authentication configuration in pg_hba.conf
Usually located on linux - /etc/postgresql/version/main/pg_hba.conf.
You should allow authentication for client for specific IP all from all IP addresses:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 0.0.0.0/0 md5
# IPv6 local connections:
host all all ::0/0 md5
#all ips
host all all all md5
More information how to set up pg_hba.conf you can find in documentation.
Then you should set up listening on specific port.
You have to find the postgresql.conf. Usually located /etc/postgresql/9.1/main/postgresql.conf) file and change the line with listen_address from:
#listen_address = ''
to (don't forget remove # which means comment):
listen_address = '*'
After every step you should restart Postgresql service:
sudo service postgresql restart
After step 2 you should see port 5432 (or 5433) in listening address after netstat command:
netstat -ntlp
After that you have to open port for PostgreSQL in firewall:
sudo ufw allow 5432
You can check firewall settings with (you should see 5432 in the list):
sudo ufw status
If any of the previous step doesn't work you should check if PostgreSQL is not running on different port (usually 5433) and repeat the previous steps.
This happens very often when you have more running versions of PostgreSQL or you upgrade database and forgot stop the previous version of PostgreSQL.
If you have problems to find configuration files you can check this thread Where are my postgres *.conf files?.
In case you are using GCP remember to set the firewall rule inside GCP to allow that port, it might save you some hours of debugging.