UNIX 시스템의 섀도우 패스워드 데이터베이스(shadow password database)에 접근하려면 Python의 spwd 모듈을 사용해야 합니다. 섀도우 패스워드 파일은 민감한 정보(암호화된 비밀번호 등)를 담고 있으므로, 이 파일에 접근하려면 root 권한과 같은 충분한 시스템 권한이 필요합니다.
섀도우 패스워드 데이터베이스의 각 항목(entry)은 튜플과 유사한 객체 형태로 반환되며, 인덱스 또는 속성 이름으로 값을 조회할 수 있습니다.
spwd 모듈 임포트하기
spwd 모듈을 사용하려면 먼저 다음과 같이 임포트합니다.
import spwd
섀도우 패스워드 데이터베이스의 주요 속성
반환되는 항목 객체는 아래와 같은 속성들을 가지고 있습니다.
| 인덱스 | 속성 및 설명 |
|---|---|
| 0 | sp_nam 로그인 이름(사용자 계정명) |
| 1 | sp_pwd 암호화된 비밀번호 |
| 2 | sp_lstchg 비밀번호가 마지막으로 변경된 날짜 |
| 3 | sp_min 비밀번호 변경 사이에 필요한 최소 일수 |
| 4 | sp_max 비밀번호 변경 사이의 최대 허용 일수 |
| 5 | sp_warn 비밀번호 만료 전에 사용자에게 경고를 보내는 일수 |
| 6 | sp_inact 비밀번호 만료 후 계정이 잠기기까지의 유예 일수 |
| 7 | sp_expire 1970년 1월 1일 기준으로 계정이 비활성화되는 날까지의 일수 |
| 8 | sp_flag 예약된 필드(Reserved) |
spwd 모듈의 주요 메서드
1. spwd.getspnam(name)
지정한 사용자 이름에 해당하는 섀도우 패스워드 데이터베이스 항목 하나를 반환합니다. 해당 사용자가 존재하지 않으면 KeyError가 발생합니다.
2. spwd.getspall()
시스템에서 읽을 수 있는 모든 섀도우 패스워드 데이터베이스 항목을 리스트 형태로 반환합니다.
예제 코드
import spwd
# root 계정의 비밀번호 상세 정보 출력
print("Root: " + str(spwd.getspnam('root')) + '\n')
# 모든 섀도우 패스워드 항목 순회하며 출력
for entry in spwd.getspall():
print("Name: " + entry[0] + "\t\tPassword: " + entry.sp_pwdp)
실행 결과
(원하는 출력 결과를 얻으려면 스크립트를 sudo 모드로 실행해야 합니다.)
$ sudo python3 example.py Root: spwd.struct_spwd(sp_namp='root', sp_pwdp='!', sp_lstchg=17778, sp_min=0, sp_max=99999, sp_warn=7, sp_inact=-1, sp_expire=-1, sp_flag=-1) …….. …….. …….. Name: geoclue Password: * Name: gnome-initial-setup Password: * Name: gdm Password: * Name: unix_user Password: $6$47n9s0Ep$znWkgNtywebHGKq2o6kZKhGOM8ryp8z4/6P6PUE1m.NQ5Erg9aWncNUAGbuNLFNWUO9M9xzKLxRpFGB5md/nu1 Name: mongodb Password: !
출력 결과에서 각 계정의 암호화된 비밀번호 필드를 확인할 수 있습니다. *나 !로 표시된 계정은 직접 로그인이 비활성화된 시스템 계정이며, 실제 해시 값이 있는 계정만 비밀번호 인증이 가능합니다.
참고 사항
spwd 모듈은 Python 3.11부터 폐기(deprecated)되었으며, Python 3.13에서는 표준 라이브러리에서 제거되었습니다. 최신 Python 버전에서는 pwd 모듈과 함께 시스템 명령어(getent shadow 등)를 호출하거나, 서드파티 라이브러리를 사용하는 방식을 고려하는 것이 좋습니다.