Talend Connection to PostgreSQL Database fails - postgresql

I'm trying to make a connection to a PostgreSQL database which is located in a remote server using Talend Open Studio for Big Data v7.3.1
the problem is that the server requires SSL certificates. I tried many ways but It still fails.
Here are the connection strings that I tried and the log errors in TOS BD
1)With ssl mode disable jdbc:postgresql://xx.xx.xx.xx:5432/dbName?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory&sslmode=disable
Exception in component tDBConnection_1 (DB_Connection)
org.postgresql.util.PSQLException: FATAL: pg_hba.conf rejects connection for host "my.ip.address.here", user "user", database "databasename", SSL off
2)Without specifying ssl mode (it means it takes the default mode) jdbc:postgresql://xx.xx.xx.xx:5432/dbName?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
org.postgresql.ssl.PGjdbcHostnameVerifier verify
GRAVE: Server name validation failed: hostname xx.xx.xx.xx does not match common name xxxxx
Exception in component tDBConnection_1 (DB_Connection)
org.postgresql.util.PSQLException: The hostname xx.xx.xx.xx could not be verified by
hostnameverifier PgjdbcHostnameVerifier
3)If I omit SSL parameters part in the connection like this jdbc:postgresql://xx.xx.xx.xx:5432/dbName? it asks for a valid client certificate.
NB:I can connect to the database using the pgadmin the problem is with Talend open Studio

The solution is to put the certificates locations in the connection string with specifying the ssl mode :
ssl=true&sslmode=prefer&sslcert=DirectoryToSslCertificates/client.crt&sslkey=DirectoryToSslCertificates/clientkey.pk8&sslrootcert=DirectoryToSslCertificates/root.crt
(dont forget to change the certificates formats with openssl commands,I had .pem files)

Related

PostgreSQL: Secure LDAP (LDAPS) to AD with LDAPTLS and LDAPSCHEME not working

I am trying to establish secure LDAP (LDAPS) connection for postgresql.
Currently, LDAP authentication method is established and working.
dockerized PostgreSQL v.14
LDAP connection to Active Directory. AD is setup by IT dept
I tried several options like LDAPTLS and LDAPSCHEME but nothing working.
LDAPTLS:
modified pg_hba.conf file by adding following rule
host all all 0.0.0.0/0 ldap ldapserver=test.ldapserver.com ldapport=389 ldaptls=1 ldapbasedn="DC=test,DC=ldapserver,DC=com" ldapbinddn="CN=test-user,OU=dept,DC=test,DC=ldapserver,DC=com" ldapbindpasswd="ldappassword" ldapsearchfilter="(&(memberOf=CN=subgroup,OU=dept,OU=special,DC=test,DC=ldapserver,DC=com)(cn=$username))"
IT dept provided only root-ca and sub-ca certificates. Server.key and server.crt not provided.
adding the root-ca cert and modified the postgresql.conf
ssl = on
ssl_ca_file = '/etc/ssl/certs/root-ca.crt'
FATAL: could not load server certificate file "server.crt": No such file or directory
After I commented the ssl and ssl_ca_file then the server starts but throw error
LOG: could not start LDAP TLS session: Connect error
DETAIL: LDAP diagnostics: (unknown error code)
FATAL: LDAP authentication failed for user "user"
How to get the server.key and server.crt if root-ca.crt is provided?
LDAPSCHEME:
updated pg_hba.conf file as following
host all all 0.0.0.0/0 ldap ldapserver=test.ldapserver.com ldapscheme=ldaps ldapbasedn="DC=test,DC=ldapserver,DC=com" ldapbinddn="CN=test-user,OU=dept,DC=test,DC=ldapserver,DC=com" ldapbindpasswd="ldappassword" ldapsearchfilter="(&(memberOf=CN=subgroup,OU=dept,OU=special,DC=test,DC=ldapserver,DC=com)(cn=$username))"
LOG: could not perform initial LDAP bind for ldapbinddn="CN=test-user,OU=dept,DC=test,DC=ldapserver,DC=com" on server "test.ldapserver.com": Can't contact LDAP server
DETAIL: LDAP diagnostics: (unknown error code)
FATAL: LDAP authentication failed for user "user"
Also added ldapport=636 and ldaptls=0, but the error remain the same.
What is missing here? Because LDAP can bind without adding ldapscheme
I also tried with ldapurl, but here seems the url doesn't work correctly
host all all 0.0.0.0/0 ldap ldapscheme=ldaps ldapurl="ldaps://test.ldapserver.com:636/DC=test,DC=ldapserver,DC=com?sub?memberOf=CN=subgroup,OU=dept,OU=special,DC=test,DC=ldapserver,DC=com" ldapbinddn="CN=test-user,OU=dept,DC=test,DC=ldapserver,DC=com" ldapbindpasswd="ldappassword
Is this the correct way to use ldapurl?
You are confusing the use of SSL to secure communication between the client and the PostgreSQL server, and the use of SSL to secure communication between the PostgreSQL server and the LDAP server. All those setting you mention (server.key, server.crt, ssl, ssl_ca_file) are for the first of those, not the second.
For the second topic, those certs are not configured through PostgreSQL as far as I know. PostgreSQL just outsources that to whatever your LDAP library is, and it would be configured through that package. Like, for example, /etc/ldap/ldap.conf.

