Possible SSL improvements for a newcomer to tackle

Started by Zeus Kronionover 8 years ago16 messages
#1Zeus Kronion
zkronion@gmail.com

I previously made one minuscule contribution to the project two years ago.
I'm interested in doing some more, and I'm trying to figure out what to
focus on. Two SSL-related projects caught my attention:
1) Allow automatic selection of SSL client certificates from a certificate
store (/messages/by-id/8766.1241799013@sss.pgh.pa.us).
It seems relatively straightforward to support an additional file format
for key-value pairs in postgresql.crt/.key, and I think this is something I
could take on if it's still desired.
2) I was surprised to learn the following from the docs:

By default, PostgreSQL will not perform any verification of the server

certificate. This means that it is possible to spoof the server identity
(for example by modifying a DNS record or by taking over the server IP
address) without the client knowing. In order to prevent spoofing, SSL
certificate
verification must be used.

Is there a technical reason to perform no verification by default? Wouldn't
a safer default be desirable?

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zeus Kronion (#1)
Re: Possible SSL improvements for a newcomer to tackle

Zeus Kronion <zkronion@gmail.com> writes:

2) I was surprised to learn the following from the docs:

By default, PostgreSQL will not perform any verification of the server
certificate.

Is there a technical reason to perform no verification by default? Wouldn't
a safer default be desirable?

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against? You need some local
notion of which are your trusted root certificates before you can verify
anything. So to default to verification would be to default to failing to
connect at all until user has created a ~/.postgresql/root.crt file with
valid, relevant entries. That seems like a nonstarter.

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Michael Paquier
michael.paquier@gmail.com
In reply to: Zeus Kronion (#1)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 3, 2017 at 1:15 PM, Zeus Kronion <zkronion@gmail.com> wrote:

I previously made one minuscule contribution to the project two years ago.
I'm interested in doing some more, and I'm trying to figure out what to
focus on. Two SSL-related projects caught my attention:
1) Allow automatic selection of SSL client certificates from a certificate
store (/messages/by-id/8766.1241799013@sss.pgh.pa.us).
It seems relatively straightforward to support an additional file format for
key-value pairs in postgresql.crt/.key, and I think this is something I
could take on if it's still desired.
2) I was surprised to learn the following from the docs:

One other thing that could be improved, and that has been already
asked for is improvement for passphrase handling, particularly since
SSL parameters can be reloaded, by adding for example a new GUC
parameter that calls a shell command which outputs what is wanted to
stdout. It could be tricky to implement as the postmaster should be
able to handle requests when launching the command. But I think you
get the idea.

By default, PostgreSQL will not perform any verification of the server
certificate. This means that it is possible to spoof the server identity
(for example by modifying a DNS record or by taking over the server IP
address) without the client knowing. In order to prevent spoofing, SSL
certificate verification must be used.

Is there a technical reason to perform no verification by default? Wouldn't
a safer default be desirable?

It would be nice to get into a stronger default with "require" at
least, the recommendation is to use at least "verify-ca" for any
serious deployment. Note that not long ago there were arguments about
how the default value of sslmode called 'prefer' is good at giving a
false sense of security, but this led nowhere (can't put my hands on
this thread now..).
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#2)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Zeus Kronion <zkronion@gmail.com> writes:

2) I was surprised to learn the following from the docs:

By default, PostgreSQL will not perform any verification of the server
certificate.

Is there a technical reason to perform no verification by default?

Wouldn't

a safer default be desirable?

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against? You need some local
notion of which are your trusted root certificates before you can verify
anything. So to default to verification would be to default to failing to
connect at all until user has created a ~/.postgresql/root.crt file with
valid, relevant entries. That seems like a nonstarter.

Yes, you need something to verify against.

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-certificates.crt.
Exactly where to find them would be distribution-specific though, and we
would need to actually add support for a second certificate store. But that
would probably be a useful feature in itself.

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

