Client SSL validation using root.crt

Lists: pgsql-generalpgsql-hackers
From: "Sergio" <sergio(dot)cinos(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Client SSL validation using root.crt
Date: 2006-11-17 10:54:54
Message-ID: 1163760893.916252.251170@m7g2000cwm.googlegroups.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general pgsql-hackers

Hello all,

I see a strange behaviour using root.crt. PostgreSQL always waits a
client certificate to check agains root.crt. But I set up a
'hostnossl' auth line un pg_hba.conf, PostgreSQL still wants a client
certificate. Also fails if line is a 'host'.

Better with an example:

---pg_hba.conf---
hostssl all all 192.168.0.1/32 md5
hostnossl all all 192.168.0.2/32 md5
-----------------

If I connect to PostgresSQL from 192.168.0.1, it fails if I don't
provide a client certificate, it is ok. But if I connect from
192.168.0.2, it also fails becouse I don't send a certificate. But I
declared a non-ssl connection from 192.168.0.2, it should let me
connect to databases, isn'it?

Removing root.crt works as expected. Client in 192.168.0.1 connect
using a SSL connection, and client in 192.168.0.2 connect using a
single connection.

It this behaviour ok? I think not. I want to allow clients on my LAN
access PostgreSQL server without a SSL connection , and require
a client certificate and a SSL connection to clients from outside my
LAN.
I think it is not a strange configuration. So the configuration is:
---pg_hba.conf---
hostnossl all all <my-lan-range> md5
hostssl <user> <db> 0.0.0.0/0 md5
-----------------
This fails, because PostgreSQL expect that all clients provide a
client certificate.

Is there any config option to solve this? Is there any page or manual
about PostgreSQL with SSL (more in-deep that
http://www.postgresql.org/docs/8.0/interactive/ssl-tcp.html) ?
Oh, I'm using PostgreSQL 8.0.8 on a Gentoo box. Maybe I have to upgrade
to another version?

Thans you in advance.


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Sergio" <sergio(dot)cinos(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Client SSL validation using root.crt
Date: 2006-11-21 03:30:31
Message-ID: 17443.1164079831@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general pgsql-hackers

"Sergio" <sergio(dot)cinos(at)gmail(dot)com> writes:
> I see a strange behaviour using root.crt. PostgreSQL always waits a
> client certificate to check agains root.crt. But I set up a
> 'hostnossl' auth line un pg_hba.conf, PostgreSQL still wants a client
> certificate.

No, not really. The problem is that in the default PGSSLMODE=prefer
behavior, libpq tries an SSL connection first. It's prepared to retry
with a non-SSL connection if it gets a rejection from the server ...
but if OpenSSL fails to establish the connection, it just dies
immediately.

I got the behavior I think you want with the attached patch, which
allows a retry for SSL setup errors as well as server rejections.
The trouble with this is that it masks SSL setup errors. For example,
if the server has "hostssl" to require SSL on localhost connections,
and I don't have a client certificate:

$ psql -l -h localhost
psql: FATAL: no pg_hba.conf entry for host "127.0.0.1", user "tgl", database "postgres", SSL off

The only way to get any info about what's wrong with the SSL setup
is to select a nondefault SSLMODE:

$ PGSSLMODE=require psql -l -h localhost
psql: could not open certificate file "/home/tgl/.postgresql/postgresql.crt": No such file or directory

I'm not sure there's anything much to be done about this --- in any
given failure scenario, the user is probably only interested in one or
the other of the SSL and non-SSL error messages, and libpq has no very
good way to guess which one. (I thought for a bit about reporting both,
but that seems pretty likely to confuse more often than it helps.)

So I'm inclined to apply the patch, at least in HEAD (8.2), but wanted
to see if anyone had any other ideas.

Meanwhile, Sergio's best workaround is "export PGSSLMODE=allow".

regards, tom lane

Index: fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.338
diff -c -r1.338 fe-connect.c
*** fe-connect.c 6 Oct 2006 17:14:00 -0000 1.338
--- fe-connect.c 21 Nov 2006 02:56:20 -0000
***************
*** 1400,1405 ****
--- 1400,1424 ----
conn->status = CONNECTION_MADE;
return PGRES_POLLING_WRITING;
}
+ if (pollres == PGRES_POLLING_FAILED)
+ {
+ /*
+ * Failed ... if sslmode is "prefer" then do a non-SSL
+ * retry
+ */
+ if (conn->sslmode[0] == 'p' /* "prefer" */
+ && conn->allow_ssl_try /* redundant? */
+ && !conn->wait_ssl_try) /* redundant? */
+ {
+ /* only retry once */
+ conn->allow_ssl_try = false;
+ /* Must drop the old connection */
+ closesocket(conn->sock);
+ conn->sock = -1;
+ conn->status = CONNECTION_NEEDED;
+ goto keep_going;
+ }
+ }
return pollres;
#else /* !USE_SSL */
/* can't get here */


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Sergio <sergio(dot)cinos(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org, pgsql-hackers(at)postgresql(dot)org
Subject: Re: [HACKERS] Client SSL validation using root.crt
Date: 2006-11-21 10:29:45
Message-ID: 20061121102945.GB7205@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general pgsql-hackers

On Mon, Nov 20, 2006 at 10:30:31PM -0500, Tom Lane wrote:
> "Sergio" <sergio(dot)cinos(at)gmail(dot)com> writes:
> > I see a strange behaviour using root.crt. PostgreSQL always waits a
> > client certificate to check agains root.crt. But I set up a
> > 'hostnossl' auth line un pg_hba.conf, PostgreSQL still wants a client
> > certificate.
>
> No, not really. The problem is that in the default PGSSLMODE=prefer
> behavior, libpq tries an SSL connection first. It's prepared to retry
> with a non-SSL connection if it gets a rejection from the server ...
> but if OpenSSL fails to establish the connection, it just dies
> immediately.

It is possible to continue communicating after SSL negotiation failure.
If SSL_accept/connect return 0, that means the negotiation failed
cleanly and in theory libpq could continue in non-SSL mode.

I think long term this would be the nicest solution (no double
connections) but it's probably more complicated then looping around
again after SSL failure.

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Martijn van Oosterhout <kleptog(at)svana(dot)org>
Cc: Sergio <sergio(dot)cinos(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org, pgsql-hackers(at)postgresql(dot)org
Subject: Re: [HACKERS] Client SSL validation using root.crt
Date: 2006-11-21 15:06:45
Message-ID: 4304.1164121605@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general pgsql-hackers

Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:
> It is possible to continue communicating after SSL negotiation failure.
> If SSL_accept/connect return 0, that means the negotiation failed
> cleanly and in theory libpq could continue in non-SSL mode.

We'd have to change the backend too, though, because in existing
releases it likewise will drop out on SSL negotiation failure.

> I think long term this would be the nicest solution (no double
> connections) but it's probably more complicated then looping around
> again after SSL failure.

I don't think it's that important. If the backend is configured with
ssl = off then we already fall through without using an extra connection
cycle. The double connection only occurs if both sides think they
should use SSL but something goes wrong ... which is probably a
situation that needs user attention anyway.

regards, tom lane