Skip to content

Commit 7009932

Browse files
authored
fix: garbage collect after every profile intall + remove osquery (#1938)
* fix: garbage collect after every profile intall + remove osquery * chore: fmt
1 parent 5935952 commit 7009932

File tree

3 files changed

+84
-70
lines changed

3 files changed

+84
-70
lines changed

ansible/files/permission_check.py

Lines changed: 72 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import subprocess
2-
import json
31
import sys
42
import argparse
53
import os
64
import stat
5+
import pwd
6+
import grp
77

88

99
# Expected groups for each user
@@ -159,21 +159,25 @@
159159
}
160160

161161

162-
# This program depends on osquery being installed on the system
163-
# Function to run osquery
164-
def run_osquery(query):
165-
process = subprocess.Popen(
166-
["osqueryi", "--json", query], stdout=subprocess.PIPE, stderr=subprocess.PIPE
167-
)
168-
output, error = process.communicate()
169-
return output.decode("utf-8")
170-
171-
172-
def parse_json(json_str):
162+
def get_user_groups(username):
163+
"""Get all groups that a user belongs to using Python's pwd and grp modules."""
173164
try:
174-
return json.loads(json_str)
175-
except json.JSONDecodeError as e:
176-
print("Error decoding JSON:", e)
165+
user_info = pwd.getpwnam(username)
166+
user_uid = user_info.pw_uid
167+
user_gid = user_info.pw_gid
168+
169+
# Get all groups
170+
groups = []
171+
for group in grp.getgrall():
172+
# Check if user is in the group (either as primary group or in member list)
173+
if user_gid == group.gr_gid or username in group.gr_mem:
174+
groups.append({"username": username, "groupname": group.gr_name})
175+
176+
# Sort by groupname to match expected behavior
177+
groups.sort(key=lambda x: x["groupname"])
178+
return groups
179+
except KeyError:
180+
print(f"User '{username}' not found")
177181
sys.exit(1)
178182

179183

@@ -195,43 +199,60 @@ def compare_results(username, query_result):
195199

196200

197201
def check_nixbld_users():
198-
query = """
199-
SELECT u.username, g.groupname
200-
FROM users u
201-
JOIN user_groups ug ON u.uid = ug.uid
202-
JOIN groups g ON ug.gid = g.gid
203-
WHERE u.username LIKE 'nixbld%';
204-
"""
205-
query_result = run_osquery(query)
206-
parsed_result = parse_json(query_result)
207-
208-
for user in parsed_result:
209-
if user["groupname"] != "nixbld":
210-
print(
211-
f"User '{user['username']}' is in group '{user['groupname']}' instead of 'nixbld'."
212-
)
213-
sys.exit(1)
202+
"""Check that all nixbld users are only in the nixbld group."""
203+
# Get all users that match the pattern nixbld*
204+
nixbld_users = []
205+
for user in pwd.getpwall():
206+
if user.pw_name.startswith("nixbld"):
207+
nixbld_users.append(user.pw_name)
208+
209+
if not nixbld_users:
210+
print("No nixbld users found")
211+
return
212+
213+
# Check each nixbld user's groups
214+
for username in nixbld_users:
215+
groups = get_user_groups(username)
216+
for user_group in groups:
217+
if user_group["groupname"] != "nixbld":
218+
print(
219+
f"User '{username}' is in group '{user_group['groupname']}' instead of 'nixbld'."
220+
)
221+
sys.exit(1)
214222

215223
print("All nixbld users are in the 'nixbld' group.")
216224

217225

