-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/postgresql: change option enableTCPIP
to actually mean TCP/IP.
#353707
base: master
Are you sure you want to change the base?
Conversation
Setting the option `services.postgresql.enableTCPIP` to `false` did not disable TCP/IP. Instead, this makes PostgreSQL listen on `localhost`. This was confusing, as a security minded user may want to disable TCP/IP entirely, even for localhost. It also prevented running multiple instances of PostgreSQL on the same host without manually assigning distinct TCP/IP ports. This commit adds a new option, `services.postgres.listenAddresses`, that defaults to `localhost`. The default behaviour of `services.postgresql` is maintained: the service listens on localhost using TCP/IP with the new default `enableTCPIP = null`. A warning informs users that setting `enableTCPIP = true` now only listens on localhost. Setting `listenAddresses` is now required to listen on all or multiple interfaces. This option follows the upstream PostgreSQL syntax for `liste_addresses`.
Whether PostgreSQL should listen on network interfaces. | ||
If 'false', the database can only be accessed via its Unix | ||
domain socket. | ||
A value of 'null' defaults to 'true'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why setting the type to nullOr bool
when the default is true
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new default is null
. This has the same behavior as true
but this makes it possible to show a warning only to users who have this option configured, not to users who left the default values.
listenAddresses = mkOption { | ||
type = types.str; | ||
default = "localhost"; | ||
description = '' | ||
The TCP/IP address(es) on which the server is to listen for connections from client applications. | ||
The value takes the form of a comma-separated list of host names and/or numeric IP addresses. | ||
The special entry * corresponds to all available IP interfaces. | ||
|
||
See the PostgreSQL documentation on [listen_address](https://www.postgresql.org/docs/16/runtime-config-connection.html#GUC-LISTEN-ADDRESSES). | ||
''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be clearer if it was a list of strings later joined with comma in implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this, however I am not sure whether the Nixpkgs policy is to map the settings of the services as close as possible ("The value takes the form of a comma-separated list of host names and/or numeric IP addresses") or to provide a more abstract interface.
On a similar topic, other packages use alternative names for this such as hosts
, bind
, listen
, interface
, ports
, ... listen_addresses
is the name of the setting in PostgreSQL (and a few other services).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it you want to keep it like this, I suggest you change the type from string to lib.types.commas
which are comma separated strings, which provide an additional check that the definition is valid (see nixos manual).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer update this branch with a list of strings (or IP addresses if there is a type for that) if that is compatible with the Nixpkgs policy.
services.postgresql.settings = | ||
{ | ||
hba_file = "${pkgs.writeText "pg_hba.conf" cfg.authentication}"; | ||
ident_file = "${pkgs.writeText "pg_ident.conf" cfg.identMap}"; | ||
log_destination = "stderr"; | ||
listen_addresses = if cfg.enableTCPIP then "*" else "localhost"; | ||
listen_addresses = if (cfg.enableTCPIP != false) then cfg.listenAddresses else ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
listen_addresses = if (cfg.enableTCPIP != false) then cfg.listenAddresses else ""; | |
listen_addresses = lib.optionalString (cfg.enableTCPIP != false) cfg.listenAddresses; |
|
||
listenAddresses = mkOption { | ||
type = types.str; | ||
default = "localhost"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that ipv6 localhost ::1 and 127.0.0.1 on ipv4 only systems?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the PostgreSQL documentation:
The default value is localhost, which allows only local TCP/IP “loopback” connections to be made.
Co-authored-by: Sandro <[email protected]>
Co-authored-by: Sandro <[email protected]>
Co-authored-by: Sandro <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on what goes in first, we need to either adjust here or #352966, where we move all the postgres tests into nixos/tests/postgresql
and make sure to run them against all PG versions etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for linking to that PR, I didn't know about it. Do you think it would be relevant to test the behavior of these options with all PG versions ? My understanding is that this is not affected by the different versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it would be relevant to test the behavior of these options with all PG versions ?
No, I don't think so. But I haven't made up my mind about where to draw the line, yet.
The "and make sure to run them against all PG versions" was meant as a description for that PR, not necessarily as a requirement for this one.
The requirement is*, that we have it in the same folder eventually, so that we're getting pinged via ci/OWNERS
:)
* And that we have it working nicely via passthru, but you already have that in principle, I think. Just avoiding the long relative path would be good (see my PR, too, for how to).
@@ -472,12 +485,16 @@ in | |||
''; | |||
}) cfg.ensureUsers; | |||
|
|||
warnings = lib.optional (cfg.enableTCPIP == true) '' | |||
Behaviour of `services.postgresql.enableTCPIP` changed from binding on all interfaces to binding on localhost in addition to the unix socket. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong: there's now an option called listenAddresses
that controls where to listen.
Generally, I'm wondering if we shouldn't just deprecate the enableTCPIP
option and give users fine-grained control over the listen address part.
In fact, we don't even need a listenAddresses
option, we can just define the option in the freeform settings type (I mean settings.listen_addresses
).
I.e.
options.services.postgresql.enableTCPIP
gives a deprecation warning.- if
enableTCPIP
is set, keep the old behavior (and remove it after a while - given that this is a rather central piece, we may want to go that route). - when it's
null
, don't touchlisten_addresses
.
Does that make sense?
This is an attempt at fixing #346013, started during NixCon 2024 with the help of @jfroche .
Setting the option
services.postgresql.enableTCPIP
tofalse
did not disable TCP/IP. Instead, this makes PostgreSQL listen onlocalhost
.This was confusing, as a security minded user may want to disable TCP/IP entirely, even for localhost.
It also prevented running multiple instances of PostgreSQL on the same host without manually assigning distinct TCP/IP ports.
This commit adds a new option,
services.postgres.listenAddresses
, that defaults tolocalhost
.The default behaviour of
services.postgresql
is maintained: the service listens on localhost using TCP/IP with the new defaultenableTCPIP = null
.A warning informs users that setting
enableTCPIP = true
now only listens on localhost. SettinglistenAddresses
is now required to listen on all or multiple interfaces. This option follows the upstream PostgreSQL syntax forliste_addresses
.New tests validate the new behavior.
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.