Skip to content

Commit 2f18016

Browse files
committed
test: some sanity tests for jit pam module
1 parent a118e56 commit 2f18016

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
@@ -617,6 +617,140 @@ def test_libpq5_version(host):
617617
print("✓ libpq5 version is >= 14")
618618

619619

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

0 commit comments

Comments
 (0)