diff --git a/ansible/files/permission_check.py b/ansible/files/permission_check.py index c4f73aa4e..a753f69ec 100644 --- a/ansible/files/permission_check.py +++ b/ansible/files/permission_check.py @@ -96,6 +96,8 @@ ], } +# postgresql.service is expected to mount /etc as read-only +expected_mount = "/etc ro" # This program depends on osquery being installed on the system # Function to run osquery @@ -152,6 +154,33 @@ def check_nixbld_users(): print("All nixbld users are in the 'nixbld' group.") +def check_postgresql_mount(): + # processes table has the nix .postgres-wrapped path as the + # binary path, rather than /usr/lib/postgresql/bin/postgres which + # is a symlink to /var/lib/postgresql/.nix-profile/bin/postgres, a script + # that ultimately calls /nix/store/...-postgresql-and-plugins-15.8/bin/.postgres-wrapped + query = """ + SELECT pid + FROM processes + WHERE path LIKE '%.postgres-wrapped%' + AND cmdline LIKE '%-D /etc/postgresql%'; + """ + query_result = run_osquery(query) + parsed_result = parse_json(query_result) + + pid = parsed_result[0].get("pid") + + # get the mounts for the process + with open(f"/proc/{pid}/mounts", "r") as o: + lines = [line for line in o if "/etc" in line and "ro," in line] + if len(lines) == 0: + print(f"Expected exactly 1 match, got 0") + sys.exit(1) + if len(lines) != 1: + print(f"Expected exactly 1 match, got {len(lines)}: {';'.join(lines)}") + sys.exit(1) + + print("postgresql.service mounts /etc as read-only.") def main(): parser = argparse.ArgumentParser( @@ -219,6 +248,8 @@ def main(): # Check if all nixbld users are in the nixbld group check_nixbld_users() + # Check if postgresql.service is using a read-only mount for /etc + check_postgresql_mount() if __name__ == "__main__": main() diff --git a/ansible/files/postgresql_config/postgresql.service.j2 b/ansible/files/postgresql_config/postgresql.service.j2 index c056ac433..4cc138ec7 100644 --- a/ansible/files/postgresql_config/postgresql.service.j2 +++ b/ansible/files/postgresql_config/postgresql.service.j2 @@ -21,5 +21,8 @@ RestartSec=5 OOMScoreAdjust=-1000 EnvironmentFile=-/etc/environment.d/postgresql.env LimitNOFILE=16384 +{% if supabase_internal is defined %} +ReadOnlyPaths=/etc +{% endif %} [Install] WantedBy=multi-user.target diff --git a/ansible/playbook.yml b/ansible/playbook.yml index 806079aa9..bcd47ac9b 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -213,7 +213,9 @@ - name: Run osquery permission checks become: yes shell: | + systemctl start postgresql.service sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && /usr/bin/python3 /tmp/ansible-playbook/ansible/files/permission_check.py {{ '--qemu' if qemu_mode is defined else '' }}" + systemctl stop postgresql.service when: stage2_nix - name: Remove osquery diff --git a/ansible/vars.yml b/ansible/vars.yml index 3cd541336..f0da23fd2 100644 --- a/ansible/vars.yml +++ b/ansible/vars.yml @@ -9,9 +9,9 @@ postgres_major: # Full version strings for each major version postgres_release: - postgresorioledb-17: "17.0.1.063-orioledb" - postgres17: "17.4.1.013" - postgres15: "15.8.1.070" + postgresorioledb-17: "17.0.1.064-orioledb" + postgres17: "17.4.1.014" + postgres15: "15.8.1.071" # Non Postgres Extensions pgbouncer_release: "1.19.0"