리눅스는 어떻게 여러 사용자가 동시에 사용하는 멀티 유저 환경을 효율적으로 관리할 수 있을까요? 이 글에서는 리눅스가 사용자 암호와 로그인 정보를 저장하고 관리하는 방식을 단계별로 자세히 살펴봅니다.
/etc/passwd 파일 살펴보기
사용자가 아이디와 비밀번호를 입력하면 리눅스는 /etc 디렉터리 안의 여러 파일에 기록된 내용과 입력값을 대조해 신원을 확인합니다.
그중 /etc/passwd 파일은 사용자 정보를 저장하는 가장 핵심적인 파일입니다.
이 파일의 마지막 항목은 carbon이라는 사용자에 해당하며, 각 항목은 콜론(:)으로 구분된 여러 필드로 이루어져 있습니다.
carbon: 이 항목에 해당하는 사용자의 이름입니다.x: 해당 사용자에게 비밀번호가 존재한다는 의미입니다. 실제 비밀번호는 /etc/shadow 파일에 별도로 저장됩니다. 만약 x 대신!기호가 표시되어 있다면 비밀번호가 설정되어 있지 않다는 뜻입니다.1000: 이 사용자의 UID(사용자 ID)입니다.1000: 이 사용자가 소속된 그룹의 GID(그룹 ID)입니다.carbon, , ,: 전체 이름, 전화번호 등 부가 정보를 담는 필드입니다. 여기서는 전화번호가 입력되지 않았습니다./home/carbon: 이 사용자에게 할당된 홈 디렉터리의 경로입니다./bin/bash: 이 사용자에게 할당된 기본 셸입니다.
이번에는 전화번호까지 함께 저장된 새로운 사용자를 만들어 보겠습니다. adduser 명령어를 사용해 pluto 사용자를 시스템에 추가합니다.
다시 /etc/passwd 파일을 확인하면 pluto 사용자의 전체 정보를 볼 수 있습니다. 전체 이름과 연락처가 쉼표로 구분되어 나열된 이 필드를 GECOS 필드라고 부릅니다.
사용자를 생성할 때 할당되는 홈 디렉터리와 기본 셸의 기본값은 /etc/adduser.conf 파일에 지정되어 있습니다.
새로 생성되는 사용자의 ID는 1000번부터 59999번 사이의 값으로 자동 부여됩니다.
carbon 사용자는 cat 명령어만으로 /etc/passwd 파일의 내용을 열람할 수 있었습니다. 이 파일의 권한을 확인해 보겠습니다.
파일에 쓰기 작업을 할 수 있는 것은 root 사용자뿐이며, 나머지 사용자는 읽기만 가능합니다. 모든 사용자가 이 파일을 읽을 수 있기 때문에 여기에 비밀번호를 직접 저장하는 것은 보안상 바람직하지 않습니다. 그래서 비밀번호는 /etc/shadow라는 별도의 파일에 따로 보관됩니다.
/etc/shadow 파일 살펴보기
이제 /etc/shadow 파일에서 carbon과 pluto 사용자의 저장된 비밀번호를 확인해 보겠습니다.
/etc/shadow 파일의 권한을 보면 root 사용자만 읽고 쓸 수 있으며, shadow 그룹에 속한 멤버만 읽기가 허용됩니다. 실제로 shadow 그룹은 비어 있지만, 이 파일의 구조상 반드시 필요한 그룹입니다.
root로 로그인하면 /etc/shadow의 마지막 열 줄을 확인할 수 있습니다. /etc/passwd의 모든 항목에는 이 파일에 대응하는 항목이 하나씩 존재하며, 형식은 다음과 같습니다.
pluto:$6$JvWfZ9u....:18283:0:99999:7:::
이 파일 역시 모든 항목이 콜론(:)으로 구분된 여러 필드로 구성됩니다. pluto 사용자의 항목을 하나씩 해석해 보겠습니다.
pluto: 이 항목에 해당하는 사용자의 이름입니다.$6$JvWfZ9u.$yGFIqOJ....: 해시 알고리즘 정보와 함께 저장된 해시된 비밀번호입니다. 평문 비밀번호에 솔트(salt) 값을 결합해 해시를 생성합니다.
{ 평문 비밀번호, 솔트 } -> 해시된 비밀번호
이 필드의 내용을 자세히 분석해 보겠습니다. $ 기호는 세 개의 필드를 구분하는 구분자로 사용됩니다.
$6 $JvWfZ9u. $yGFIqOJ....
$6: 사용된 해시 알고리즘을 나타냅니다. 주요 해시 알고리즘 목록은 다음과 같습니다.- $1 : MD5
- $2a : Blowfish
- $2y : Eksblowfish
- $5 : SHA-256
- $6 : SHA-512
$JvWfZ9u.: 솔트 값입니다.$yGFIqOJ....: 해시된 비밀번호입니다.
최종적으로 생성된 해시 값이 사용자의 암호화된 비밀번호로 저장됩니다. 솔트 값은 사용자마다 고유하게 부여되므로, 두 사용자가 우연히 같은 평문 비밀번호를 사용하더라도 서로 다른 해시 값이 생성됩니다.
이 항목의 나머지 필드들도 차례로 살펴보겠습니다.
18283: 1970년 1월 1일을 기준으로 비밀번호가 마지막으로 변경된 날짜까지의 일수입니다.0: 비밀번호를 다시 변경할 수 있기까지 필요한 최소 일수입니다. 값이 0이면 언제든지 변경할 수 있습니다.99999: 비밀번호를 반드시 변경해야 하는 최대 일수입니다. 값이 99999면 사용자가 원하는 만큼 오랫동안 비밀번호를 유지할 수 있습니다.7: 비밀번호 만료가 설정된 경우, 만료 전에 사용자에게 경고를 보내는 일수입니다.: : :: 이 항목에는 세 개의 필드가 더 있지만 여기서는 모두 비어 있습니다. 첫 번째는 비밀번호 만료 후 계정이 비활성화되기까지 대기하는 일수, 두 번째는 1970년 1월 1일 기준으로 계정이 비활성화된 날짜까지의 일수, 세 번째는 향후 사용을 위해 예약된 필드입니다. 필드가 비어 있다는 것은 현재 비밀번호가 만료되지 않았고 조만간 만료되도록 설정되어 있지 않음을 의미합니다.
비밀번호 유효 기간과 관련된 마지막 일곱 개의 필드를 통틀어 비밀번호 에이징 정책(Password Aging Policy) 정보라고 합니다.
에이징 정책의 기본값은 /etc/login.defs 파일에 지정되어 있으며, chage 명령어를 사용하면 사용자별로 이 값을 변경할 수 있습니다.
그룹 정보는 어디에 저장될까?
사용자 정보와 비밀번호가 /etc/passwd와 /etc/shadow 파일에 저장되듯이, 그룹 정보는 /etc/group 파일에 저장됩니다.
위에서 강조된 부분은 carbon과 pluto 사용자가 속한 그룹들입니다. 리눅스에서 사용자를 생성하면 해당 사용자는 즉시 사용자 이름과 동일한 이름의 그룹에 자동으로 배정됩니다.
그룹 멤버들은 그룹 관련 활동을 위해 그룹 비밀번호를 공유할 수도 있습니다. x 값은 해당 그룹의 비밀번호 정보가 /etc/gshadow 파일에 저장되어 있음을 의미합니다.
단, /etc/gshadow에 대한 접근은 root 사용자로 엄격히 제한됩니다.
root 사용자는 /etc/gshadow의 항목을 열람할 수 있으며, 이 파일의 구조는 /etc/shadow와 유사합니다. carbon 그룹의 항목을 보면 두 번째 필드가 ! 값을 가지는데, 이는 해당 그룹에 비밀번호가 설정되어 있지 않다는 의미입니다.
전체 과정 정리
사용자가 로그인을 시도하면 시스템은 /etc/shadow에 저장된 해당 사용자의 솔트 값을 이용해 입력된 비밀번호의 해시를 계산합니다. 이어서 계산된 해시를 저장된 해시와 비교하고, 두 값이 일치하면 사용자에게 접근 권한이 부여됩니다. 이처럼 리눅스는 passwd, shadow, group, gshadow 파일들의 유기적인 연계를 통해 안전하고 체계적인 멀티 유저 환경을 유지합니다.
함께 읽으면 좋은 글:
- 리눅스에서 루트 비밀번호 재설정하는 방법
- 리눅스 터미널에서 사용자 비밀번호 관리하는 방법