How to connect to PostgreSQL? - postgresql

I want to connect to a PostgreSQL server with rust-postgres:
let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
The complete code example is from Client and Config.
I keep getting the error
Error: Error { kind: Connect, cause: Some(Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }) }
In a terminal, I can interact with PostgreSQL:
(base) wm#wm:~/Desktop/HP$ sudo -i -u postgres
postgres#wm:~$ psql
psql (10.10 (Ubuntu 10.10-0ubuntu0.18.04.1))
Type "help" for help.
postgres=#
There are few issues relevant to failed connections, so I guess there must be something I missed.

Postgresql supports client connections via local Unix sockets or via TCP/IP connections.
In the default configuration, though, it will not listen for TCP/IP connections. It will only listen for connections to a local Unix socket. The location of this socket is defined by the postgresql configuration variable unix_socket_directories.
In your tests, you have found that when running the psql command line tool with no arguments, it manages to connect to the database. This works because psql uses the postgresql supplied client library (libpq) and this client library has the default behavior of connecting to the local Unix socket if no hostname is supplied.
However, when using rust-postgres, you are supplying a connection string including the text "host=localhost". This is instructing rust-postgres to make a connection to IP address localhost. It fails because the postgresql server is not configured to listen on any IP interfaces, and only listen on a Unix socket.
You could change the connection string to specify the unix socket to connect to, for example:
host=/var/run/postgresql/.s.PGSQL.5432
The value above reflects where the socket is on my machine, it might be different on yours.
The libpq library allows you to leave the host parameter out altogether and it will connect to the Unix socket automatically; unfortunately it does not look like rust-postgres supports this though.
Alternatively, you could reconfigure your postgresql server so that it listens on the loopback IP adapter. This involves setting the listen_addresses parameter in the postgresl configuration file. See this answer for more details, including changes you will need to make to the authentication in pg_hba.conf.

Related

Connecting DBeaver to remote PostgreSQL DB via Unix socket