could not initiate GSSAPI security context on Postgres 14 logical replication

I am following this post to enable ssl on Postgres 14 for logical replication. Then try to make connection on client:
CREATE SUBSCRIPTION my-sub
CONNECTION 'host=my-domain.com dbname=my-db user=my-username password=xxxxxx'
PUBLICATION my-pub;
It throws error:
2022-05-12 13:51:36.047 PDT [37340] ERROR: could not connect to the publisher: connection to server at "my_domain.com" (xxx.xxx.xxx.141), port 5432 failed: could not initiate GSSAPI security context: The operation or option is not available: Credential for asked mech-type mech not found in the credential handle
connection to server at "my_domain.com" (xxx.xxx.xxx.141), port 5432 failed: FATAL: connection requires a valid client certificate
connection to server at "my-domain.com" (xxx.xxx.xxx.141), port 5432 failed: FATAL: no pg_hba.conf entry for host "xxx.xxx.xxx.199", user "my-username", database "my-db", no encryption
On my-pub server, one line was added to pg_hba.conf:
hostssl all all 0.0.0.0/0 scram-sha-256 clientcert=verify-full
On sub client, the ca file is setup as below:
ssl_ca_file = '/usr/local/var/postgres/root.crt'. //<<==client cert copied from pub server.
Mostly people just use serve certs. Using client certs is unusual, I would say especially in the case of a logical replication subscriber. But if you do actually want the publisher to demand client certs, it is not configured incorrectly to that purpose (or at least, not that we can tell from the current data). The publisher is demanding a client cert, but the subscriber is not offering one. The configuration problem is on the subscriber.
Note that in this case the subscriber will be acting as the client to connect to the publisher, not acting in the role of a server. It uses the libpq client library to do that, and so the configuration of it is not based on the contents of postgresql.conf. In particular, ssl_ca_file is a server configuration option, not client configuration.
So the way to do this would be for the CONNECTION to look something like
'host=my-domain.com dbname=my-db user=my-username password=xxxxxx sslcert=/foobar/my-username.crt sslkey=/foobar/my-username.key'
But for this to work, the cert and key would need to be on the subscriber computer, readable to whomever owns the postgres process. Which already renders any security benefit dubious.

PostgreSQL SSL doesn't work in cmd and java

