Thread: Unix socket dir, an idea

Unix socket dir, an idea

From
Danylo Hlynskyi
Date:
Before writing a patch, I'd like to hear discussion first.

I've searched archives first and read following previous discussions on this topic:
- https://www.postgresql.org/message-id/4FCF6040.5030408%40redhat.com
- https://www.postgresql.org/message-id/14899.974513046%40sss.pgh.pa.us

The problem (as I see it) is that everybody would like to move `/tmp` socket dir to `/var/run`, or even `/var/run/postgresql` (or even `/run/postgresql`), but compatibility with old clients (which connect to /tmp by default) is a concern.

One reason to make this move is because any user can create PG socket in `/tmp`, and thus local clients will use that PG, instead of system one (which won't even start because it can't create socket - it is already used).

I propose following 2 ideas:

1. Add a Makefile parameter CONFIG_PGSOCKET_DIR to explicitly switch to new unix socket directory, and let distributions decide if they want this, and if they want, they should handle socket dir change on their own. For example, switch to `/var/run/postgresql` require `/var/run/postgresql` directory to be created - an extra step compared to current situation.

This will allow remove some patches for many (many?) distributions.

By default (CONFIG_PGSOCKET_DIR undefined) unix socket dir should be set to `/tmp` - backward compatibility.

2. The new socket directory shouldn't be hardcoded to single directory, instead it should be detected dynamically.

For server:
- if unix_socket_directory specified, use it
- if not, check if /run/user/$(id -u) exists. If yes, use it as socket dir
- if doesn't exist, check CONFIG_PGSOCKET_DIR exists. If yes, use it as socket dir
- else fail

For client:
- if host explicitly set, use it
- if not, check if /run/user/$(id -u) exists and socket file exists there. If yes, use it as socket
- if doesn't exist, check CONFIG_PGSOCKET_DIR exists. If yes, use it as socket dir
- else fail

What will be solved:
- no more local /tmp hijack
- `pg_ctl start` and psql, when run as single user, will use same socket directory /run/user/$(id -u) - no need to create safe directory first
- psql will still be able to connect to "service" PG - if socket is not found in user runtime dir, then lookup in system (runtime) dir

Drawbacks:
- running pg_ctl as root will no longer make server accessible by default to other users, because /run/user/0 is readable only by root
- if `postgres` user, under which postgresql service runs, is "normal" user, and has /run/user/XXX directory, pg will require start-time -k /var/run/postgresql switch, to be accessible to other users' clients
- there will no longer be a "single" directory to lookup sockets, so an instructions on nuances of unix socket dir resolution for newcomers is required
- non-systemd distributions won't benefit from this logic
- /run/user/$(id -u) is opinionated. $XDG_RUNTIME_DIR would be better

Thoughts?

Re: Unix socket dir, an idea

From
Tom Lane
Date:
Danylo Hlynskyi <abcz2.uprola@gmail.com> writes:
> The problem (as I see it) is that everybody would like to move `/tmp`
> socket dir to `/var/run`, or even `/var/run/postgresql` (or even
> `/run/postgresql`), but compatibility with old clients (which connect to
> /tmp by default) is a concern.

*Some* people would like to move the default socket location.  Others
of us see that as a recipe for chaos.  If it's really easy to change
that, we're going to have a Babel of servers and clients that can't
talk to each other.

I would also like to point out the extreme Unix-centricity (and
even particular-distribution-centricity) of the alternative locations
you mention, as well as the fact that all those locations are unfriendly
to running an unprivileged postmaster (i.e. one that hasn't been
explicitly blessed by whoever has root on the box).

> 1. Add a Makefile parameter CONFIG_PGSOCKET_DIR to explicitly switch to new
> unix socket directory, and let distributions decide if they want this, and
> if they want, they should handle socket dir change on their own.

We already have DEFAULT_PGSOCKET_DIR in pg_config_manual.h, and distros
that want to change it typically carry a patch to adjust that header.
I'm not sure we really want to make it any easier than that.

> 2. The new socket directory shouldn't be hardcoded to single directory,
> instead it should be detected dynamically.

This idea is just nuts.  It makes each of the problems I mentioned above
about ten times worse.

> For client:
> - if host explicitly set, use it
> - if not, check if /run/user/$(id -u) exists and socket file exists there.
> If yes, use it as socket