I recently installed https://dbeaver.io/ on a Windows PC and wish to access a database on a remote Linux server from it.
My Linux username is my_username and I also have a system user psql_user. I also have two existing PostgreSQL databases with the same name as their respective user. Typically, only the psql_user is used and is access by a php-fpm pool listening to a Unix socket and running as user psql_user, and as such have configured /var/lib/pgsql/12/data/pg_hba.conf as:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 ident
host all all ::1/128 ident
local replication all peer
host replication all 127.0.0.1/32 ident
host replication all ::1/128 ident
With the above configuration, after ssh'ing onto the server, I can access the my_username database by executing psql and can also access the psql_user database by executing sudo -u psql_user psql and do not need to use a password for either.
But now, how to connect from the remote Windows PC?
To attempt to do so, I first created ssh keys without passphrases on the Windows PC for both my_username and psql_user and added the public key to each Linux user's authorized_keys (had to manually create /home/psql_user/ because it is a systems user). I can can successfully PuTTY to the server as either using the ssh keys.
Next, on the DBeaver connection settings SSH tab, I checked "Use SSH Tunnel", entered the username and private key location and the Test tunnel configuration successfully shows connected with the client version as SSH-2.0-JSCH-01.54 and server version as SSH-2.0-OpenSSH_7.4. I also made no changes to the Advanced portion of this tab such as local and remote hosts and ports, and have also left the "You can use variables in SSH parameters" at their default values.
Using my server IP in the main tab, Authentication "Database Native", and leave password empty, I test the connection but get The connection attempt failed. syslog reports that connection to the IP on port 5432 failed which makes sense because I am set up using Unix sockets.
So, then I change the server IP on the main tab to 127.0.0.1 (or localhost) and try again but get FATAL: Ident authentication failed for user "my_username". Okay, a little closer, but not quite there.
I think it might be because DBeaver is passing the port so I attempt to disable this part by got to the Edit Driver tab and changing jdbc:postgresql://{host}[:{port}]/[{database}] to jdbc:postgresql://{host}/[{database}], but now get Connection to 127.0.0.1:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
Not sure where to go next. When I PuTTY into the Linux machine, all is good but not when connecting remotely using DBeaver, and thought it would be the same if I am using SSH to connect DBeaver to the server. How can this be accomplished?
As pointed out in the other answer, DBeaver's SSH tunnel option doesn't support sockets currently. It is always TCP port based, so only connections using the host options in pg_hba.conf can be made (I've placed a feature request for SSH socket forwarding in DBeaver).
Here's how to set up forwarding of a local TCP port to a remote Unix socket. This allows you to use peer authentication over the Unix socket, so you don't have to provide a password for the PostgreSQL role:
ssh username#dbserver.example.com -L 5555:/var/run/postgresql/.s.PGSQL.5432 -fN
While I think that ssh tunnelling can be set up to connect to a unix socket rather than a port, I don't think dbeaver offers a way to do that, so you would have to set it up separately.
Although ident should also work if your server runs the identd service. I think most linux don't do that by default, but just apt install oidentd or whatever the equiv would be on your package manager should fix that.
The easier solution would be to just change the method from ident to md5 or scram, and assign a password (which dbeaver offers to memorize).

Can't connect to postgres database from remote host using psycopg2?

I am unable to connect to postgres database through remote host using psycopg2 and getting the error like
Error:
File "/usr/lib64/python2.7/site-packages/psycopg2/__init__.py", line 126, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: Connection timed out
Is the server running on host "192.x.x.x" and accepting
TCP/IP connections on port 5432?
Note: I have made following changes
1.updated the pg_hba config file
host all all 0.0.0.1/32 trust
2.updated the postgresql file
listen_addresses = '*'
3.changed the firewall rule to allow connection from port 5432
What else I have to do to make it work?
For others that might encounter the same issue, here are some things you can try.
Make sure the service is listening on the needed interfaces
sudo ss -lntp | grep 5432
If you see something like 127.0.0.1:5432 or ::1:5432 this means localhost.
Tweak postgresql.conf:
listen_addresses='192.168.1.2, 127.0.0.1'
You can also use '*' which means any interface but depending on your network configuration it might be dangerous.
Make sure the listen_addresses line isn't commented (as was the case above) and restart the service after making changes.
Check your firewall configuration
After making sure the service is listening on the correct interface make sure your firewall(s), if any, permit the client to connect to the service (this can mean your local firewall, a network device sitting between the client and the service).
Check pg_hba.conf
This file controls PostgreSQL's host-based authentication mechanism:
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.1.3/32 md5
The line above allows all users to connect from 192.168.1.3 if they provide the required password; if you want to allow a whole subnet you can use something like 192.168.1.0/24.
If you suspect an issue with psycopg2 or Python you can test the connectivity using PostgreSQL's client: psql:
psql -U postgres -h 192.168.1.2 db_name

Connect to remote postgres server from EC2 Instance

I am trying to fetch data from the Postgres server which is remotely available from Amazon EC2 instance. When I try to telnet the remote server, it is connected.
But when I am running a kafka connector which connects to the remote Postgres server it throws an error stating
FATAL: no pg_hba.conf entry for host, SSL off for configuration Couldn't open a connection to jdbc:postgresql://<url>
I tried changing the connection string from
jdbc:postgresql://host:5432/schema_name?user=******&password=******&defaultFetchSize=250000&useCursorFetch=true
to
jdbc:postgresql://host:5432/schema_name?ssl=true&user=******&password=******&defaultFetchSize=250000&useCursorFetch=true
then it throws another error which is
The server does not support SSL. for configuration Couldn't open a connection to jdbc:postgresql://<url>
There is no SSL support in the Postgres server because I can connect to the server through any DB connector without ssh. I am sure it has to do something with the security access group of EC2(considering I can telnet to the server from the instance). Any help would be much appreciated.
Looks like error is in the pg_hba.conf. I would have put this as a comment but not enough rep.
When you telnet to the server did you use the db port?
Can you post your pg_hba.conf file. This is one off my home dev server. You'll need to add a line similar to this: host all all 192.168.1.1/24 md5 with your IP addr and details.
If you're using this in a corporate network I'd highly recommend looking at a amazon VPC and not to expose your database to the internet.
# 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
host all all 10.10.187.1/24 md5

Perl DBI: connect to REMOTE PostgreSQL db still complains about local socket file

I'm trying to use DBIx::Class to connect to a remote PostgreSQL db.
My connect string: "DBI:Pg:database=asterisk:host=example.com:hostaddr=10.10.10.10:port=5432", $user, $pass
example.com does resolve to '10.10.10.10', swapping both to the IP or having only host=IP all result in
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? at /usr/local/share/perl/5.10.1/DBIx/Class/Storage/DBI.pm line 1489. at db-access.pl line 26
On this debian I don't have or want postgresql, I do have libdbd-pg-perl however. And DBI->available_drivers says that I do have Pg (It didn't before I installed the library).
How can I find out what it's trying to do and do I need anything else installing? The server in question is configured to allow connections from 10.100.* addresses which the machine running this code is on and I can connect to it with tools such as PSequel and pgAdmin on my workstation (same network) with the db user in question.
"DBI:Pg:database=asterisk:host=example.com:hostaddr=10.10.10.10:port=5432"
That should be:
"DBI:Pg:database=asterisk;host=example.com;hostaddr=10.10.10.10;port=5432"
Only the first two separators are colons. The rest of them should be semi-colons.

pgAdmin and PostgreSQL: can't connect to server

I just installed PostgreSQL on Snow Leopard and can't connect to the database server via pgAdmin 3.
I'm on my local machine, however I keep getting this error:
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 5423?
I'm a bit of a noob when it comes to Postgres, so I'm not really sure what the problem is.
I can, however, log in through the command line, via psql -U postgres, and start and stop the server successfully.
Any help would be much appreciated.
The error message pointed out that you tried to connect to server on port 5423. However, postgres server listens on 5432 by default.
From your above comment (SHOW port; gives me "5432"), I think you need to change the port to 5432!
UPDATE: Tuan Dang spotted it. I'll leave this answer in place in case it helps someone else for whom the issue isn't quite the same.
Since you can connect via the command line, run:
SHOW port;
from psql. You'll probably see that the port is not 5432. You need to connect to the port PostgreSQL is actually running on from your application.
It's also possible that it just isn't listening on TCP/IP. Run:
SHOW listen_addresses;
to see what it's listening for.
The reason you can connect via the command line is likely to be because the command line psql you're using is connecting over a unix socket (since you didn't specify a host) and your app is connecting via tcp/ip.