Please help with the following problem ...
OS - Windows.
I want to configure SSL on Postgresql 12.
Then my Java application will add entries to the database, delete, etc.
I created certificates: CA, server, client.
CA and server are located in the directory C:\Program Files\PostgreSQL\12\data
The client is located in C:\Users\User\AppData\postgresql
Then I added CA certificate to trusted in Windows.
Configs:
pg_hba:
hostnossl all all 0.0.0.0/0 reject
hostssl all all 0.0.0.0/0 cert clientcert=1
postgresql.conf:
ssl = on
ssl_ca_file = 'root.crt'
I can connect server throw pgAdmin with my certificates, but there are some errors in cmd (and java)
Thant's what I tried to do in cmd
psql.exe -U postgres -h 127.0.0.1
Result:
SSL: certificate verify failed
FATAL: pg_hba.conf rejects connection for host "127.0.0.1", user "postgres", database "prod", SSL off
Logs:
tlsv1 alert unknown ca
FATAL: pg_hba.conf rejects connection for host "127.0.0.1", user "postgres", database "prod", SSL off
Please, tell me what's can be wrong and how can I fix it...
Also I did not find information, how to transfer my certificates to the database from Java application. Maybe, anybody can help me with that problem))
Thanks!
use this in your connection string and it will work:
ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
Then I added CA certificate to trusted in Windows.
psql does not integrate with the Windows certificate manager. The CA to be used by the client needs to go in %APPDATA%\postgresql\root.crt, or if elsewhere its location must be specified by a connection parameter (sslrootcert) or environment variable (PGSSLROOTCERT). These must be files, I don't think there is way to say "go get it from the cert manager".
I think jdbc is the same way, it does not integrate with the Windows cert manager either, for how to specify the locations see https://jdbc.postgresql.org/documentation/head/ssl-client.html
SSL: certificate verify failed FATAL: pg_hba.conf rejects connection for host "127.0.0.1", user "postgres", database "prod", SSL off
Maybe you already know this, but first it tried using SSL and failed to verify the cert (it does not make it clear which side failed, the client cert or the server cert), then it tried to fall back to no SSL and got rejected by the pg_hba. If you had set the client's sslmode to "require" or higher, it would not have tried to fall back to the no SSL, it would have stopped at the first error.

Can't establish Postgres pgAdmin SSH tunnel on Ubuntu

I have a droplet on DigitalCloud with Ubuntu 14.04 and PostgreSQL 9.3. On local machine i have the same configuration.
My ssh connection is working so there is no problem with it. It must be somewhere in my Postgres connection or environment settings.
So what i have already done on the server is:
changed the listening port in /etc/ssh/sshd_config
Port 4321
enabled remote connections in /etc/postgresql/9.3/main/pg_hba.conf
host all all 0.0.0.0/0 md5
added listening addresses in /etc/postgresql/9.3/main/postgresql.conf
listen_addresses = '*'
And here is my local connection settings:
Here is my Properties tab screen
Here is my SSH Tunnel tab screen
I use just the same (and only) id_rsa.pub file which i used to establish my ssh connection before. Which is working. And this is an error that i get upon trying to connect:
SSH error: Authentication by identify file failed with error code -16
[Unable to extract public key from private key file: Wrong passphrase
or invalid/unrecognized private key file format]
My passphrase was set to empty.
If i try to connect without SSH tunnel there is another error:
Error connecting to the server: SSL error: unknown protocol expected
authentication request from server, but received S
I'm a complete newbie to it and I may have missed something important. So tell me if you want me to provide any other info on this matter.
EDIT 1:
If i use correct id_rsa file (without pub) then i get this same error:
Error connecting to the server: SSL error: unknown protocol expected
authentication request from server, but received S
I use just the same (and only) id_rsa.pub file
The first issue is that this is the wrong file. See if you have a file in the same place named "id_rsa" without the ".pub" extension. That is the file you should use as the identity file.
RSA ssh keys come in two files: "id_rsa" contains the private key, while "id_rsa.pub" contains the public key. id_rsa.pub is installed onto the server that you are connecting to, while id_rsa is used by the client that is making the connection to the server.
(Key files can be named something other than "id_rsa", of course. The point is that the private key is in foobar, while the public key is in foobar.pub.)
If you don't have an id_rsa file, then you should generate a new key and keep both files this time.
The second issue is that you have the wrong port on the Properties tab. The port number on the properties tab is the port that the PG server is running on. You should set this to 5432 or whatever port your server is actually listening on. It seems you should also set the "host" on the properties tab to "localhost", but I don't know if this is required.
Error connecting to the server: SSL error: unknown protocol expected authentication request from server, but received S
What is happening now is that your tunneled PG connection is going to port 4321 on the remote host, which is the SSH server. It happens that the first thing an SSH server sends to a new client is a version string, which looks like "SSH-2.0-OpenSSH_6.9" I don't know the PG protocol, but apparently your client reads the "S" in the SSH string and immediately knows it's not connected to a PG server.

