Thread: Re: [HACKERS] SSL over Unix-domain sockets

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Bruce Momjian wrote:
> Tom Lane wrote:
> > Conclusions:
> >
> > * SSL, even without real authentication, is *way* too expensive to
> > enable by default.
> >
> > * The extra cost of going across a local TCP connection is measurable,
> > but it's insignificant compared to the cost of turning on SSL.  (This
> > is on a Fedora 8 kernel BTW ... that result might vary on other
> > platforms.)
> >
> > So you could make a pretty good case that the answer for DBAs who
> > want to prevent spoofing is to disable socket connections in pg_hba.conf
> > and force even local connections to come through "hostssl" connections.
>
> Yea, I figured using protected directories for the socket was the
> zero-cost solution, and if you have to do SSL, might as well just use
> TCP too.  (If you moved the socket file to a protected directory I think
> you could use external_pid_file='/tmp/.s.PGSQL.5432' to prevent a spoof
> socket file in /tmp.  Should we document that idea?)

I did some research on this.  external_pid_file will not prevent the
server from starting.  If the lock file exists it just generates an
entry in the log file:

    postmaster: could not write external PID file "/tmp/x": Permission denied

Looking at the threat matrix, we have:

    Server        Client        Server Up?    Spoofable?
    /tmp        /tmp        Y        N
    /tmp        /tmp        N        Y
    $HOME        $HOME        Y        N
    $HOME        $HOME        N        N
    $HOME        /tmp        Y        N
    $HOME        /tmp        N        Y

Basically, if you use a user-specific directory for the server socket
file ($HOME) and an external_pid_file, the only way for the client to be
spoofed is for the client to be using /tmp _and_ for the server to be
down.

I assume most new applications will be tested while the server is up and
therefore will fail and the client will be fixed.

I have written the following documentation addition suggesting the use
of external_pid_file.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v
retrieving revision 1.402
diff -c -c -r1.402 runtime.sgml
*** doc/src/sgml/runtime.sgml    8 Jan 2008 18:07:38 -0000    1.402
--- doc/src/sgml/runtime.sgml    17 Jan 2008 00:20:36 -0000
***************
*** 1397,1405 ****
     connections is to use a Unix domain socket directory (<xref
     linkend="guc-unix-socket-directory">) that has write permission only
     for a trusted local user.  This prevents a malicious user from creating
!    their own socket file in that directory.  For TCP connections the server
!    must accept only <literal>hostssl</> connections (<xref
!    linkend="auth-pg-hba-conf">) and have SSL
     <filename>server.key</filename> (key) and
     <filename>server.crt</filename> (certificate) files (<xref
     linkend="ssl-tcp">). The TCP client must connect using
--- 1397,1413 ----
     connections is to use a Unix domain socket directory (<xref
     linkend="guc-unix-socket-directory">) that has write permission only
     for a trusted local user.  This prevents a malicious user from creating
!    their own socket file in that directory.
!    Additionally, you might want to set <xref
!    linkend="guc-external-pid-file"> to <literal>/tmp/.s.PGSQL.5432</> to
!    prevent spoofing for clients looking for the socket in its default
!    location.  This protection is only effective while the server is
!    running.
!   </para>
!
!   <para>
!    For TCP connections the server must accept only <literal>hostssl</>
!    connections (<xref linkend="auth-pg-hba-conf">) and have SSL
     <filename>server.key</filename> (key) and
     <filename>server.crt</filename> (certificate) files (<xref
     linkend="ssl-tcp">). The TCP client must connect using

Re: [HACKERS] SSL over Unix-domain sockets

From
Peter Eisentraut
Date:
Bruce Momjian wrote:
> I have written the following documentation addition suggesting the use
> of external_pid_file.

How does that prevent spoofing?

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Bruce Momjian wrote:
> > I have written the following documentation addition suggesting the use
> > of external_pid_file.
>
> How does that prevent spoofing?

It creates a lock file that is the same name as the socket file that a
default-configured client would use, so it prevents a spoofed socket
from being created.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: [HACKERS] SSL over Unix-domain sockets

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> Peter Eisentraut wrote:
>> How does that prevent spoofing?

