Thread: Refuse SSL patch
PostgreSQL hackers, This patch allows the PostgreSQL server to refuse SSL connections selectively, and the clients to not initiate SSL connections. The point is for me to be able to choose non-SSL connections over SSL, even when SSL is available, for maximum performance. I've got a PostgreSQL server that has a separate private network link to an application server, and I want database connections there to always be non-SSL for speed. But I also connect to the same PostgreSQL instance from a remote site, and always want that connection to be SSL only for security. I haven't seen any previous mention of a similar patch, though I found the following idea proposed by Magnus Hagander which I like: > Perhaps we shuold replace PGREQUIRE_SSL with "PGSSLMODE", being: > 0 - Refuse SSL > 1 - Negotiate, Prefer non-SSL > 2 - Negotiate, Prefer SSL (default) > 3 - Require SSL http://archives.postgresql.org/pgsql-hackers/2000-08/msg00639.php He also notes the desire to be able to disable SSL for speed. Magnus's post was over two years ago and it doesn't appear anything along these lines was done. Since then the current setup of 'host'/'hostssl' in pg_hba.conf and the client connect option 'requiressl' is pretty firmly engrained, so to keep compatibility I added 'hostnossl' to pg_hba and a 'nossl' option to the client library. Patch against PostgreSQL 7.2.3 is attached. Is this useful to others? If you'd like me to make some changes to make it acceptable, please let me know. Thanks, Jon
Attachment
Jon Jensen <jon@endpoint.com> writes: > I haven't seen any previous mention of a similar patch, though I found the > following idea proposed by Magnus Hagander which I like: >> Perhaps we shuold replace PGREQUIRE_SSL with "PGSSLMODE", being: >> 0 - Refuse SSL >> 1 - Negotiate, Prefer non-SSL >> 2 - Negotiate, Prefer SSL (default) >> 3 - Require SSL Hm, I like that better than two independent boolean vars (it's not obvious which should override the other, or why); moreover it adds more functionality (your approach does not provide a way to do mode 1). For backwards compatibility, if PGSSLMODE is not set then you could look for PGREQUIRE_SSL, and assume mode 3 (rather than the default 2) if PGREQUIRE_SSL is set. It might be better to use keywords or mnemonics of some kind in place of these arbitrary numeric codes. No strong feeling about that. > Is this useful to others? If you'd like me to make some changes to make it > acceptable, please let me know. Patches to the relevant documentation would be a minimum requirement. (In looking at this, I observe the original patch neglected to document the PGREQUIRE_SSL environment variable; don't emulate that bad example.) regards, tom lane
On Mon, 9 Dec 2002, Tom Lane wrote: > Jon Jensen <jon@endpoint.com> writes: > > I haven't seen any previous mention of a similar patch, though I found the > > following idea proposed by Magnus Hagander which I like: > > >> Perhaps we shuold replace PGREQUIRE_SSL with "PGSSLMODE", being: > >> 0 - Refuse SSL > >> 1 - Negotiate, Prefer non-SSL > >> 2 - Negotiate, Prefer SSL (default) > >> 3 - Require SSL > > Hm, I like that better than two independent boolean vars (it's not > obvious which should override the other, or why); moreover it adds > more functionality (your approach does not provide a way to do mode 1). > For backwards compatibility, if PGSSLMODE is not set then you could look > for PGREQUIRE_SSL, and assume mode 3 (rather than the default 2) if > PGREQUIRE_SSL is set. I'm working on implementing this now. > It might be better to use keywords or mnemonics of some kind in place of > these arbitrary numeric codes. No strong feeling about that. I wish I could think of some decent keywords, but the concepts don't lend themselves well to short descriptions. I'll start with the numbers Magnus suggested, and we can switch to names for the modes later if we want. > > Is this useful to others? If you'd like me to make some changes to make it > > acceptable, please let me know. > > Patches to the relevant documentation would be a minimum requirement. Ok. Jon
Jon, I just documented the service/PGSERVICE capability in the CVS tree. It allows a pg_service.conf file that controls additional libpq connection options. In your app, you just do: connectdb("service=conn1") and "conn1" is looked up in pg_service.conf and it gets its other connection parameters from there. The code is already in 7.3. I just documented it, and changed auto-dbname setting to be active only when they don't specify a dbname. Also, I created a sample file called pg_service.conf.sample. This may provide a better way for you to control SSL rather than changing PGREQUIRE_SSL, which was also recently documented in the CVS tree. I don't think overloading REQUIRE to mean something else is really the way to go. Looking at your options, we have: > > 0 - Refuse SSL Hard to imagine why someone would pick this one. > > 1 - Negotiate, Prefer non-SSL This is the only new valid one. My question is why you would specify ssl on the host if you don't need ssl? > > 2 - Negotiate, Prefer SSL (default) Already the default for no requiressl. > > 3 - Require SSL Already requiressl. If the problem is that some apps need requiressl and others don't, I think the service file may be your cleanest option. --------------------------------------------------------------------------- Jon Jensen wrote: > PostgreSQL hackers, > > This patch allows the PostgreSQL server to refuse SSL connections > selectively, and the clients to not initiate SSL connections. > > The point is for me to be able to choose non-SSL connections over SSL, > even when SSL is available, for maximum performance. I've got a PostgreSQL > server that has a separate private network link to an application server, > and I want database connections there to always be non-SSL for speed. But > I also connect to the same PostgreSQL instance from a remote site, and > always want that connection to be SSL only for security. > > I haven't seen any previous mention of a similar patch, though I found the > following idea proposed by Magnus Hagander which I like: > > > Perhaps we shuold replace PGREQUIRE_SSL with "PGSSLMODE", being: > > 0 - Refuse SSL > > 1 - Negotiate, Prefer non-SSL > > 2 - Negotiate, Prefer SSL (default) > > 3 - Require SSL > > http://archives.postgresql.org/pgsql-hackers/2000-08/msg00639.php > > He also notes the desire to be able to disable SSL for speed. > > Magnus's post was over two years ago and it doesn't appear anything along > these lines was done. Since then the current setup of 'host'/'hostssl' in > pg_hba.conf and the client connect option 'requiressl' is pretty firmly > engrained, so to keep compatibility I added 'hostnossl' to pg_hba and a > 'nossl' option to the client library. > > Patch against PostgreSQL 7.2.3 is attached. > > Is this useful to others? If you'd like me to make some changes to make it > acceptable, please let me know. > > Thanks, > Jon Content-Description: [ Attachment, skipping... ] Content-Description: [ Attachment, skipping... ] > > ---------------------------(end of broadcast)--------------------------- > TIP 3: if posting/reading through Usenet, please send an appropriate > subscribe-nomail command to majordomo@postgresql.org so that your > message can get through to the mailing list cleanly -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
On Tue, 7 Jan 2003, Bruce Momjian wrote: > Jon, I just documented the service/PGSERVICE capability in the CVS tree. > It allows a pg_service.conf file that controls additional libpq > connection options. In your app, you just do: > > connectdb("service=conn1") > > and "conn1" is looked up in pg_service.conf and it gets its other > connection parameters from there. The code is already in 7.3. I just > documented it, and changed auto-dbname setting to be active only when > they don't specify a dbname. Also, I created a sample file called > pg_service.conf.sample. > > This may provide a better way for you to control SSL rather than > changing PGREQUIRE_SSL, which was also recently documented in the CVS > tree. I will take a look at the pg_service.conf file. > I don't think overloading REQUIRE to mean something else is really the > way to go. Looking at your options, we have: > > > > 0 - Refuse SSL > > Hard to imagine why someone would pick this one. But this is the exact reason I started my patch -- I need a server that can do SSL to allow *only* SSL connections to an off-site IP address, but *only* non-SSL connections to an internal IP address on a private network. Speed would suffer greatly if I were to allow SSL connections internally, but security would suffer if I disabled all SSL connections. > > > 1 - Negotiate, Prefer non-SSL > > This is the only new valid one. My question is why you would specify ssl > on the host if you don't need ssl? This is the one I don't see much need for, but I don't want to second-guess people's needs if I can help it. Might as well put in all the possibilities. > > > 2 - Negotiate, Prefer SSL (default) > > Already the default for no requiressl. > > > > 3 - Require SSL > > Already requiressl. > > If the problem is that some apps need requiressl and others don't, I > think the service file may be your cleanest option. I hadn't heard of that before you checked in the docs patch yesterday, so I'll check it out. Thanks, Jon
Jon Jensen wrote: > > I don't think overloading REQUIRE to mean something else is really the > > way to go. Looking at your options, we have: > > > > > > 0 - Refuse SSL > > > > Hard to imagine why someone would pick this one. > > But this is the exact reason I started my patch -- I need a server that > can do SSL to allow *only* SSL connections to an off-site IP address, but > *only* non-SSL connections to an internal IP address on a private network. > Speed would suffer greatly if I were to allow SSL connections internally, > but security would suffer if I disabled all SSL connections. But doesn't pg_hba.conf do that already, in that you say 'host' for the local ip, but ssl for the remote ip's? The only value I see to the existing REQUIRESSL is to say "I am a client and only want to do SSL", and in that case you can use the services file to use the same binary on different hosts, and control whether you want that host to require SSL or not. It doesn't make the switching based on who the host is connecting to, but your proposal doesn't do that either. I have to say I am just still confused over this. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
On Tue, 7 Jan 2003, Bruce Momjian wrote: > Jon Jensen wrote: > > > I don't think overloading REQUIRE to mean something else is really the > > > way to go. Looking at your options, we have: > > > > > > > > 0 - Refuse SSL > > > > > > Hard to imagine why someone would pick this one. > > > > But this is the exact reason I started my patch -- I need a server that > > can do SSL to allow *only* SSL connections to an off-site IP address, but > > *only* non-SSL connections to an internal IP address on a private network. > > Speed would suffer greatly if I were to allow SSL connections internally, > > but security would suffer if I disabled all SSL connections. > > But doesn't pg_hba.conf do that already, in that you say 'host' for the > local ip, but ssl for the remote ip's? The proposed SSLMODE is a client-side configuration option to supercede REQUIRESSL, which is also a client configuration option. Here's the problem: 1. The client always tries to connect via SSL if SSL support was compiled in. There is no way to change this presently. 2. If the server can do SSL *at all*, it negotiates an SSL connection with the client. 3. End of story -- we have an SSL connection when I don't want one. The only way around it is to have the server have no SSL support at all. So it's a client problem. The client needs to be configured to not try an SSL connection at all, when I don't want it to. Hence SSLMODE=0, which means forbid SSL. But on the other hand, we want some control on the server as well -- we may want to disallow SSL connections from a certain IP address, if nothing else just to make sure a client doesn't accidentally use SSL over the local network because someone forgets not to use it. Otherwise we could be accidentally using SSL on the local network and killing performance. So I added a 'hostnossl' option to pg_hba.conf, which will allow only non-SSL connections from certain IP addresses. Only the client changes are really necessary for my setup to work, but the server change allows me to guarantee that other developers don't accidentally connect via SSL when it's not wanted. Does that make more sense? Jon
On Tue, Jan 07, 2003 at 16:04:45 +0000, Jon Jensen <jon@endpoint.com> wrote: > > 1. The client always tries to connect via SSL if SSL support was compiled > in. There is no way to change this presently. > 2. If the server can do SSL *at all*, it negotiates an SSL connection with > the client. Can't you use a "reject" hostssl line in hba.conf to keep SSL connections from working for particular IP addresses? Does the client not fall back in this case?
Bruno Wolff III <bruno@wolff.to> writes: > Can't you use a "reject" hostssl line in hba.conf to keep SSL connections > from working for particular IP addresses? Does the client not fall back > in this case? I think it won't --- the fallback is only at the initial attempt to open the connection, not if the startup packet is rejected. A more global question is whether the overhead of SSL is really large enough to justify any concern about avoiding it. I have never measured it, but even a local LAN is a lot slower than modern CPUs. It doesn't seem to me to be a foregone conclusion that we need to worry about providing a way to avoid it. regards, tom lane
On Tue, 7 Jan 2003, Bruno Wolff III wrote: > On Tue, Jan 07, 2003 at 16:04:45 +0000, > Jon Jensen <jon@endpoint.com> wrote: > > > > 1. The client always tries to connect via SSL if SSL support was compiled > > in. There is no way to change this presently. > > 2. If the server can do SSL *at all*, it negotiates an SSL connection with > > the client. > > Can't you use a "reject" hostssl line in hba.conf to keep SSL connections > from working for particular IP addresses? Does the client not fall back > in this case? No, the client doesn't fall back if it makes a successful connection to the server in SSL mode, but the server denies access. It only falls back if the server can't do SSL at all. And in any case, that still wouldn't allow me to decide on the client side whether I want SSL or not, on a per-connection basis, because the client always chooses SSL. Jon
Jon Jensen wrote: > > But doesn't pg_hba.conf do that already, in that you say 'host' for the > > local ip, but ssl for the remote ip's? > > The proposed SSLMODE is a client-side configuration option to supercede > REQUIRESSL, which is also a client configuration option. Here's the > problem: > > 1. The client always tries to connect via SSL if SSL support was compiled > in. There is no way to change this presently. > 2. If the server can do SSL *at all*, it negotiates an SSL connection with > the client. Oh, that is a key thing I didn't know. Seems we should just add a libpq PREVENTSSL option and be done with it. Seems clearer than numbers, and hits the most useful functionality. If they set REQUIRESSL and PREVENTSSL, we throw an error. Right now, if they set 'host' in pg_hba.conf, and the client knows SSL, we use it. Your idea had the additional functionality of preferring non-SSL if the server knew SSL but had 'host' in pg_hba.conf. > But on the other hand, we want some control on the server as well -- we > may want to disallow SSL connections from a certain IP address, if nothing > else just to make sure a client doesn't accidentally use SSL over the > local network because someone forgets not to use it. Otherwise we could be > accidentally using SSL on the local network and killing performance. So I > added a 'hostnossl' option to pg_hba.conf, which will allow only non-SSL > connections from certain IP addresses. Perhaps your idea of 'hostnossl' in pg_hba.conf is a good one. That way, both client and server would have the ability to say never or only SSL. It allows more central control. So, in negotiation, that only leaves open the question of what happens when none of those are set, and it seems we prefer SSL in such cases. Is that the correct default? In fact, once we have 'hostnossl' why do we need PREVENTSSL in libpq? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
On Tue, 7 Jan 2003, Tom Lane wrote: > Bruno Wolff III <bruno@wolff.to> writes: > > Can't you use a "reject" hostssl line in hba.conf to keep SSL connections > > from working for particular IP addresses? Does the client not fall back > > in this case? > > I think it won't --- the fallback is only at the initial attempt to open > the connection, not if the startup packet is rejected. That's right. > A more global question is whether the overhead of SSL is really large > enough to justify any concern about avoiding it. I have never measured > it, but even a local LAN is a lot slower than modern CPUs. It doesn't > seem to me to be a foregone conclusion that we need to worry about > providing a way to avoid it. Not at all. SSL has significant overhead. Here's a quick test that runs three SELECT queries returning about 50,000 rows: bash-2.05$ time ./timeit real 0m10.527s user 0m5.290s sys 0m0.420s bash-2.05$ time ./timeit nossl=1 real 0m6.947s user 0m1.720s sys 0m0.350s This is with a client and server on separate machines on the same local network, each with 2+ GB RAM and Xeon 2.4 GHz processors (dual, though that's not relevant). The slowdown will be worse with slower CPUs, of course. I can't imagine why I'd want to tolerate wasting CPU on both ends of the connection and slowing down data transfer, when my original purpose in moving the database off the app server box was to increase capacity. I will of course continue using my working patched versions of PostgreSQL that allow me the flexibility of deciding on client and server whether I will talk via SSL or not. My question is whether the mainline PostgreSQL software will give users the same flexibility. I'll finish up my SSLMODE patch and submit it, and it's up to you all from there. Jon
On Tue, 7 Jan 2003, Bruce Momjian wrote: > > The proposed SSLMODE is a client-side configuration option to supercede > > REQUIRESSL, which is also a client configuration option. Here's the > > problem: > > > > 1. The client always tries to connect via SSL if SSL support was compiled > > in. There is no way to change this presently. > > 2. If the server can do SSL *at all*, it negotiates an SSL connection with > > the client. > > Oh, that is a key thing I didn't know. Seems we should just add a libpq > PREVENTSSL option and be done with it. That's exactly what my original patch did! :) Tom thought that having conflicting REFUSESSL and REQUIRESSL directives would be confusing, and since I dug up someone's old discussion in the list archives of the four possible modes, we could move to that. > > But on the other hand, we want some control on the server as well -- we > > may want to disallow SSL connections from a certain IP address, if nothing > > else just to make sure a client doesn't accidentally use SSL over the > > local network because someone forgets not to use it. Otherwise we could be > > accidentally using SSL on the local network and killing performance. So I > > added a 'hostnossl' option to pg_hba.conf, which will allow only non-SSL > > connections from certain IP addresses. > > Perhaps your idea of 'hostnossl' in pg_hba.conf is a good one. That > way, both client and server would have the ability to say never or only > SSL. It allows more central control. > > So, in negotiation, that only leaves open the question of what happens > when none of those are set, and it seems we prefer SSL in such cases. > Is that the correct default? > > In fact, once we have 'hostnossl' why do we need PREVENTSSL in libpq? Because hostnossl is only an authentication control, not a connection control. libpq will *always* connect SSL if it can, which guarantees that the authentication will fail with hostnossl. We have to have configuration options on both ends to make this work. Jon
Jon Jensen wrote: > On Tue, 7 Jan 2003, Bruce Momjian wrote: > > > > The proposed SSLMODE is a client-side configuration option to supercede > > > REQUIRESSL, which is also a client configuration option. Here's the > > > problem: > > > > > > 1. The client always tries to connect via SSL if SSL support was compiled > > > in. There is no way to change this presently. > > > 2. If the server can do SSL *at all*, it negotiates an SSL connection with > > > the client. > > > > Oh, that is a key thing I didn't know. Seems we should just add a libpq > > PREVENTSSL option and be done with it. > > That's exactly what my original patch did! :) > > Tom thought that having conflicting REFUSESSL and REQUIRESSL directives > would be confusing, and since I dug up someone's old discussion in the > list archives of the four possible modes, we could move to that. Oh. I find two params clearer than one with meaningless numbers. :-) > > > But on the other hand, we want some control on the server as well -- we > > > may want to disallow SSL connections from a certain IP address, if nothing > > > else just to make sure a client doesn't accidentally use SSL over the > > > local network because someone forgets not to use it. Otherwise we could be > > > accidentally using SSL on the local network and killing performance. So I > > > added a 'hostnossl' option to pg_hba.conf, which will allow only non-SSL > > > connections from certain IP addresses. > > > > Perhaps your idea of 'hostnossl' in pg_hba.conf is a good one. That > > way, both client and server would have the ability to say never or only > > SSL. It allows more central control. > > > > So, in negotiation, that only leaves open the question of what happens > > when none of those are set, and it seems we prefer SSL in such cases. > > Is that the correct default? > > > > In fact, once we have 'hostnossl' why do we need PREVENTSSL in libpq? > > Because hostnossl is only an authentication control, not a connection > control. libpq will *always* connect SSL if it can, which guarantees that > the authentication will fail with hostnossl. We have to have configuration > options on both ends to make this work. Well, your 0-3 valued patch must have had some code that fell back to non-SSL when SSL failed. Can't we do that by default? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
Bruce Momjian writes: > > Tom thought that having conflicting REFUSESSL and REQUIRESSL directives > > would be confusing, and since I dug up someone's old discussion in the > > list archives of the four possible modes, we could move to that. > > Oh. I find two params clearer than one with meaningless numbers. :-) But the numeric model provides four modes (refuse ssl, prefer no ssl, prefer ssl, require ssl) whereas the refuse/require combination only provides three modes (refuse ssl, require ssl, and one other depending on how you define it when neither is set). If you don't like numbers, make them words. -- Peter Eisentraut peter_e@gmx.net
Peter Eisentraut wrote: > Bruce Momjian writes: > > > > Tom thought that having conflicting REFUSESSL and REQUIRESSL directives > > > would be confusing, and since I dug up someone's old discussion in the > > > list archives of the four possible modes, we could move to that. > > > > Oh. I find two params clearer than one with meaningless numbers. :-) > > But the numeric model provides four modes (refuse ssl, prefer no ssl, > prefer ssl, require ssl) whereas the refuse/require combination only > provides three modes (refuse ssl, require ssl, and one other depending on > how you define it when neither is set). If you don't like numbers, make > them words. OK, that works: require prevent prefer noprefer This allows us to subsume PGREQUIRE_SSL into the new variable. Do we still need additional functionality in pg_hba.conf? I am only asking if pushing these decisions out to the client makes sense? For performance reasons, it is good to push this information out to the clients so the proper connection method is used the first time. However, for easier maintenance, we could have all of this in pg_hba.conf only, and have clients try SSL first, and fall back to non-SSL if the server doesn't want SSL. It would require two new pg_hba.conf line types. We have prefer-SSL (host) and SSL-only (ssl) now. require (ssl) prevent (nossl) prefer (hostpreferssl) noprefer(host) This would change 'host' to not prefer SSL. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073