No that's horrible. If it's unreliable, it doesn't provide any actual
benefit. We have a history of that in our default being prefer instead of
allow, but we definitely shouldn't make that situation even worse.

--
Magnus Hagander
Me: https://www.hagander.net/ <http://www.hagander.net/&gt;
Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/&gt;

#5Adrien Nayrat
adrien.nayrat@dalibo.com
In reply to: Zeus Kronion (#1)
Re: Possible SSL improvements for a newcomer to tackle

Hi,

On 10/03/2017 06:15 AM, Zeus Kronion wrote:

2) I was surprised to learn the following from the docs:

 By default, PostgreSQL will not perform any verification of the server

certificate. This means that it is possible to spoof the server identity (for
example by modifying a DNS record or by taking over the server IP address)
without the client knowing. In order to prevent spoofing, SSL certificate
verification must be used.

Is there a technical reason to perform no verification by default? Wouldn't a
safer default be desirable?

If you want to verify server's certificate you should use DANE [1] + DNSSEC [2]
? (I am not an SSL expert too)

If I understand correctly, you can store your certificate in a DNS record
(TLSA). Then the client can check the certificate. You must trust your DNS
server (protection against spoofing), that's why you have to use DNSSEC.

1: https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities
2: https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions

--
Adrien NAYRAT

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#4)
Re: Possible SSL improvements for a newcomer to tackle

Magnus Hagander <magnus@hagander.net> writes:

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against?

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-certificates.crt.
Exactly where to find them would be distribution-specific though, and we
would need to actually add support for a second certificate store. But that
would probably be a useful feature in itself.