SSL error when connection pgAdmin3 to Heroku postgreSQL DB

When trying to connect to Heroku PostgresSQL DB using pgAdmin3 I'm getting the following error:
Error connecting to the server: SSL error: certificate verify failed
The connection is based on pg:credentials output and defined as below:
[Properties]:
Host: <host>
Port: 5432
Service: [blank]
Maintenance DB: <database>
Username: <user>
[SSL]:
SSL: require
Server Root Certificate File: [blank]
Server Certificate Revocation List: [blank]
Client Certificate File: [blank]
Client Key File: [blank]
SSL compression: on
[SSH Tunnel] and [Advanced] left default
so as per Heroku guidelines SSL is enabled (set to: [**require**]).
Any ideas how to provide/fix the certificate referred by the error message?
It's likely that pgAdmin is picking up a bundle of CA certificates that has been configured on your system, in which case require would try to verify the server certificate against that bundle.
Typically, this would be a root.crt file located in %APPDATA%\postgresql\ (C:\Users\YourUserName\AppData\Roaming\postgresql\) under Windows, or in ~/.postgresql/ under Linux.
If there is such a file, try to move it out of the way temporarily to check if it works better.
The problem with moving it out of the way is that you are then no longer verifying any remote PostgreSQL certificates against anything but it still works (with require, it would fail with verify-full).
You can solve this by putting the root.crt file in the right place and adding the server certificate to the list of trusted certificates.
It can be bit tricky to find a remote PostgreSQL certificate, but this simple Python application should let you do it (replace hostname and port as required):
import socket
import ssl
import struct
hostname = '...'
port = 5432
sock = socket.socket()
sock.connect((hostname, port))
# We first connect without encryption and tell the server
# we want to upgrade to SSL/TLS.
initiate_ssl_command = struct.Struct('!ii').pack(8, 80877103)
sock.sendall(initiate_ssl_command)
resp = sock.recv(1)
print "Response should be S: %s" % (resp,)
# We then initiate an SSL/TLS connection on this socket.
ssl_sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_NONE)
ssl_sock.do_handshake()
peer_cert = ssl_sock.getpeercert(True)
print ssl.DER_cert_to_PEM_cert(peer_cert)
ssl_sock.close()
(For details about what this code does, see the PostgreSQL protocol documentation, in particular the "SSL Session Encryption" section and the SSLRequest message, which is similar to what STARTTLS does in other protocols such as SMTP.)
Security warning: Here, you're just hoping that this particular connection has not been attacked and returns the genuine certificate the first time. It's what you'll use as a trust anchor for subsequent connections. (It's very similar to accepting an SSH server key for the first connection, it will flag changes to the certificate if it changes.)
It's also worth noting that the certificate Subject DN might not match that of the server you're connecting to, therefore you might not be able to use PostgreSQL's verify-full mode (which is the only really secure mode, since it also verifies the host name as well as the trust anchor).
Ideally, Heroku (or whoever provides this service) should give you that certificate by another secure means, and make sure that the Subject DN in that certificate matches the host name they give you. (I'm not sure if this is the case at the moment, perhaps it is available from the administration interface.)