Uh, how is a client supposed to know what UID the postmaster is running
under?

            regards, tom lane



Re: Unix socket dir, an idea

From
Danylo Hlynskyi
Date:
Hi Tom, and much thanks for reply!

> I would also like to point out the extreme Unix-centricity (and
> even particular-distribution-centricity) of the alternative locations
> you mention

Yes! The /run/user and /var/run directories are absent on MacOS. That's why I **don't** propose to change
default directory to /var/run. Each distribution **may** set it on it's own or use default /tmp
- Ubuntu/Debian can set to /var/run/postgresql
- generic systemd distro can set to /run/postgresql
- /tmp everywhere else, including MacOS. Actually, a default
- (I think this is unrelated to Windows, but maybe windows has it's own notion for runtime directories)

All those won't be hardcoded in PG source, it is build time param and distribution holds all the responsibility
for changing the default.

> as well as the fact that all those locations are unfriendly
> to running an unprivileged postmaster (i.e. one that hasn't been
> explicitly blessed by whoever has root on the box).

Yes! That's why I propose to use **user runtime directory** first, when it's available. Systemd distros do
have one (think of user's private /tmp), which is denoted by XDG_RUNTIME_DIR envvar. No need
for server to be root, and no way for other users to hijack server socket (which is currently possible
with 0777 /tmp)

If you are talking about two regular users, one of which runs server, another client - they will have now
to agree which socket directory to use, yes. And what is nice, they won't be able to override system-level
postgresql without having root rights (currently it is possible to do between pg restarts).

> Uh, how is a client supposed to know what UID the postmaster is running under?

It doesn't have to. It first looks up under current user runtime directory (XDG_RUNTIME_DIR or /run/user/$(id -u))
and if it can't find socket there, it searches in CONFIG_PGSOCKET_DIR (which is common for both server and client)

> we're going to have a Babel of servers and clients that can't talk to each other.

I'd like to note, that exactly the curent Babel of servers and clients made me write this email.
1. Debian/Ubuntu care about security, so they move socket directory from 0777 directory to 0755 directory
(/var/run/postgresql)
2. PG in Nix distro packageset used default setting (/tmp), and thus `psql` installed via Nix on Ubuntu didn't connect
to Ubuntu server by default
3. Because Debian did change default directory, `pg_ctl start` doesn't work with default params:
```
~$ /usr/lib/postgresql/9.6/bin/pg_ctl -D temppg -o "-p 5400" start
server starting
FATAL: could not create lock file "/var/run/postgresql/.s.PGSQL.5400.lock": Permission denied
```

Thanks again for reading this!

сб, 30 бер. 2019 о 02:40 Tom Lane <tgl@sss.pgh.pa.us> пише:
Danylo Hlynskyi <abcz2.uprola@gmail.com> writes:
> The problem (as I see it) is that everybody would like to move `/tmp`
> socket dir to `/var/run`, or even `/var/run/postgresql` (or even
> `/run/postgresql`), but compatibility with old clients (which connect to
> /tmp by default) is a concern.

*Some* people would like to move the default socket location.  Others
of us see that as a recipe for chaos.  If it's really easy to change
that, we're going to have a Babel of servers and clients that can't
talk to each other.

I would also like to point out the extreme Unix-centricity (and
even particular-distribution-centricity) of the alternative locations
you mention, as well as the fact that all those locations are unfriendly
to running an unprivileged postmaster (i.e. one that hasn't been
explicitly blessed by whoever has root on the box).

> 1. Add a Makefile parameter CONFIG_PGSOCKET_DIR to explicitly switch to new
> unix socket directory, and let distributions decide if they want this, and
> if they want, they should handle socket dir change on their own.

We already have DEFAULT_PGSOCKET_DIR in pg_config_manual.h, and distros
that want to change it typically carry a patch to adjust that header.
I'm not sure we really want to make it any easier than that.

> 2. The new socket directory shouldn't be hardcoded to single directory,
> instead it should be detected dynamically.

This idea is just nuts.  It makes each of the problems I mentioned above
about ten times worse.

> For client:
> - if host explicitly set, use it
> - if not, check if /run/user/$(id -u) exists and socket file exists there.
> If yes, use it as socket

Uh, how is a client supposed to know what UID the postmaster is running
under?

                        regards, tom lane