Maybe. The impression I have is that it's very common for installations
to use a locally-run CA to generate server and client certs. I would not
expect them to put such certs into /etc/ssl/certs. But I suppose there
might be cases where you would actually pay for a universally-valid cert
for a DB server ...

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Stephen Frost
sfrost@snowman.net
In reply to: Tom Lane (#6)
Re: Possible SSL improvements for a newcomer to tackle

Tom,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against?

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-certificates.crt.
Exactly where to find them would be distribution-specific though, and we
would need to actually add support for a second certificate store. But that
would probably be a useful feature in itself.

Maybe. The impression I have is that it's very common for installations
to use a locally-run CA to generate server and client certs. I would not
expect them to put such certs into /etc/ssl/certs. But I suppose there
might be cases where you would actually pay for a universally-valid cert
for a DB server ...

In many larger enterprises, they actually deploy systems with their own
CA installed into the system global certificate store (possibly removing
certain other CAs from that set too, and distributing their own version
of the relevant package that maintains the CA set).

I agree with Magnus that most other SSL apps do default to the system
global cert store and it's generally what's expected.

Thanks!

Stephen

#8Magnus Hagander
magnus@hagander.net
In reply to: Stephen Frost (#7)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 3, 2017 at 3:51 PM, Stephen Frost <sfrost@snowman.net> wrote:

Tom,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI

the

question is what are you going to verify against?

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-

certificates.crt.

Exactly where to find them would be distribution-specific though, and

we

would need to actually add support for a second certificate store. But

that

would probably be a useful feature in itself.

Maybe. The impression I have is that it's very common for installations
to use a locally-run CA to generate server and client certs. I would not
expect them to put such certs into /etc/ssl/certs. But I suppose there
might be cases where you would actually pay for a universally-valid cert
for a DB server ...

In many larger enterprises, they actually deploy systems with their own
CA installed into the system global certificate store (possibly removing
certain other CAs from that set too, and distributing their own version
of the relevant package that maintains the CA set).

I think this is also something that's seen more now than it used to be.
Back when we initially did the SSL support, few people actually did this.
That's not just for this scenario of course -- larger enterprises are much
more likely to *have* proper PKI management today, and if they do then it
will include the Linux boxes.

Bottom line: things in this area has change greatly in the past 10-15 years.

--
Magnus Hagander
Me: https://www.hagander.net/ <http://www.hagander.net/&gt;
Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/&gt;

#9Nico Williams
nico@cryptonector.com
In reply to: Tom Lane (#2)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 03, 2017 at 12:33:00AM -0400, Tom Lane wrote:

Zeus Kronion <zkronion@gmail.com> writes:

2) I was surprised to learn the following from the docs:

By default, PostgreSQL will not perform any verification of the server
certificate.

Is there a technical reason to perform no verification by default? Wouldn't
a safer default be desirable?

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against? You need some local
notion of which are your trusted root certificates before you can verify
anything. So to default to verification would be to default to failing to
connect at all until user has created a ~/.postgresql/root.crt file with
valid, relevant entries. That seems like a nonstarter.

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

You do always need trust anchors in order to verify a peer's
certificate.

Usually there will be a system-wide trust anchor set, though it may not
be appropriate for use with PG...

Still, it would be safer to refuse to connect until the lack of trust
anchors is rectified than to connect without warning about the inability
to verify a server. By forcing the user (admins) to take action to
remediate the problem, the problem then gets fixed, whereas plowing on
creates an invisible (for many users) security problem.

Now, the use of channel binding from authentication methods like GSS-API
helps a fair bit, though mostly it helps by leveraging some other
authentication infrastructure that the users (admins) have set up --
they could easily have setup PKI too then. With SCRAM there is much
less infrastructure (but also SCRAM requires very good passwords; a PAKE
would be much better).

Nico
--

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Nico Williams
nico@cryptonector.com
In reply to: Tom Lane (#6)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 03, 2017 at 09:44:01AM -0400, Tom Lane wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against?

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-certificates.crt.
Exactly where to find them would be distribution-specific though, and we
would need to actually add support for a second certificate store. But that
would probably be a useful feature in itself.

Maybe. The impression I have is that it's very common for installations
to use a locally-run CA to generate server and client certs. I would not
expect them to put such certs into /etc/ssl/certs. But I suppose there
might be cases where you would actually pay for a universally-valid cert
for a DB server ...

No, that is very common. However, in non-enterprise uses it's also very
common for those to be Web PKI certificates, which would be very
inappropriate for use in PG, so I agree that PG should not use the
system trust anchor set by default. PG should just require that a trust
anchor set be configured.

Nico
--

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Nico Williams
nico@cryptonector.com
In reply to: Adrien Nayrat (#5)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 03, 2017 at 11:45:24AM +0200, Adrien Nayrat wrote:

On 10/03/2017 06:15 AM, Zeus Kronion wrote:

2) I was surprised to learn the following from the docs:

 By default, PostgreSQL will not perform any verification of the server

certificate. This means that it is possible to spoof the server identity (for
example by modifying a DNS record or by taking over the server IP address)
without the client knowing. In order to prevent spoofing, SSL certificate
verification must be used.

Is there a technical reason to perform no verification by default? Wouldn't a
safer default be desirable?

If you want to verify server's certificate you should use DANE [1] + DNSSEC [2]
? (I am not an SSL expert too)

If I understand correctly, you can store your certificate in a DNS record
(TLSA). Then the client can check the certificate. You must trust your DNS
server (protection against spoofing), that's why you have to use DNSSEC.

+1, but it's trickier than you might think. I can connect you with
Viktor Dukhovni, who has implemented DANE for OpenSSL, and done yeoman's
work getting DANE for SMTP working.

Nico
--

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Adrien Nayrat
adrien.nayrat@dalibo.com
In reply to: Nico Williams (#11)
Re: Possible SSL improvements for a newcomer to tackle

On 10/03/2017 05:47 PM, Nico Williams wrote:

+1, but it's trickier than you might think. I can connect you with
Viktor Dukhovni, who has implemented DANE for OpenSSL, and done yeoman's
work getting DANE for SMTP working.

I really appreciate, but I know it is very tricky :). I do not pretend to work
on this feature, I really do not have sufficient knowledge :/.

--
Adrien NAYRAT

#13Zeus Kronion
zkronion@gmail.com
In reply to: Nico Williams (#9)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 3, 2017 at 11:39 AM, Nico Williams <nico@cryptonector.com>
wrote:

On Tue, Oct 03, 2017 at 12:33:00AM -0400, Tom Lane wrote:

So to default to verification would be to default to failing to
connect at all until user has created a ~/.postgresql/root.crt file with
valid, relevant entries. That seems like a nonstarter.

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

Still, it would be safer to refuse to connect until the lack of trust
anchors is rectified than to connect without warning about the inability
to verify a server. By forcing the user (admins) to take action to
remediate the problem, the problem then gets fixed, whereas plowing on
creates an invisible (for many users) security problem.

I agree with Nico. If the server certificate can't be validated, the client
should fail to connect unless specifically opting out of MITM protection.
Why not change DefaultSSLMode from "prefer," even if it isn't backwards
compatible? Is there a policy for deprecating default settings?

#14Jeff Janes
jeff.janes@gmail.com
In reply to: Tom Lane (#2)
Re: Possible SSL improvements for a newcomer to tackle

On Mon, Oct 2, 2017 at 9:33 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

That is what we do. If root.crt exists, we default to verify-ca.

And yes, it is messy and unreliable. I don't know if it adds any security
or not.

Or do you mean we could default to verify-full instead of verify-ca?

Cheers,

Jeff

#15Nico Williams
nico@cryptonector.com
In reply to: Jeff Janes (#14)
Re: Possible SSL improvements for a newcomer to tackle

On Wed, Oct 04, 2017 at 11:47:45AM -0700, Jeff Janes wrote:

On Mon, Oct 2, 2017 at 9:33 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

It's possible that we could adopt some policy like "if the root.crt file
exists then default to verify" ... but that seems messy and unreliable,
so I'm not sure it would really add any security.

That is what we do. If root.crt exists, we default to verify-ca.

And yes, it is messy and unreliable. I don't know if it adds any security
or not.

Or do you mean we could default to verify-full instead of verify-ca?

I would rather psql defaulted to verify-full and let users deal with
errors by either a) configuring appropriate trust anchors and
provisioning appropriate certificates, or b) disabling verify-full.

Users should know that they are using psql(1) insecurely -- it has to be
obvious.

Yes, this would be a backwards-incompatible change, but security tends
to justify this sort of change.

Another possibility would be to make this default change only applicable
when using postgresql-scheme URIs (which I do, almost religiously --
they are much easier to use than all alternative connection data
specifications).

Nico
--

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Jeff Janes
jeff.janes@gmail.com
In reply to: Tom Lane (#6)
Re: Possible SSL improvements for a newcomer to tackle

On Tue, Oct 3, 2017 at 6:44 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Tue, Oct 3, 2017 at 6:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I'm not an SSL expert, so insert appropriate grain of salt, but AIUI the
question is what are you going to verify against?

One way to do it would be to default to the "system global certificate
store", which is what most other SSL apps do. For example on a typical
debian/ubuntu, that'd be the store in /etc/ssl/certs/ca-

certificates.crt.

Exactly where to find them would be distribution-specific though, and we
would need to actually add support for a second certificate store. But

that

would probably be a useful feature in itself.

Maybe. The impression I have is that it's very common for installations
to use a locally-run CA to generate server and client certs. I would not
expect them to put such certs into /etc/ssl/certs.

Well, I would do it that way if it worked. Not directly /etc/ssl/certs,
but /etc/pki/ca-trust/source/anchors/

I would like the locally-run CA to able to sign not just postgresql server
certs, but also apache server certs. And then install the CA cert file in
one place per client and have it work for psql, curl, wget, etc.

Cheers,

Jeff