218226
def check_postgresql_mount():
219-
# processes table has the nix .postgres-wrapped path as the
220-
# binary path, rather than /usr/lib/postgresql/bin/postgres which
221-
# is a symlink to /var/lib/postgresql/.nix-profile/bin/postgres, a script
222-
# that ultimately calls /nix/store/...-postgresql-and-plugins-15.8/bin/.postgres-wrapped
223-
query = """
224-
SELECT pid
225-
FROM processes
226-
WHERE path LIKE '%.postgres-wrapped%'
227-
AND cmdline LIKE '%-D /etc/postgresql%';
228-
"""
229-
query_result = run_osquery(query)
230-
parsed_result = parse_json(query_result)
231-
232-
pid = parsed_result[0].get("pid")
233-
234-
# get the mounts for the process
227+
"""Check that postgresql.service mounts /etc as read-only."""
228+
# Find the postgres process by reading /proc
229+
# We're looking for a process with .postgres-wrapped in the path
230+
# and -D /etc/postgresql in the command line
231+
pid = None
232+
233+
for proc_dir in os.listdir("/proc"):
234+
if not proc_dir.isdigit():
235+
continue
236+
237+
try:
238+
# Read the command line
239+
with open(f"/proc/{proc_dir}/cmdline", "r") as f:
240+
cmdline = f.read()
241+
# Check if this is a postgres process with the right data directory
242+
if ".postgres-wrapped" in cmdline and "-D /etc/postgresql" in cmdline:
243+
pid = proc_dir
244+
break
245+
except (FileNotFoundError, PermissionError):
246+
# Process might have disappeared or we don't have permission
247+
continue
248+
249+
if pid is None:
250+
print(
251+
"Could not find postgres process with .postgres-wrapped and -D /etc/postgresql"
252+
)
253+
sys.exit(1)
254+
255+
# Get the mounts for the process
235256
with open(f"/proc/{pid}/mounts", "r") as o:
236257
lines = [line for line in o if "/etc" in line and "ro," in line]
237258
if len(lines) == 0:
@@ -265,9 +286,6 @@ def check_directory_permissions():
265286
actual_mode = oct(stat.S_IMODE(stat_info.st_mode))[2:] # Remove '0o' prefix
266287

267288
# Get owner and group names
268-
import pwd
269-
import grp
270-
271289
actual_owner = pwd.getpwuid(stat_info.st_uid).pw_name
272290
actual_group = grp.getgrgid(stat_info.st_gid).gr_name
273291

@@ -369,12 +387,10 @@ def main():
369387
if not qemu_artifact:
370388
usernames.append("ec2-instance-connect")
371389

372-
# Iterate over usernames, run the query, and compare results
390+
# Iterate over usernames, get their groups, and compare results
373391
for username in usernames:
374-
query = f"SELECT u.username, g.groupname FROM users u JOIN user_groups ug ON u.uid = ug.uid JOIN groups g ON ug.gid = g.gid WHERE u.username = '{username}' ORDER BY g.groupname;"
375-
query_result = run_osquery(query)
376-
parsed_result = parse_json(query_result)
377-
compare_results(username, parsed_result)
392+
user_groups = get_user_groups(username)
393+
compare_results(username, user_groups)
378394

379395
# Check if all nixbld users are in the nixbld group
380396
check_nixbld_users()

ansible/playbook.yml

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,17 +204,11 @@
204204
apt autoremove -y --purge snapd
205205
when: stage2_nix
206206

207-
- name: Install osquery from nixpkgs binary cache
208-
become: yes
209-
shell: |
210-
sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:nixos/nixpkgs/f98ec4f73c762223d62bee706726138cb6ea27cc#osquery"
211-
when: stage2_nix
212-
213-
- name: Run osquery permission checks
207+
- name: Run permission checks
214208
become: yes
215209
shell: |
216210
systemctl start postgresql.service
217-
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 '' }}"
211+
/usr/bin/python3 /tmp/ansible-playbook/ansible/files/permission_check.py {{ '--qemu' if qemu_mode is defined else '' }}
218212
systemctl stop postgresql.service
219213
when: stage2_nix
220214

@@ -226,12 +220,6 @@
226220
systemctl stop fail2ban.service
227221
when: stage2_nix
228222

229-
- name: Remove osquery
230-
become: yes
231-
shell: |
232-
sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove osquery"
233-
when: stage2_nix
234-
235223
- name: nix collect garbage
236224
become: yes
237225
shell: |

ansible/tasks/setup-wal-g.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,21 @@
3333
cmd: sudo -u wal-g bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/{{ git_commit_sha }}#wal-g-2"
3434
become: true
3535

36+
- name: nix collect garbage
37+
ansible.builtin.shell:
38+
cmd: sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix-collect-garbage -d"
39+
become: true
40+
3641
- name: Install wal-g 3 from nix binary cache
3742
ansible.builtin.shell:
3843
cmd: sudo -u wal-g bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/{{ git_commit_sha }}#wal-g-3"
3944
become: true
4045

46+
- name: nix collect garbage
47+
ansible.builtin.shell:
48+
cmd: sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix-collect-garbage -d"
49+
become: true
50+
4151
- name: Create symlink for wal-g-3 from Nix profile to /usr/local/bin
4252
ansible.builtin.file:
4353
dest: '/usr/local/bin/wal-g-v3'

0 commit comments

Comments
 (0)