> It creates a lock file that is the same name as the socket file that a
> default-configured client would use, so it prevents a spoofed socket
> from being created.

Only if the attacker didn't get there first.  I think this idea is
nothing but a crude kluge anyway...

            regards, tom lane

Re: [HACKERS] SSL over Unix-domain sockets

From
Andrew Dunstan
Date:

Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
>
>> Peter Eisentraut wrote:
>>
>>> How does that prevent spoofing?
>>>
>
>
>> It creates a lock file that is the same name as the socket file that a
>> default-configured client would use, so it prevents a spoofed socket
>> from being created.
>>
>
> Only if the attacker didn't get there first.  I think this idea is
> nothing but a crude kluge anyway...
>
>

I agree. I remain of the opinion that this is not a problem than can be
solved purely within the bounds of postgres.

cheers

andrew

Re: [HACKERS] SSL over Unix-domain sockets

From
Alvaro Herrera
Date:
Andrew Dunstan wrote:

> I agree. I remain of the opinion that this is not a problem than can be
> solved purely within the bounds of postgres.

I agree.  Please comment on my proposed solution.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

Re: [HACKERS] SSL over Unix-domain sockets

From
Andrew Dunstan
Date:

Alvaro Herrera wrote:
> Andrew Dunstan wrote:
>
>
>> I agree. I remain of the opinion that this is not a problem than can be
>> solved purely within the bounds of postgres.
>>
>
> I agree.  Please comment on my proposed solution.
>
>

I'm not sure tmp cleaners will work that well against a determined spoofer.

cheers

andrew

Re: [HACKERS] SSL over Unix-domain sockets

From
Alvaro Herrera
Date:
Andrew Dunstan wrote:
>
>
> Alvaro Herrera wrote:
>> Andrew Dunstan wrote:
>>
>>
>>> I agree. I remain of the opinion that this is not a problem than can be
>>> solved purely within the bounds of postgres.
>>
>> I agree.  Please comment on my proposed solution.
>
> I'm not sure tmp cleaners will work that well against a determined spoofer.

I don't understand.  The tmp cleaner is something we have to _avoid_.
Let me repeat my proposal.

I propose to create a dangling symlink on system startup in
/tmp/.s.PGSQL.<port> to the real socket, which is not on a
world-writable directory.  This avoids the spoofer, because he cannot
create the socket -- the symlink is occupying its place.

The only problem with this proposal is that the tmp cleaner would remove
the symlink.  The solution to this is to configure the tmp cleaner so
that it doesn't do that.

It absolutely requires cooperation from the sysadmin, both to setup the
symlink initially, and to configure the tmp cleaner.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Re: [HACKERS] SSL over Unix-domain sockets

From
Tom Lane
Date:
Alvaro Herrera <alvherre@commandprompt.com> writes:
> I propose to create a dangling symlink on system startup in
> /tmp/.s.PGSQL.<port> to the real socket, which is not on a
> world-writable directory.  This avoids the spoofer, because he cannot
> create the socket -- the symlink is occupying its place.

> The only problem with this proposal is that the tmp cleaner would remove
> the symlink.  The solution to this is to configure the tmp cleaner so
> that it doesn't do that.

> It absolutely requires cooperation from the sysadmin, both to setup the
> symlink initially, and to configure the tmp cleaner.

This is definitely a slick solution if you can overcome the tmp-cleaner
risk; not least because it doesn't require any work on our part ;-).
However, we should document the approach someplace.

Further down the road we could think about Postgres changes to support
such a strategy --- for instance, having the postmaster check to see
if such a link exists.  This will require more thought than we have
time for for 8.3; also I think we'd need to negotiate with packagers,
such as the Debian crew, to make sure any such behavior is acceptable
to them.

BTW, is a symlink's atime changed by accessing it?  We could imagine
adapting the existing postmaster code that keeps the socket atime fresh
so that it will work on a symlink, thus providing partial protection
against tmp-cleaners.  Portability of this is uncertain...

            regards, tom lane

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Alvaro Herrera wrote:
> > I'm not sure tmp cleaners will work that well against a determined spoofer.
>
> I don't understand.  The tmp cleaner is something we have to _avoid_.
> Let me repeat my proposal.
>
> I propose to create a dangling symlink on system startup in
> /tmp/.s.PGSQL.<port> to the real socket, which is not on a

