could not accept ssl connection tlsv1 alert unknown ca

Started by Zwettler Markus (OIZ)about 1 year ago10 messagesgeneral
Jump to latest
#1Zwettler Markus (OIZ)
Markus.Zwettler@zuerich.ch

We wanted to use pure ssl encryption without certificate validation.

We created and configured self-signed certificates at the postgres server, turned "sslmode=on" and advised our clients to use "sslmode=prefer". This worked very well.

However, one client also configured some client certificates + "sslmode=prefer" which resulted in "could not accept ssl connection tlsv1 alert unknown ca".

I always thought that Postgres does only validate certificates with "sslmode=verify-ca" and "sslmode=verify-full" => https://www.postgresql.org/docs/current/libpq-ssl.html

Did I get something wrong?

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zwettler Markus (OIZ) (#1)
Re: could not accept ssl connection tlsv1 alert unknown ca

"Zwettler Markus (OIZ)" <Markus.Zwettler@zuerich.ch> writes:

However, one client also configured some client certificates + "sslmode=prefer" which resulted in "could not accept ssl connection tlsv1 alert unknown ca".

I'm no expert, but I think this typically means a missing or untrusted
intermediate certificate, that is no chain of trust to one of the
certs that your OpenSSL considers trusted.

I always thought that Postgres does only validate certificates with "sslmode=verify-ca" and "sslmode=verify-full" => https://www.postgresql.org/docs/current/libpq-ssl.html

Those cause some additional checks to be made, but it's not like
you can expect a completely broken certificate to work without them.

regards, tom lane

#3Zwettler Markus (OIZ)
Markus.Zwettler@zuerich.ch
In reply to: Tom Lane (#2)
Re: Re: could not accept ssl connection tlsv1 alert unknown ca

Von: Tom Lane <tgl@sss.pgh.pa.us>
Gesendet: Donnerstag, 30. Januar 2025 18:51
An: Zwettler Markus (OIZ) <Markus.Zwettler@zuerich.ch>
Cc: pgsql-general@lists.postgresql.org
Betreff: [Extern] Re: could not accept ssl connection tlsv1 alert unknown ca

"Zwettler Markus (OIZ)" <Markus.Zwettler@zuerich.ch> writes:

However, one client also configured some client certificates + "sslmode=prefer"

which resulted in "could not accept ssl connection tlsv1 alert unknown ca".

I'm no expert, but I think this typically means a missing or untrusted intermediate
certificate, that is no chain of trust to one of the certs that your OpenSSL
considers trusted.

I always thought that Postgres does only validate certificates with
"sslmode=verify-ca" and "sslmode=verify-full" =>
https://www.postgresql.org/docs/current/libpq-ssl.html

Those cause some additional checks to be made, but it's not like you can expect a
completely broken certificate to work without them.

regards, tom lane

I don't understand why Postgres does a certificate validation with “sslmode=prefer”. Postgres should simply ignore every presented client certificate here. Regardless of whether it is trusted or not.

A certificate validation should only take place in the modes “sslmode=verify-ca” and “ssmode=verify-full”. Only here should Postgres refuse a connection with non-trusted certificates.

At least that's what I read in the documentation. No?

Regards, Markus

#4Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Zwettler Markus (OIZ) (#3)
Re: could not accept ssl connection tlsv1 alert unknown ca

On 1/31/25 00:57, Zwettler Markus (OIZ) wrote:

Von: Tom Lane <tgl@sss.pgh.pa.us>

Those cause some additional checks to be made, but it's not like you can expect a
completely broken certificate to work without them.

regards, tom lane

I don't understand why Postgres does a certificate validation with “sslmode=prefer”. Postgres should simply ignore every presented client certificate here. Regardless of whether it is trusted or not.

What are the relevant lines in pg_hba.conf?

A certificate validation should only take place in the modes “sslmode=verify-ca” and “ssmode=verify-full”. Only here should Postgres refuse a connection with non-trusted certificates.

At least that's what I read in the documentation. No?

Regards, Markus

--
Adrian Klaver
adrian.klaver@aklaver.com

#5Zwettler Markus (OIZ)
Markus.Zwettler@zuerich.ch
In reply to: Adrian Klaver (#4)
Re: Re: could not accept ssl connection tlsv1 alert unknown ca

-----Ursprüngliche Nachricht-----
Von: Adrian Klaver <adrian.klaver@aklaver.com>
Gesendet: Freitag, 31. Januar 2025 17:37
An: Zwettler Markus (OIZ) <Markus.Zwettler@zuerich.ch>; Tom Lane
<tgl@sss.pgh.pa.us>; pgsql-general@lists.postgresql.org
Betreff: [Extern] Re: could not accept ssl connection tlsv1 alert unknown ca

On 1/31/25 00:57, Zwettler Markus (OIZ) wrote:

Von: Tom Lane <tgl@sss.pgh.pa.us>

Those cause some additional checks to be made, but it's not like you
can expect a completely broken certificate to work without them.

regards, tom lane

I don't understand why Postgres does a certificate validation with

“sslmode=prefer”. Postgres should simply ignore every presented client certificate
here. Regardless of whether it is trusted or not.

What are the relevant lines in pg_hba.conf?

A certificate validation should only take place in the modes “sslmode=verify-ca”

and “ssmode=verify-full”. Only here should Postgres refuse a connection with non-
trusted certificates.

At least that's what I read in the documentation. No?

Regards, Markus

--
Adrian Klaver
adrian.klaver@aklaver.com

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert
hostssl "postgres" "_crunchyrepl" all cert
host all "_crunchyrepl" all reject
host all "ccp_monitoring" "127.0.0.0/8" scram-sha-256
host all "ccp_monitoring" "::1/128" scram-sha-256
host all "ccp_monitoring" all reject
hostssl all all all md5

#6Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Zwettler Markus (OIZ) (#5)
Re: could not accept ssl connection tlsv1 alert unknown ca

On 1/31/25 08:57, Zwettler Markus (OIZ) wrote:

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert
hostssl "postgres" "_crunchyrepl" all cert
host all "_crunchyrepl" all reject
host all "ccp_monitoring" "127.0.0.0/8" scram-sha-256
host all "ccp_monitoring" "::1/128" scram-sha-256
host all "ccp_monitoring" all reject
hostssl all all all md5

From here:

https://www.postgresql.org/docs/17/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

"There are two approaches to enforce that users provide a certificate
during login.

The first approach makes use of the cert authentication method for
hostssl entries in pg_hba.conf, such that the certificate itself is used
for authentication while also providing ssl connection security.

[...]

The second approach combines any authentication method for hostssl
entries with the verification of client certificates by setting the
clientcert authentication option to verify-ca or verify-full. ...
"

Is the client having issues trying a connection that matches either of
the lines below?:

hostssl replication "_crunchyrepl" all cert
hostssl "postgres" "_crunchyrepl" all cert

--
Adrian Klaver
adrian.klaver@aklaver.com

#7Zwettler Markus (OIZ)
Markus.Zwettler@zuerich.ch
In reply to: Adrian Klaver (#6)
Re: Re: could not accept ssl connection tlsv1 alert unknown ca

-----Ursprüngliche Nachricht-----
Von: Adrian Klaver <adrian.klaver@aklaver.com>
Gesendet: Freitag, 31. Januar 2025 18:07
An: Zwettler Markus (OIZ) <Markus.Zwettler@zuerich.ch>; Tom Lane
<tgl@sss.pgh.pa.us>; pgsql-general@lists.postgresql.org
Betreff: [Extern] Re: could not accept ssl connection tlsv1 alert unknown ca

On 1/31/25 08:57, Zwettler Markus (OIZ) wrote:

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert hostssl "postgres"
"_crunchyrepl" all cert host all "_crunchyrepl" all reject host all
"ccp_monitoring" "127.0.0.0/8" scram-sha-256 host all "ccp_monitoring"
"::1/128" scram-sha-256 host all "ccp_monitoring" all reject hostssl
all all all md5

From here:

https://www.postgresql.org/docs/17/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

"There are two approaches to enforce that users provide a certificate during login.

The first approach makes use of the cert authentication method for hostssl entries
in pg_hba.conf, such that the certificate itself is used for authentication while also
providing ssl connection security.

[...]

The second approach combines any authentication method for hostssl entries with
the verification of client certificates by setting the clientcert authentication option
to verify-ca or verify-full. ...
"

Is the client having issues trying a connection that matches either of the lines
below?:

replication "_crunchyrepl" all cert hostssl "postgres" "_crunchyrepl" all
cert

--
Adrian Klaver
adrian.klaver@aklaver.com

No, there are no errors with the lines mentioned.

The error appears with a connection that matches the last line.

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert
hostssl "postgres" "_crunchyrepl" all cert
host all "_crunchyrepl" all reject
host all "ccp_monitoring" "127.0.0.0/8" scram-sha-256
host all "ccp_monitoring" "::1/128" scram-sha-256
host all "ccp_monitoring" all reject
hostssl all all all md5 <<== user connection matching this line gives the error

#8Zwettler Markus (OIZ)
Markus.Zwettler@zuerich.ch
In reply to: Zwettler Markus (OIZ) (#7)
Re: Re: could not accept ssl connection tlsv1 alert unknown ca

-----Ursprüngliche Nachricht-----
Von: Zwettler Markus (OIZ) <Markus.Zwettler@zuerich.ch>
Gesendet: Montag, 3. Februar 2025 09:37
An: Adrian Klaver <adrian.klaver@aklaver.com>; Tom Lane
<tgl@sss.pgh.pa.us>; pgsql-general@lists.postgresql.org
Betreff: Re: Re: could not accept ssl connection tlsv1 alert unknown ca

-----Ursprüngliche Nachricht-----
Von: Adrian Klaver <adrian.klaver@aklaver.com>
Gesendet: Freitag, 31. Januar 2025 18:07
An: Zwettler Markus (OIZ) <Markus.Zwettler@zuerich.ch>; Tom Lane
<tgl@sss.pgh.pa.us>; pgsql-general@lists.postgresql.org
Betreff: [Extern] Re: could not accept ssl connection tlsv1 alert
unknown ca

On 1/31/25 08:57, Zwettler Markus (OIZ) wrote:

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert hostssl "postgres"
"_crunchyrepl" all cert host all "_crunchyrepl" all reject host all
"ccp_monitoring" "127.0.0.0/8" scram-sha-256 host all "ccp_monitoring"
"::1/128" scram-sha-256 host all "ccp_monitoring" all reject hostssl
all all all md5

From here:

https://www.postgresql.org/docs/17/ssl-tcp.html#SSL-CLIENT-CERTIFICATE
S

"There are two approaches to enforce that users provide a certificate during

login.

The first approach makes use of the cert authentication method for
hostssl entries in pg_hba.conf, such that the certificate itself is
used for authentication while also providing ssl connection security.

[...]

The second approach combines any authentication method for hostssl
entries with the verification of client certificates by setting the
clientcert authentication option to verify-ca or verify-full. ...
"

Is the client having issues trying a connection that matches either of
the lines
below?:

replication "_crunchyrepl" all cert hostssl "postgres" "_crunchyrepl"
all cert

--
Adrian Klaver
adrian.klaver@aklaver.com

No, there are no errors with the lines mentioned.

The error appears with a connection that matches the last line.

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert hostssl "postgres" "_crunchyrepl" all
cert host all "_crunchyrepl" all reject host all "ccp_monitoring" "127.0.0.0/8"
scram-sha-256 host all "ccp_monitoring" "::1/128" scram-sha-256 host all
"ccp_monitoring" all reject
hostssl all all all md5 <<== user connection matching this
line gives the error

Seems that I found the root cause in the docs:
"When clientcert is not specified, the server verifies the client certificate against its CA file only if a client certificate is presented and the CA is configured."
https://www.postgresql.org/docs/17/ssl-tcp.html#SSL-CLIENT-CERTIFICATES
a CA is configured on the server and the client presents a client certificate.

Is it possible to configure "clientcert=disable" in pg_hba.conf or disable the client verification otherwise?
The docs only mention "verify-ca" and "verify-full".
"In addition to the method-specific options listed below, there is a method-independent authentication option clientcert, which can be specified in any hostssl record. This option can be set to verify-ca or verify-full."
https://www.postgresql.org/docs/current/auth-pg-hba-conf.html

#9Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Zwettler Markus (OIZ) (#8)
Re: could not accept ssl connection tlsv1 alert unknown ca

On 2/3/25 02:14, Zwettler Markus (OIZ) wrote:

bash-4.4$ cat pg_hba.conf
# Do not edit this file manually!
# It will be overwritten by Patroni!
local all "postgres" peer
hostssl replication "_crunchyrepl" all cert hostssl "postgres" "_crunchyrepl" all
cert host all "_crunchyrepl" all reject host all "ccp_monitoring" "127.0.0.0/8"
scram-sha-256 host all "ccp_monitoring" "::1/128" scram-sha-256 host all
"ccp_monitoring" all reject
hostssl all all all md5 <<== user connection matching this
line gives the error

Seems that I found the root cause in the docs:
"When clientcert is not specified, the server verifies the client certificate against its CA file only if a client certificate is presented and the CA is configured."
https://www.postgresql.org/docs/17/ssl-tcp.html#SSL-CLIENT-CERTIFICATES
a CA is configured on the server and the client presents a client certificate.

Is it possible to configure "clientcert=disable" in pg_hba.conf or disable the client verification otherwise?
The docs only mention "verify-ca" and "verify-full".
"In addition to the method-specific options listed below, there is a method-independent authentication option clientcert, which can be specified in any hostssl record. This option can be set to verify-ca or verify-full."
https://www.postgresql.org/docs/current/auth-pg-hba-conf.html

From what I understand your client has to either not have the client
certificates or create them correctly.

--
Adrian Klaver
adrian.klaver@aklaver.com

#10Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Adrian Klaver (#9)
Re: could not accept ssl connection tlsv1 alert unknown ca

On 2/3/25 08:09, Adrian Klaver wrote:

On 2/3/25 02:14, Zwettler Markus (OIZ) wrote:

Is it possible to configure "clientcert=disable" in pg_hba.conf or
disable the client verification otherwise?
The docs only mention "verify-ca" and "verify-full".
"In addition to the method-specific options listed below, there is a
method-independent authentication option clientcert, which can be
specified in any hostssl record. This option can be set to verify-ca
or verify-full."
https://www.postgresql.org/docs/current/auth-pg-hba-conf.html

From what I understand your client has to either not have the client
certificates or create them correctly.

To follow up from here:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/libpq/be-secure-openssl.c;h=abf67bb1b2728e6d2cc9851ca71006d2fd0cde54;hb=HEAD

/*
* Always ask for SSL client cert, but don't fail if it's not
* presented. We might fail such connections later, depending on what
* we find in pg_hba.conf.
*/
SSL_CTX_set_verify(context,
(SSL_VERIFY_PEER |
SSL_VERIFY_CLIENT_ONCE),
verify_cb);

--
Adrian Klaver
adrian.klaver@aklaver.com