파일 · 권한 · 사용자 관리 40 / 50 · Part 4. 사용자와 그룹 관리
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정analyst)
기초편 연계: 「리눅스 시스템 기초」 18. Linux 사용자와 그룹
Part 4의 마지막 글이다. 지금까지 사용자·그룹의 구조와 관리 명령을 다뤘다. 이번 글에서는 특별한 계정들 — root와 시스템 계정 — 을 정리한다.
bin·daemon·nginx·postgres 등): 서비스마다 계정을 나누는 이유그리고 계정 보안의 가장 기본이자 중요한 점검 — UID 0은 root 하나뿐이어야 한다 — 을 확인한다.
| 계정 | UID | 역할 |
|---|---|---|
| root | 0 | 슈퍼유저. 권한 검사 우회 |
| 시스템 계정 | 1~999 | 서비스별 격리 계정 |
| nobody | 65534 | 권한 최소 계정 |
| 일반 사용자 | 1000~ | 로그인 사용자 |
root의 권한은 이름 root가 아니라 UID 0 에서 나온다(31편). /etc/passwd에 UID 0인 계정을 하나 더 만들면 이름이 무엇이든 root와 동등한 권한을 갖는다. 그래서 UID 0 계정은 root 하나여야 한다.
웹 서버(nginx), DB(postgres) 등은 각자 전용 계정으로 실행된다. 이유는 침해 범위 제한 이다. nginx가 nginx 계정으로 돌면, 웹 취약점으로 침해돼도 공격자는 nginx 권한만 얻는다. 반대로 root로 돌리면 침해 즉시 시스템 전체가 장악된다.
시스템 계정의 공통 특징:
nologin/false (대화형 로그인 차단)!/*)/var/lib/... 등)
최소 권한 원칙(45편)이 계정 설계의 근거다. 각 서비스에 필요한 최소한의 권한만 가진 전용 계정을 주면, 하나가 침해돼도 나머지가 보호된다. 이것이 "서비스마다 계정을 나누는" 이유다.
root는 이 원칙의 예외이자 위험 지점이다. root는 거의 모든 권한 검사를 우회하므로(21편), root 권한 탈취는 곧 전체 장악이다. 그래서:
nobody는 반대 극단이다. 어떤 파일도 소유하지 않고 어떤 특권도 없어야 하는, 격리가 필요한 프로세스용 계정이다. 여러 서비스가 nobody를 공유하면 격리가 약해지므로, 현대에는 서비스별 전용 계정을 선호한다.
# 1) root
getent passwd root
# 2) 주요 시스템 계정
for u in daemon bin sys nobody; do getent passwd $u 2>/dev/null; done
# 3) nobody
getent passwd nobody
# 4) 시스템 계정의 공통 특징: nologin 셸
awk -F: '$3<1000 && $3>0 {print $1" (uid="$3", shell="$7")"}' /etc/passwd | head -15
# 5) 핵심 점검: UID 0 은 root 뿐이어야 정상
awk -F: '$3==0 {print $1}' /etc/passwd

텍스트 원본(실제 출력):
[analyst@rocky9-lab ~]$ echo "=== root (UID 0) ==="
=== root (UID 0) ===
[analyst@rocky9-lab ~]$ getent passwd root
root:x:0:0:root:/root:/bin/bash
[analyst@rocky9-lab ~]$ echo "=== 주요 시스템 계정과 역할 ==="
=== 주요 시스템 계정과 역할 ===
[analyst@rocky9-lab ~]$ for u in daemon bin sys nobody; do getent passwd $u 2>/dev/null; done
daemon:x:2:2:daemon:/sbin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
[analyst@rocky9-lab ~]$ echo "=== nobody: 권한 최소 계정 ==="
=== nobody: 권한 최소 계정 ===
[analyst@rocky9-lab ~]$ getent passwd nobody
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
[analyst@rocky9-lab ~]$ echo "=== 시스템 계정의 공통 특징: nologin 셸 ==="
=== 시스템 계정의 공통 특징: nologin 셸 ===
[analyst@rocky9-lab ~]$ awk -F: '$3<1000 && $3>0 {print $1" (uid="$3", shell="$7")"}' /etc/passwd | head -15
bin (uid=1, shell=/sbin/nologin)
daemon (uid=2, shell=/sbin/nologin)
adm (uid=3, shell=/sbin/nologin)
lp (uid=4, shell=/sbin/nologin)
sync (uid=5, shell=/bin/sync)
shutdown (uid=6, shell=/sbin/shutdown)
halt (uid=7, shell=/sbin/halt)
mail (uid=8, shell=/sbin/nologin)
operator (uid=11, shell=/sbin/nologin)
games (uid=12, shell=/sbin/nologin)
ftp (uid=14, shell=/sbin/nologin)
tss (uid=59, shell=/usr/sbin/nologin)
systemd-coredump (uid=999, shell=/sbin/nologin)
[analyst@rocky9-lab ~]$ echo "=== UID 0 은 root 뿐이어야 정상 ==="
=== UID 0 은 root 뿐이어야 정상 ===
[analyst@rocky9-lab ~]$ awk -F: '$3==0 {print $1}' /etc/passwd
root
| 출력 | 해석 |
|---|---|
root:x:0:0:root:/root:/bin/bash | UID·GID 0. 유일한 슈퍼유저여야 함 |
daemon:x:2:2:daemon:/sbin:/sbin/nologin | 시스템 계정, nologin 셸 |
nobody:x:65534:...:/sbin/nologin | 권한 최소 계정. Rocky는 GECOS가 "Kernel Overflow User" |
시스템 계정 목록 대부분 /sbin/nologin | 로그인 차단이 공통 특징 |
sync (shell=/bin/sync), shutdown, halt | 특수 셸을 가진 역사적 계정(로그인하면 해당 동작만 수행) |
awk '$3==0' → root | UID 0이 root 하나뿐 → 정상 |
마지막 줄이 이번 글의 핵심 점검 결과다. root만 나오면 정상, toor·admin 등이 함께 나오면 백도어다.
sync·shutdown·halt 계정의 특수 셸도 흥미롭다. 이들은 로그인하면 셸 대신 해당 명령만 실행하는 역사적 계정으로, 현대 서버에서는 거의 쓰이지 않지만 기본 포함된다.
| 점검 | 명령 | 위험 |
|---|---|---|
| UID 0 유일성 | awk -F: '$3==0' | 추가 계정 = 백도어 root |
| 서비스 계정 셸 | 시스템 계정의 7번 필드 | nologin이 아니면 이상 |
| 서비스 실행 계정 | ps -eo user,comm | 서비스가 root로 실행 |
| nobody 소유 파일 | find / -user nobody | nobody가 파일 소유하면 격리 약화 |
| root 로그인 | sshd_config PermitRootLogin | 직접 root 로그인 허용 |
핵심 원칙 두 가지:
[핵심 점검] awk -F: '($3==0){print "UID0:",$1}' /etc/passwd # root 외 있으면 즉시 조사
ps -eo user,pid,comm | awk '$1=="root"' # root 실행 프로세스 검토
↓
[이상 신호] UID 0 추가 계정 / 서비스 계정 로그인 셸 / 서비스의 불필요한 root 실행
↓
[Evidence] /etc/passwd ctime, 계정 생성 로그(useradd), 프로세스 실행 계정
↓
[Detection] /etc/passwd 변경, UID 0 계정 추가를 FIM·auditd 로 실시간 탐지
↓
[Response] 백도어 계정 즉시 잠금·삭제, 침입 경로(권한 상승, 49편) 조사
| 관점 | 내용 |
|---|---|
| 최우선 IOC | UID 0 추가 계정. 계정 보안 점검의 1순위 |
| 서비스 격리 | 서비스가 전용 계정으로 도는지, root로 도는지 확인 |
| Detection | /etc/passwd의 UID 0 항목 추가를 즉시 알림 |
| 실수 | 결과 | 예방 |
|---|---|---|
| 서비스를 root로 실행 | 침해 시 전체 장악 | 전용 최소 권한 계정 |
| UID 0 중복 미점검 | 백도어 방치 | 상시 awk '$3==0' |
| 시스템 계정에 로그인 셸 부여 | 발판 제공 | nologin 유지 |
| root 직접 로그인 허용 | 무차별 대입 표적 | sudo 위임, PermitRootLogin no |
| nobody로 여러 서비스 실행 | 격리 약화 | 서비스별 계정 |
[ ] root 가 UID 0 임을 확인했다
[ ] 시스템 계정의 nologin 셸을 확인했다
[ ] nobody 의 역할을 이해했다
[ ] UID 0 이 root 뿐인지 점검했다
[ ] 서비스를 전용 계정으로 실행해야 하는 이유를 설명할 수 있다
[ ] UID 0 추가 계정이 최우선 IOC 임을 안다
Part 4 정리 — 31~40편에서 계정 구조, passwd·shadow·group 파일, useradd·usermod·userdel, groupadd 체계, 기본/보조 그룹, root·시스템 계정까지 사용자·그룹 관리 전체 를 다뤘다. Part 5부터는 이 계정들의 권한 상승과 보안 점검 을 다룬다.
Part 5 「권한 상승과 Linux 보안」을 시작한다. 다음 글 「41. su와 sudo의 차이」 에서는 일반 사용자가 root 권한을 얻는 두 방법을 비교한다. 특히 추적성 의 차이 — sudo는 명령 단위로 로그를 남기고, su는 그렇지 않다 — 를 실제 로그로 확인한다.