I am confused because you say "dangling" then you say "to the real
socket".  You are saying it isn't dangling when the server is running?

> world-writable directory.  This avoids the spoofer, because he cannot
> create the socket -- the symlink is occupying its place.
>
> The only problem with this proposal is that the tmp cleaner would remove
> the symlink.  The solution to this is to configure the tmp cleaner so
> that it doesn't do that.
>
> It absolutely requires cooperation from the sysadmin, both to setup the
> symlink initially, and to configure the tmp cleaner.

If you are going to require the admin to modify the tmp cleanup script,
the admin might as well create the symlink at the same time and have it
recreate on boot.  We could actually just document this idea and be done
with it.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Bruce Momjian wrote:
> Alvaro Herrera wrote:
> > > I'm not sure tmp cleaners will work that well against a determined spoofer.
> >
> > I don't understand.  The tmp cleaner is something we have to _avoid_.
> > Let me repeat my proposal.
> >
> > I propose to create a dangling symlink on system startup in
> > /tmp/.s.PGSQL.<port> to the real socket, which is not on a
>
> I am confused because you say "dangling" then you say "to the real
> socket".  You are saying it isn't dangling when the server is running?
>
> > world-writable directory.  This avoids the spoofer, because he cannot
> > create the socket -- the symlink is occupying its place.
> >
> > The only problem with this proposal is that the tmp cleaner would remove
> > the symlink.  The solution to this is to configure the tmp cleaner so
> > that it doesn't do that.
> >
> > It absolutely requires cooperation from the sysadmin, both to setup the
> > symlink initially, and to configure the tmp cleaner.
>
> If you are going to require the admin to modify the tmp cleanup script,
> the admin might as well create the symlink at the same time and have it
> recreate on boot.  We could actually just document this idea and be done
> with it.

Oh, sorry, I see now you are having the admin create the symlink and
modify the tmp cleaner --- yea, I think we just document this and call
it done.

Do we do anything in the backend for this proposal?

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: [HACKERS] SSL over Unix-domain sockets

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> I am confused because you say "dangling" then you say "to the real
> socket".  You are saying it isn't dangling when the server is running?

Exactly.  When the server is running it provides a perfectly good path
to the postmaster.  The point (and the main difference from your PIDfile
proposal) is that it's supposed to be there all the time, even when the
postmaster isn't running.  This is what provides protection against the
spoofer getting there first.

> If you are going to require the admin to modify the tmp cleanup script,
> the admin might as well create the symlink at the same time and have it
> recreate on boot.

No, that's not the same, because it doesn't provide protection against
the symlink getting deleted later on.

            regards, tom lane

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > I am confused because you say "dangling" then you say "to the real
> > socket".  You are saying it isn't dangling when the server is running?
>
> Exactly.  When the server is running it provides a perfectly good path
> to the postmaster.  The point (and the main difference from your PIDfile
> proposal) is that it's supposed to be there all the time, even when the
> postmaster isn't running.  This is what provides protection against the
> spoofer getting there first.

OK, got it.

> > If you are going to require the admin to modify the tmp cleanup script,
> > the admin might as well create the symlink at the same time and have it
> > recreate on boot.
>
> No, that's not the same, because it doesn't provide protection against
> the symlink getting deleted later on.

Right, so you have to modify the tmp cleaner and create the symlink, right?

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: [HACKERS] SSL over Unix-domain sockets

From
Andrew Dunstan
Date:

