Skip to content

Commit f9ef9b7

Browse files
committed
test: some sanity tests for jit pam module
1 parent fdd95c8 commit f9ef9b7

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

testinfra/test_ami_nix.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,140 @@ def test_libpq5_version(host):
589589
print("✓ libpq5 version is >= 14")
590590

591591

592+
def test_jit_pam_module_installed(host):
593+
"""Test that the JIT PAM module (pam_jit_pg.so) is properly installed."""
594+
# Check if gatekeeper is installed via Nix
595+
result = run_ssh_command(host['ssh'], "sudo -u postgres ls -la /var/lib/postgresql/.nix-profile/lib/security/pam_jit_pg.so 2>/dev/null")
596+
if result['succeeded']:
597+
print(f"\nJIT PAM module found in Nix profile:\n{result['stdout']}")
598+
else:
599+
print("\nJIT PAM module not found in postgres user's Nix profile")
600+
assert False, "JIT PAM module (pam_jit_pg.so) not found in expected location"
601+
602+
# Check if the symlink exists in the Linux PAM security directory
603+
result = run_ssh_command(host['ssh'], "find /nix/store -type f -path '*/lib/security/pam_jit_pg.so' 2>/dev/null | head -5")
604+
if result['succeeded'] and result['stdout'].strip():
605+
print(f"\nJIT PAM module symlinks found:\n{result['stdout']}")
606+
else:
607+
print("\nNo JIT PAM module symlinks found in /nix/store")
608+
609+
# Verify the module is a valid shared library
610+
result = run_ssh_command(host['ssh'], "file /var/lib/postgresql/.nix-profile/lib/security/pam_jit_pg.so")
611+
if result['succeeded']:
612+
print(f"\nJIT PAM module file type:\n{result['stdout']}")
613+
assert "shared object" in result['stdout'].lower() or "dynamically linked" in result['stdout'].lower(), \
614+
"JIT PAM module is not a valid shared library"
615+
616+
print("✓ JIT PAM module is properly installed")
617+
618+
619+
def test_pam_postgresql_config(host):
620+
"""Test that the PAM configuration for PostgreSQL exists and is properly configured."""
621+
# Check PostgreSQL version to determine if PAM config should exist
622+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql --version | grep -oE '[0-9]+' | head -1")
623+
pg_major_version = 15 # Default
624+
if result['succeeded'] and result['stdout'].strip():
625+
try:
626+
pg_major_version = int(result['stdout'].strip())
627+
except ValueError:
628+
pass
629+
630+
print(f"\nPostgreSQL major version: {pg_major_version}")
631+
632+
# PAM config should exist for non-PostgreSQL 15 versions
633+
if pg_major_version != 15:
634+
# Check if PAM config file exists
635+
result = run_ssh_command(host['ssh'], "ls -la /etc/pam.d/postgresql")
636+
if result['succeeded']:
637+
print(f"\nPAM config file found:\n{result['stdout']}")
638+
639+
# Check file permissions
640+
result = run_ssh_command(host['ssh'], "stat -c '%a %U %G' /etc/pam.d/postgresql")
641+
if result['succeeded']:
642+
perms = result['stdout'].strip()
643+
print(f"PAM config permissions: {perms}")
644+
# Should be owned by postgres:postgres with 664 permissions
645+
assert "postgres postgres" in perms, "PAM config not owned by postgres:postgres"
646+
else:
647+
print("\nPAM config file not found")
648+
assert False, "PAM configuration file /etc/pam.d/postgresql not found"
649+
else:
650+
print("\nSkipping PAM config check for PostgreSQL 15")
651+
# For PostgreSQL 15, the PAM config should NOT exist
652+
result = run_ssh_command(host['ssh'], "test -f /etc/pam.d/postgresql")
653+
if result['succeeded']:
654+
print("\nWARNING: PAM config exists for PostgreSQL 15 (not expected)")
655+
656+
print("✓ PAM configuration is properly set up")
657+
658+
659+
def test_jit_pam_gatekeeper_profile(host):
660+
"""Test that the gatekeeper package is properly installed in the postgres user's Nix profile."""
661+
# Check if gatekeeper is in the postgres user's Nix profile
662+
result = run_ssh_command(host['ssh'], "sudo -u postgres nix profile list 2>/dev/null | grep -i gatekeeper")
663+
if result['succeeded'] and result['stdout'].strip():
664+
print(f"\nGatekeeper found in Nix profile:\n{result['stdout']}")
665+
else:
666+
# Try alternative check
667+
result = run_ssh_command(host['ssh'], "sudo -u postgres ls -la /var/lib/postgresql/.nix-profile/ | grep -i gate")
668+
if result['succeeded'] and result['stdout'].strip():
669+
print(f"\nGatekeeper-related files in profile:\n{result['stdout']}")
670+
else:
671+
print("\nGatekeeper not found in postgres user's Nix profile")
672+
# This might be expected if it's installed system-wide instead
673+
674+
# Check if we can find the gatekeeper derivation
675+
result = run_ssh_command(host['ssh'], "find /nix/store -maxdepth 1 -type d -name '*gatekeeper*' 2>/dev/null | head -5")
676+
if result['succeeded'] and result['stdout'].strip():
677+
print(f"\nGatekeeper derivations found:\n{result['stdout']}")
678+
else:
679+
print("\nNo gatekeeper derivations found in /nix/store")
680+
681+
print("✓ Gatekeeper package installation check completed")
682+
683+
684+
def test_jit_pam_module_dependencies(host):
685+
"""Test that the JIT PAM module has all required dependencies."""
686+
# Check dependencies of the PAM module
687+
result = run_ssh_command(host['ssh'], "ldd /var/lib/postgresql/.nix-profile/lib/security/pam_jit_pg.so 2>/dev/null")
688+
if result['succeeded']:
689+
print(f"\nJIT PAM module dependencies:\n{result['stdout']}")
690+
691+
# Check for required libraries
692+
required_libs = ["libpam", "libc"]
693+
for lib in required_libs:
694+
if lib not in result['stdout'].lower():
695+
print(f"WARNING: Required library {lib} not found in dependencies")
696+
697+
# Check for any missing dependencies
698+
if "not found" in result['stdout'].lower():
699+
assert False, "JIT PAM module has missing dependencies"
700+
else:
701+
print("\nCould not check JIT PAM module dependencies")
702+
703+
print("✓ JIT PAM module dependencies are satisfied")
704+
705+
706+
def test_jit_pam_postgresql_integration(host):
707+
"""Test that PostgreSQL can be configured to use PAM authentication."""
708+
# Check if PAM is available as an authentication method in PostgreSQL
709+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c \"SELECT name, setting FROM pg_settings WHERE name LIKE '%pam%';\" 2>/dev/null")
710+
if result['succeeded']:
711+
print(f"\nPostgreSQL PAM-related settings:\n{result['stdout']}")
712+
713+
# Check pg_hba.conf for potential PAM entries (even if not currently active)
714+
result = run_ssh_command(host['ssh'], "grep -i pam /etc/postgresql/pg_hba.conf 2>/dev/null || echo 'No PAM entries in pg_hba.conf'")
715+
if result['succeeded']:
716+
print(f"\nPAM entries in pg_hba.conf:\n{result['stdout']}")
717+
718+
# Verify PostgreSQL was compiled with PAM support
719+
result = run_ssh_command(host['ssh'], "sudo -u postgres pg_config --configure 2>/dev/null | grep -i pam || echo 'PAM compile flag not found'")
720+
if result['succeeded']:
721+
print(f"\nPostgreSQL PAM compile flags:\n{result['stdout']}")
722+
723+
print("✓ PostgreSQL PAM integration check completed")
724+
725+
592726
def test_postgrest_read_only_session_attrs(host):
593727
"""Test PostgREST with target_session_attrs=read-only and check for session errors."""
594728
# First, check if PostgreSQL is configured for read-only mode

0 commit comments

Comments
 (0)