|
95 | 95 | ],
|
96 | 96 | }
|
97 | 97 |
|
| 98 | +# postgresql.service is expected to mount /etc as read-only |
| 99 | +expected_mount = "/etc ro" |
98 | 100 |
|
99 | 101 | # This program depends on osquery being installed on the system
|
100 | 102 | # Function to run osquery
|
@@ -151,6 +153,33 @@ def check_nixbld_users():
|
151 | 153 |
|
152 | 154 | print("All nixbld users are in the 'nixbld' group.")
|
153 | 155 |
|
| 156 | +def check_postgresql_mount(): |
| 157 | + # processes table has the nix .postgres-wrapped path as the |
| 158 | + # binary path, rather than /usr/lib/postgresql/bin/postgres which |
| 159 | + # is a symlink to /var/lib/postgresql/.nix-profile/bin/postgres, a script |
| 160 | + # that ultimately calls /nix/store/...-postgresql-and-plugins-15.8/bin/.postgres-wrapped |
| 161 | + query = """ |
| 162 | + SELECT pid |
| 163 | + FROM processes |
| 164 | + WHERE path LIKE '%.postgres-wrapped%' |
| 165 | + AND cmdline LIKE '%-D /etc/postgresql%'; |
| 166 | + """ |
| 167 | + query_result = run_osquery(query) |
| 168 | + parsed_result = parse_json(query_result) |
| 169 | + |
| 170 | + pid = parsed_result[0].get("pid") |
| 171 | + |
| 172 | + # get the mounts for the process |
| 173 | + with open(f"/proc/{pid}/mounts", "r") as o: |
| 174 | + lines = [line for line in o if "/etc" in line and "ro," in line] |
| 175 | + if len(lines) == 0: |
| 176 | + print(f"Expected exactly 1 match, got 0") |
| 177 | + sys.exit(1) |
| 178 | + if len(lines) != 1: |
| 179 | + print(f"Expected exactly 1 match, got {len(lines)}: {';'.join(lines)}") |
| 180 | + sys.exit(1) |
| 181 | + |
| 182 | + print("postgresql.service mounts /etc as read-only.") |
154 | 183 |
|
155 | 184 | def main():
|
156 | 185 | parser = argparse.ArgumentParser(
|
@@ -218,6 +247,8 @@ def main():
|
218 | 247 | # Check if all nixbld users are in the nixbld group
|
219 | 248 | check_nixbld_users()
|
220 | 249 |
|
| 250 | + # Check if postgresql.service is using a read-only mount for /etc |
| 251 | + check_postgresql_mount() |
221 | 252 |
|
222 | 253 | if __name__ == "__main__":
|
223 | 254 | main()
|
0 commit comments