Alvaro Herrera wrote:
> Andrew Dunstan wrote:
>
>> Alvaro Herrera wrote:
>>
>>> Andrew Dunstan wrote:
>>>
>>>
>>>
>>>> I agree. I remain of the opinion that this is not a problem than can be
>>>> solved purely within the bounds of postgres.
>>>>
>>> I agree.  Please comment on my proposed solution.
>>>
>> I'm not sure tmp cleaners will work that well against a determined spoofer.
>>
>
> I don't understand.  The tmp cleaner is something we have to _avoid_.
> Let me repeat my proposal.
>
> I propose to create a dangling symlink on system startup in
> /tmp/.s.PGSQL.<port> to the real socket, which is not on a
> world-writable directory.  This avoids the spoofer, because he cannot
> create the socket -- the symlink is occupying its place.
>
> The only problem with this proposal is that the tmp cleaner would remove
> the symlink.  The solution to this is to configure the tmp cleaner so
> that it doesn't do that.
>
> It absolutely requires cooperation from the sysadmin, both to setup the
> symlink initially, and to configure the tmp cleaner.
>

Oh. I'm sorry. Yes, I think this would work.

cheers

andrew

Re: [HACKERS] SSL over Unix-domain sockets

From
Greg Smith
Date:
On Thu, 17 Jan 2008, Tom Lane wrote:

> BTW, is a symlink's atime changed by accessing it?

It seems so in the cases I've tried or researched, but it's complicated.
After burning through a bunch of time looking into this I wanted to drop
some notes so nobody else has to wander down the specific dead-ends I just
followed.

I figured I'd just run some experiments to figure this out for my Linux
system, but that didn't go so well.  The process of running anything that
shows the atime:

   ls -l --time=atime <file>
   ls -lu <file>
   stat <file>

actually updates the atime to right now along the way.  I hacked up
something with perl that directly calls lstat() and it did the same thing.

Mystified, I found this thread suggesting the same thing is true on Mac OS
X:  http://lists.apple.com/archives/darwin-kernel/2006/Dec/msg00054.html

The point made in there is that how symlinks are encoded varies not just
from OS to OS but from filesystem to filesystem, and that encoding changes
how things like atime work.  On Linux with ext2, I found this note:

"Symbolic links are also filesystem objects with inodes.  They deserve
special mention because the data for them is stored within the inode
itself if the symlink is less than 60 bytes long.  It uses the fields
which would normally be used to store the pointers to data blocks."

So what I think is happening is:  the process of doing anything at all
with a Linux symlink references the inode that has the link.  That updates
the atime on that inode.  But since there's no actual data underneath that
lookup in cases where the link is less than 60 bytes, the inode atime is
the link atime, so that just updated the link's atime to right now as
well.  I have no idea how any tmp cleaner could ever find a short symlink
it can delete if I'm understanding this correctly.

I left behind the link I was just playing with and I'll see if I can get
tmpwatch to eat it tomorrow, that seems like the most appropriate test
here.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

Re: [HACKERS] SSL over Unix-domain sockets

From
Peter Eisentraut
Date:
Am Donnerstag, 17. Januar 2008 schrieb Bruce Momjian:
> It creates a lock file that is the same name as the socket file that a
> default-configured client would use, so it prevents a spoofed socket
> from being created.

A counter-spoofing solution must be implemented in the client.  No moving
around of files by the server will ever solve the problem.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: [HACKERS] SSL over Unix-domain sockets

From
Peter Eisentraut
Date:
Am Donnerstag, 17. Januar 2008 schrieb Andrew Dunstan:
> I agree. I remain of the opinion that this is not a problem than can be
> solved purely within the bounds of postgres.

Well, the SSL patch I showed certainly solves the problem.  (I am not saying
it is the best possible solution.)  Of course there also need to be prudent
users, but that is the case for any security system.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: [HACKERS] SSL over Unix-domain sockets

From
Peter Eisentraut
Date:
Am Freitag, 18. Januar 2008 schrieb Alvaro Herrera:
> I propose to create a dangling symlink on system startup in
> /tmp/.s.PGSQL.<port> to the real socket, which is not on a
> world-writable directory.  This avoids the spoofer, because he cannot
> create the socket -- the symlink is occupying its place.

This approaches the issue from the wrong end.  Spoofing attacks the client, so
the defense must be in the client.  If the defense of the client is to rely
on a carefully configured server, then that might exclude some possible
attack vectors, but it is not a defense the client can rely on.

To look at this in another way, if we relied on every browser user to type in
web addresses correctly and all server administrators to make sure
their "socket address" cannot be hijacked, we wouldn't need SSL on the web.
The proper approach, however, is to configure the client to only talk to
servers that can prove their identity.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: [HACKERS] SSL over Unix-domain sockets

