From 64196a0b0883f5dd52bdf80f4aa7db5e6a0d6f8e Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 8 Dec 2022 18:25:20 -0500 Subject: [PATCH 1/3] Put certificates in /etc/pki instead The problem with /var/lib/pgsql/data/userdata is if this is a new install, initalizing the database will fail because the userdata directory is not empty and it is expected to be empty. Since the postgres configs are always mounted on the pod we need the certs to be in a predictable location. --- Dockerfile | 1 + container-assets/on-start.sh | 6 +++++- container-assets/pre-start.sh | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index d9c8572..eda5b95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,6 +74,7 @@ RUN ARCH=$(uname -m) && \ yum -y reinstall tzdata && \ yum -y clean all --enablerepo='*' && \ localedef -f UTF-8 -i en_US en_US.UTF-8 && \ + chmod -R g+w /etc/pki/tls && \ test "$(id postgres)" = "uid=26(postgres) gid=26(postgres) groups=26(postgres)" && \ mkdir -p /var/lib/pgsql/data && \ /usr/libexec/fix-permissions /var/lib/pgsql /var/run/postgresql diff --git a/container-assets/on-start.sh b/container-assets/on-start.sh index 03df013..9a1a1c9 100755 --- a/container-assets/on-start.sh +++ b/container-assets/on-start.sh @@ -2,6 +2,10 @@ psql --command "ALTER ROLE \"${POSTGRESQL_USER}\" SUPERUSER;" -if [ -f /opt/app-root/src/certificates/server.key ]; then +if [ -f /etc/pki/tls/private/server.key ]; then sed -i 's/host\(\b.*\)/hostssl\1/g' /var/lib/pgsql/data/userdata/pg_hba.conf + + sed -i 's/.*ssl = off.*/ssl = on/g' /var/lib/pgsql/data/userdata/postgresql.conf + sed -i 's/.*ssl_cert_file.*/ssl_cert_file = \/etc\/pki\/tls\/certs\/server.crt/g' /var/lib/pgsql/data/userdata/postgresql.conf + sed -i 's/.*ssl_key_file.*/ssl_key_file = \/etc\/pki\/tls\/private\/server.key/g' /var/lib/pgsql/data/userdata/postgresql.conf fi diff --git a/container-assets/pre-start.sh b/container-assets/pre-start.sh index 4e79905..dd1b36f 100755 --- a/container-assets/pre-start.sh +++ b/container-assets/pre-start.sh @@ -3,9 +3,9 @@ if [ ! -f /opt/app-root/src/certificates/server.key ]; then echo "Skipping SSL setup, key not found." else - cp /opt/app-root/src/certificates/server.crt /var/lib/pgsql/data/userdata/server.crt - cp /opt/app-root/src/certificates/server.key /var/lib/pgsql/data/userdata/server.key + cp /opt/app-root/src/certificates/server.crt /etc/pki/tls/certs/server.crt + cp /opt/app-root/src/certificates/server.key /etc/pki/tls/private/server.key # Postgresql server will reject key files with liberal permissions - chmod og-rwx /var/lib/pgsql/data/userdata/server.key + chmod og-rwx /etc/pki/tls/private/server.key fi From 9f7b767c43ece8af5c4b86f48b35a882c18b92a6 Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 28 Sep 2023 16:35:51 -0400 Subject: [PATCH 2/3] Ingest current run-postgresql for future editing Based on run-postgresql in v13 @ 481efd6 --- container-assets/miq-run-postgresql | 59 ++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/container-assets/miq-run-postgresql b/container-assets/miq-run-postgresql index 97df057..e148b1e 100755 --- a/container-assets/miq-run-postgresql +++ b/container-assets/miq-run-postgresql @@ -6,4 +6,61 @@ do export "$(basename $file)=$(cat $file)" done -exec "/usr/bin/run-postgresql" + +# Original run-postgresql +export ENABLE_REPLICATION=${ENABLE_REPLICATION:-false} + +set -eu +export_vars=$(cgroup-limits) ; export $export_vars + +source "${CONTAINER_SCRIPTS_PATH}/common.sh" + +set_pgdata + +process_extending_files \ + "${APP_DATA}/src/postgresql-pre-start" \ + "${CONTAINER_SCRIPTS_PATH}/pre-start" + +check_env_vars +generate_passwd_file +generate_postgresql_config + +# Is this brand new data volume? +PG_INITIALIZED=false + +if [ ! -f "$PGDATA/postgresql.conf" ]; then + initialize_database + PG_INITIALIZED=: +else + try_pgupgrade +fi + +# Use insanely large timeout (24h) to ensure that the potential recovery has +# enough time here to happen (unless liveness probe kills us). Note that in +# case of server failure this command still exists immediately. +pg_ctl start -w --timeout 86400 -o "-h ''" + +# This is just a pedantic safety measure (the timeout above is unlikely to +# happen), but `pt_ctl -w` is not reliable prior to PostgreSQL v10 where it +# returns exit_status=0 even if the server is still starting. For more info +# see the issue#297 and +# https://www.postgresql.org/message-id/CAB7nPqSJs85wK9aknm%3D_jmS6GnH3SQBhpzKcqs8Qo2LhEg2etw%40mail.gmail.com +pg_isready + +if $PG_INITIALIZED ; then + process_extending_files \ + "${APP_DATA}/src/postgresql-init" \ + "${CONTAINER_SCRIPTS_PATH}/init" + migrate_db + create_users +fi + +process_extending_files \ + "${APP_DATA}/src/postgresql-start" \ + "${CONTAINER_SCRIPTS_PATH}/start" + +pg_ctl stop + +unset_env_vars +echo "Starting server..." +exec postgres "$@" From 6d7f38d94d9f43ec51554857e8b9da7c790d4a61 Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 28 Sep 2023 16:45:41 -0400 Subject: [PATCH 3/3] Conditionally inject the postgres SSL config after other configs This needs to happen after generate_postgresql_config creates the ephemeral config file which includes all configs from mounted volumes so that these ssl settings are loaded last overwriting anything in included configs. It also needs to happen before try_pgupgrade could potentially try to start a server and before pg_ctl tries to start the server. We also need to ensure hostssl in pg_hba.conf after initialize_database in the case of a new empty volume. --- container-assets/miq-run-postgresql | 13 +++++++++++++ container-assets/on-start.sh | 8 -------- container-assets/pre-start.sh | 1 + 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/container-assets/miq-run-postgresql b/container-assets/miq-run-postgresql index e148b1e..d1b11fc 100755 --- a/container-assets/miq-run-postgresql +++ b/container-assets/miq-run-postgresql @@ -25,6 +25,13 @@ check_env_vars generate_passwd_file generate_postgresql_config +# MIQ conditionally inject SSL config +if [ -f /etc/pki/tls/private/server.key ]; then + echo "ssl = on" >> $POSTGRESQL_CONFIG_FILE + echo "ssl_cert_file = '/etc/pki/tls/certs/server.crt'" >> $POSTGRESQL_CONFIG_FILE + echo "ssl_key_file = '/etc/pki/tls/private/server.key'" >> $POSTGRESQL_CONFIG_FILE +fi + # Is this brand new data volume? PG_INITIALIZED=false @@ -35,6 +42,12 @@ else try_pgupgrade fi +# MIQ conditionally configure SSL listener +if [ -f /etc/pki/tls/private/server.key ]; then + # Can't do this before initialize_database + sed -i 's/host\(\b.*\)/hostssl\1/g' /var/lib/pgsql/data/userdata/pg_hba.conf +fi + # Use insanely large timeout (24h) to ensure that the potential recovery has # enough time here to happen (unless liveness probe kills us). Note that in # case of server failure this command still exists immediately. diff --git a/container-assets/on-start.sh b/container-assets/on-start.sh index 9a1a1c9..5830c44 100755 --- a/container-assets/on-start.sh +++ b/container-assets/on-start.sh @@ -1,11 +1,3 @@ #!/bin/bash psql --command "ALTER ROLE \"${POSTGRESQL_USER}\" SUPERUSER;" - -if [ -f /etc/pki/tls/private/server.key ]; then - sed -i 's/host\(\b.*\)/hostssl\1/g' /var/lib/pgsql/data/userdata/pg_hba.conf - - sed -i 's/.*ssl = off.*/ssl = on/g' /var/lib/pgsql/data/userdata/postgresql.conf - sed -i 's/.*ssl_cert_file.*/ssl_cert_file = \/etc\/pki\/tls\/certs\/server.crt/g' /var/lib/pgsql/data/userdata/postgresql.conf - sed -i 's/.*ssl_key_file.*/ssl_key_file = \/etc\/pki\/tls\/private\/server.key/g' /var/lib/pgsql/data/userdata/postgresql.conf -fi diff --git a/container-assets/pre-start.sh b/container-assets/pre-start.sh index dd1b36f..6f155a8 100755 --- a/container-assets/pre-start.sh +++ b/container-assets/pre-start.sh @@ -3,6 +3,7 @@ if [ ! -f /opt/app-root/src/certificates/server.key ]; then echo "Skipping SSL setup, key not found." else + echo "Copying SSL certificates to /etc/pki/ and fixing permissions" cp /opt/app-root/src/certificates/server.crt /etc/pki/tls/certs/server.crt cp /opt/app-root/src/certificates/server.key /etc/pki/tls/private/server.key