diff --git a/README.rst b/README.rst index 069a558..4c23b7f 100644 --- a/README.rst +++ b/README.rst @@ -54,10 +54,14 @@ Upstream's ``conf.d/main`` sets ``listen_addresses = '*'`` and appends ``host all all 0.0.0.0/0 md5`` to ``pg_hba.conf``, so the appliance accepts password authentication for every database from anywhere. On an IPv6 first, publicly routable appliance (brief section 5.3) that is not a default this -project can inherit quietly. This layer keeps Debian's -``listen_addresses = 'localhost'``, which is the loopback of both families, -and asserts at build time that neither of upstream's two changes is -present. An appliance that really has remote clients opens the port, says +project can inherit quietly. This layer listens on +``'::1,127.0.0.1'``, the loopback of both families and nothing else, and +asserts at build time that neither of upstream's two changes is present. +Both addresses are written out rather than left to Debian's default of +``'localhost'``: that default binds the IPv4 loopback alone, because +Debian's ``/etc/hosts`` maps ``::1`` to ``ip6-localhost`` and never to +``localhost``, which is a defect this layer shipped once and its own boot +test caught. An appliance that really has remote clients opens the port, says who may connect and terminates TLS. That is a decision an appliance makes, not one a database layer makes for everything built on it. diff --git a/changelog b/changelog index 500786b..5ca7b24 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,13 @@ +turnkey-postgresql-19.0 (2) turnkey; urgency=low + + * Listen on both loopback addresses, named literally: + listen_addresses = '::1,127.0.0.1'. Debian's default, 'localhost', + binds the IPv4 loopback alone, because Debian's /etc/hosts maps ::1 to + ip6-localhost and never to localhost, so an appliance built on this + layer and reaching its database over IPv6 found nothing listening. + + -- Keel Linux maintainers Sun, 27 Sep 2026 07:30:00 +0000 + turnkey-postgresql-19.0 (1) turnkey; urgency=low * Initial release of the PostgreSQL database layer for Keel, compatible diff --git a/conf.d/main b/conf.d/main index b304ae3..5908c2a 100755 --- a/conf.d/main +++ b/conf.d/main @@ -41,12 +41,30 @@ EOF systemctl stop postgresql -# The cluster listens on the loopback of both families and nowhere else. -# Debian's default, listen_addresses = 'localhost', is exactly that, so it -# is asserted rather than changed: upstream's postgresql appliance replaces -# it with '*' and appends a pg_hba line accepting password authentication -# from 0.0.0.0/0, and this layer must not inherit that by accident. -grep -qE "^#?listen_addresses = 'localhost'" "$CONF_DIR/postgresql.conf" +# The cluster listens on the loopback of both families and nowhere else, +# and both are named as literal addresses. +# +# Debian's default is listen_addresses = 'localhost', and that was taken +# for "the loopback of both families" when this layer was written. It is +# not. Debian's /etc/hosts maps ::1 to ip6-localhost and ip6-loopback and +# never to localhost, so getaddrinfo("localhost") answers 127.0.0.1 alone +# and the cluster binds the IPv4 loopback only. Measured on the booted +# layer: "LISTEN 127.0.0.1:5432" and nothing on [::1]:5432, with ::1 up on +# lo and pg_hba.conf already holding its scram-sha-256 line for ::1/128. +# An appliance built on this layer and reaching its database over IPv6, +# which is the default this project builds for (brief section 10), found +# nothing listening. +# +# Two literal addresses cannot resolve into something else, which is the +# whole point of writing them out; what they bind to is then proved on the +# booted machine by the boot test rather than assumed here. +sed -i "s|^#\?listen_addresses = .*|listen_addresses = '::1,127.0.0.1'\t\t# set by conf.d/main of keel-postgresql: see the comment there|" \ + "$CONF_DIR/postgresql.conf" +grep -qE "^listen_addresses = '::1,127\.0\.0\.1'" "$CONF_DIR/postgresql.conf" + +# Upstream's postgresql appliance replaces listen_addresses with '*' and +# appends a pg_hba line accepting password authentication from 0.0.0.0/0. +# This layer must not inherit either by accident. ! grep -qE "^listen_addresses = '\*'" "$CONF_DIR/postgresql.conf" ! grep -qE '^host\s+all\s+all\s+0\.0\.0\.0/0' "$CONF_DIR/pg_hba.conf"