From
Magnus Hagander
Date:
On Fri, Jan 18, 2008 at 11:24:09AM +0100, Peter Eisentraut wrote:
> Am Donnerstag, 17. Januar 2008 schrieb Andrew Dunstan:
> > I agree. I remain of the opinion that this is not a problem than can be
> > solved purely within the bounds of postgres.
>
> Well, the SSL patch I showed certainly solves the problem.  (I am not saying
> it is the best possible solution.)  Of course there also need to be prudent
> users, but that is the case for any security system.

Not that much more than moving the socket file to a secure directory. Both
rely on configuring the client properly. It's arguably a lot easier to
configure the client to connect to the correct socket, than to make sure
the client has a root certificate installed.

//Magnus

Re: [HACKERS] SSL over Unix-domain sockets

From
Peter Eisentraut
Date:
Am Freitag, 18. Januar 2008 schrieb Magnus Hagander:
> Not that much more than moving the socket file to a secure directory. Both
> rely on configuring the client properly. It's arguably a lot easier to
> configure the client to connect to the correct socket, than to make sure
> the client has a root certificate installed.

How would a client check whether the socket file is in a secure location?

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: [HACKERS] SSL over Unix-domain sockets

From
Magnus Hagander
Date:
On Fri, Jan 18, 2008 at 12:35:40PM +0100, Peter Eisentraut wrote:
> Am Freitag, 18. Januar 2008 schrieb Magnus Hagander:
> > Not that much more than moving the socket file to a secure directory. Both
> > rely on configuring the client properly. It's arguably a lot easier to
> > configure the client to connect to the correct socket, than to make sure
> > the client has a root certificate installed.
>
> How would a client check whether the socket file is in a secure location?

The same way it would get the root certificate to trust - it would be told
so by the administrator who had secured the location.

//Magnus

Re: [HACKERS] SSL over Unix-domain sockets

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > I am confused because you say "dangling" then you say "to the real
> > socket".  You are saying it isn't dangling when the server is running?
>
> Exactly.  When the server is running it provides a perfectly good path
> to the postmaster.  The point (and the main difference from your PIDfile
> proposal) is that it's supposed to be there all the time, even when the
> postmaster isn't running.  This is what provides protection against the
> spoofer getting there first.

OK, I have added documention suggesting the creation a symbolic link in
/tmp to prevent server spoofing when the socket file has been moved.

I think we can consider this issue concluded.  I think SSL over unix
domain sockets has so much overhead as to be worse in most cases than
just creating the symlink.

Of course if someone comes up with a better idea we can reopen this.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://postgres.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v
retrieving revision 1.403
diff -c -c -r1.403 runtime.sgml
*** doc/src/sgml/runtime.sgml    24 Jan 2008 06:23:32 -0000    1.403
--- doc/src/sgml/runtime.sgml    31 Jan 2008 17:21:57 -0000
***************
*** 1397,1403 ****
     connections is to use a Unix domain socket directory (<xref
     linkend="guc-unix-socket-directory">) that has write permission only
     for a trusted local user.  This prevents a malicious user from creating
!    their own socket file in that directory.  For TCP connections the server
     must accept only <literal>hostssl</> connections (<xref
     linkend="auth-pg-hba-conf">) and have SSL
     <filename>server.key</filename> (key) and
--- 1397,1412 ----
     connections is to use a Unix domain socket directory (<xref
     linkend="guc-unix-socket-directory">) that has write permission only
     for a trusted local user.  This prevents a malicious user from creating
!    their own socket file in that directory.  If you are concerned that
!    some applications might still look in <filename>/tmp</> for the
!    socket file and hence be vulnerable to spoofing, create a symbolic link
!    during operating system startup in <filename>/tmp</> that points to
!    the relocated socket file.  You also might need to modify your
!    <filename>/tmp</> cleanup script to preserve the symbolic link.
!   </para>
!
!   <para>
!    For TCP connections the server
     must accept only <literal>hostssl</> connections (<xref
     linkend="auth-pg-hba-conf">) and have SSL
     <filename>server.key</filename> (key) and