각 필드를 위치(position)와 의미(meaning)로 동시에 외우는 것이 핵심이다. 필드 순서가 곧 시험 문제다.
/etc/passwd는 시스템의 모든 계정 목록이다. 이름과 달리 오늘날 실제 암호는 여기 없다.
1980년대까지는 암호 해시가 두 번째 필드에 있었다. 그러나 이 파일은 모든 사용자가 읽어야(644) 한다 — ls -l로 UID를 이름으로 바꾸려면 누구나 읽어야 하기 때문이다.
그래서 해시를 /etc/shadow로 분리(shadow 기법)했고, passwd의 두 번째 필드에는 x만 남았다.
root:x:0:0:root:/root:/bin/bash# 1 2 3 4 5 6 7
#
필드
의미
함정 포인트
1
Username
로그인 이름
최대 32자, 보통 소문자로 시작
2
Password
x = shadow 참조, */! = 잠김, 빈칸 = 무암호
여기에 해시가 있으면 shadow 미사용(구식)
3
UID
사용자 번호
0 = root, 1~999 시스템, 1000~ 일반(배포판별)
4
GID
기본(primary) 그룹 번호
/etc/group의 GID와 매칭
5
GECOS
코멘트(실명, 전화 등)
finger 정보. 콤마로 세분
6
Home Directory
홈 디렉터리 경로
로그인 시 작업 디렉터리
7
Login Shell
로그인 셸
/bin/bash, /sbin/nologin, /bin/false
UID 0은 단순히 "첫 번째 사용자"가 아니라 그 자체가 root 권한의 정의다. 커널은 이름이 root인지 보지 않고 UID가 0인지만 본다. 따라서 passwd에서 어떤 일반 계정의 UID를 0으로 바꾸면 그 계정은 즉시 root와 동등한 권한을 갖는다. 이게 침입자가 백도어를 심는 고전적 수법이고, 시험에서 "UID가 0인 계정이 root 외에 또 있다 = 보안 위협"으로 출제된다.
7번째 필드(셸)에 /sbin/nologin이나 /bin/false를 넣으면 그 계정은 로그인이 차단된다. 차이가 있다. /bin/false는 아무 메시지 없이 즉시 종료(exit 1)하고, /sbin/nologin은 "This account is currently not available." 같은 안내 메시지를 출력한 뒤 종료한다. 데몬 전용 계정(daemon, bin, nobody 등)이 이 셸을 갖는 이유는, 그 계정으로는 대화형 로그인이 일어나면 안 되기 때문이다. 메시지는 /etc/nologin.txt로 커스터마이즈할 수 있다.
⚠️ 함정: GECOS 필드(5번째)를 "암호 필드"로 착각하는 보기가 있다. 암호는 2번째(현재는 x), 실제 해시는 shadow에 있다. 또 6번째(홈)와 7번째(셸)의 순서를 바꾼 보기도 오답으로 쓰인다. 순서는 홈이 먼저, 셸이 마지막이다.
# 직접 쳐보기 — passwd 구조 관찰cat /etc/passwd | head -5 # 시스템 계정들getent passwd root # NSS를 거친 조회(LDAP 포함)awk -F: '$3==0 {print $1}' /etc/passwd # UID 0인 계정 전부 출력(root만 나와야 정상)awk -F: '$3>=1000 && $3<60000 {print $1}' /etc/passwd # 일반 사용자만
GECOS라는 이름은 1970년대 General Electric Comprehensive Operating System에서 왔다. 초기 유닉스가 GE 메인프레임에 배치 작업을 보낼 때 그 시스템이 요구하는 계정 정보를 이 필드에 적었던 흔적이다. 지금은 그냥 "사용자 코멘트 필드"로 쓰이지만 이름만 화석처럼 남았다. chfn 명령으로 이 필드를 수정한다.
3번 필드부터 8번 필드까지의 날짜·일수는 모두 1970년 1월 1일(Unix Epoch)을 기준으로 한 값이다. "Last Change = 19700"이면 1970년 1월 1일로부터 19700일이 지난 날 암호를 바꿨다는 뜻이다. 사람이 읽기 어렵기 때문에 chage -l user1로 사람이 읽는 날짜로 변환해 본다.
2번 필드의 해시 앞 접두사가 알고리즘을 나타낸다. $1$=MD5, $2a$/$2y$=Blowfish, $5$=SHA-256, $6$=SHA-512. 현대 배포판 기본은 $6$다. 형식은 $id$salt$hash로, salt(난수)가 들어가기에 같은 암호라도 사용자마다 해시가 다르다. 만약 이 필드가 !나 !!로 시작하면 "잠긴 상태에서의 원래 해시 보존"을 뜻한다. passwd -l은 해시 앞에 !를 붙여 잠그고, passwd -u는 그 !를 떼어 푼다.
⚠️ 함정: Min(4번)과 Max(5번)의 순서, 그리고 Warn(6번)과 Inactive(7번)의 의미를 뒤바꾼 보기가 오답으로 쓰이기 쉽다. 외우는 순서: "마지막변경 → 최소 → 최대 → 경고 → 비활성 → 만료". 또 7번 Inactive("암호 만료 후 계정 잠금 유예")와 8번 Expire("계정 자체 절대 만료일")를 혼동시키는 문제가 있다. Inactive는 암호 만료에 연동, Expire는 절대 날짜다.
2번 필드가 빈칸이면 무암호 로그인 가능(매우 위험), *나 !이면 로그인 불가(데몬 계정의 정상 상태)다. 빈칸과 *을 같은 것으로 묶은 보기는 틀렸다.
# 직접 쳐보기 — shadow 수명 정책 확인sudo getent shadow user1 # shadow 한 줄sudo chage -l user1 # 사람이 읽는 형식으로 만료 정책sudo cat /etc/shadow | cut -d: -f1,3,4,5 # 이름:마지막변경:Min:Max
shadow 기법은 1987년 SunOS에서 처음 도입됐고, 이후 모든 유닉스 계열로 퍼졌다. 도입 동기는 단순했다 — passwd는 644로 모두가 읽어야 하는데(이름↔UID 변환 때문) 거기 해시가 있으면 누구나 해시를 복사해 오프라인 무차별 대입(brute force) 공격을 걸 수 있었다. 해시만 400 파일로 떼어내자 이 공격 표면이 사라졌다. "왜 암호를 passwd가 아닌 shadow에 두는가?"의 정답이 바로 이것이다.
/etc/group은 그룹의 목록과 그 멤버를 담는다. 권한은 644(모두 읽기)다. 한 줄은 4개 필드다.
developers:x:1500:alice,bob,carol# 1 2 3 4
#
필드
의미
1
Group Name
그룹 이름
2
Password
x = gshadow 참조(대부분 사용 안 함)
3
GID
그룹 번호
4
Member List
보조 그룹 멤버(콤마 구분)
여기서 가장 헷갈리는 지점 — passwd의 4번째 필드(GID)가 가리키는 그룹은 그 사용자의 기본(primary) 그룹이고, /etc/group의 4번째 멤버 목록에 이름이 들어 있으면 그건 보조(secondary) 그룹이다. 따라서 어떤 사용자가 자기 기본 그룹의 멤버 목록에는 안 적혀 있을 수 있다. alice의 passwd GID가 1500이면 alice는 developers의 멤버지만 group 파일의 멤버 목록(4번 필드)에는 굳이 안 적힌다. groups alice로 보면 둘 다 합쳐 나온다.
사용자가 새 파일을 만들면 그 파일의 그룹 소유자는 기본 그룹(passwd의 GID)이 된다. 보조 그룹은 "그 그룹에 속한 파일에 대한 접근 권한"을 부여할 뿐, 새로 만든 파일의 기본 소유 그룹이 되지는 않는다. (단, 디렉터리에 SetGID가 걸려 있으면 예외 — Day 4에서 다룬다.)
group 파일의 4번 필드는 보조 그룹 멤버만 나열한다. "이 목록에 없으면 그룹 소속이 아니다"는 틀렸다 — 기본 그룹은 passwd에서 결정되므로 목록에 없어도 소속일 수 있다. id user1로 primary/secondary를 한눈에 확인할 수 있다.
# 직접 쳐보기 — 그룹 소속 추적id alice # uid, gid(primary), groups(전체)groups alice # 소속 그룹 이름들getent group developers # 특정 그룹의 멤버 목록awk -F: '$3>=1000{print $1,$3}' /etc/group # 일반 그룹들
그룹 암호(2번 필드)는 newgrp 명령으로 자신의 기본 그룹을 일시적으로 바꿀 때 쓰인다. 그 그룹 멤버가 아닌 사용자가 그룹 암호를 알면 newgrp로 그 그룹에 임시 합류할 수 있다. 그러나 보안상 위험해 현대 시스템에서는 거의 비활성(!)이다. 3번 필드의 관리자는 gpasswd로 멤버를 추가/삭제할 수 있는 사용자다.
group과 gshadow의 4번째 멤버 목록은 gpasswd나 usermod로 바꾸면 두 파일이 동기화된다. 손으로 group만 고치고 gshadow를 안 고치면 불일치가 생기고, grpck 명령으로 이런 불일치를 검사할 수 있다. (passwd↔shadow의 짝은 pwck로 검사한다.)
"그룹 암호는 group 파일의 2번 필드에 저장된다"는 틀렸다. group의 2번 필드는 x(gshadow 참조 표시)일 뿐, 실제 그룹 암호 해시는 gshadow의 2번 필드에 있다. passwd↔shadow 관계와 똑같은 구조다.
# 직접 쳐보기 — 네 파일의 짝 관계 점검sudo pwck -r # passwd ↔ shadow 정합성 검사(읽기전용)sudo grpck -r # group ↔ gshadow 정합성 검사sudo getent gshadow developers
한 대학 전산실에서 조교가 /etc/group만 vi로 직접 편집해 학생을 그룹에서 뺐는데, gpasswd를 통하지 않아 /etc/gshadow의 멤버 목록이 그대로 남았다. 일부 도구는 gshadow를 우선 참조했기에 "뺐는데도 권한이 남는" 유령 멤버 현상이 생겼다. 교훈: 계정·그룹 파일은 직접 편집보다 전용 명령(usermod, gpasswd, vipw, vigr)을 거쳐 짝 파일을 동시에 갱신하는 것이 원칙이다. vipw/vigr은 잠금을 걸고 안전하게 편집하며, -s 옵션으로 shadow/gshadow를 편집한다.