1. 사용자 관련 핵심 파일
1.1 /etc/passwd
시스템의 모든 사용자 계정 정보가 저장된 파일. 모든 사용자가 읽을 수 있다.
username:x:UID:GID:GECOS:home_directory:login_shell
| 필드 | 설명 | 예시 |
|---|---|---|
username | 로그인 사용자명 (최대 32자) | phh |
x | 비밀번호 필드. x는 /etc/shadow에 저장됨을 의미 | x |
UID | 사용자 고유 번호. 0=root, 1-999=시스템, 1000+=일반 | 1000 |
GID | 기본 그룹 번호 (/etc/group의 GID와 대응) | 1000 |
GECOS | 사용자 설명 (이름, 연락처 등). 쉼표로 구분 | Park H H,,, |
home_directory | 홈 디렉토리 경로 | /home/phh |
login_shell | 로그인 시 실행되는 쉘 | /bin/bash |
# 확인
cat /etc/passwd
grep "^phh:" /etc/passwd
# 필드별 추출
awk -F: '{print $1, $3, $6}' /etc/passwd # 사용자명, UID, 홈디렉토리참고: 로그인이 불가능한 시스템 계정은 쉘이 /usr/sbin/nologin 또는 /bin/false로 설정됨.
1.2 /etc/shadow
비밀번호 해시와 비밀번호 정책 정보가 저장된 파일. root만 읽을 수 있다 (퍼미션 640 또는 000).
username:password_hash:lastchange:min:max:warn:inactive:expire:reserved
| 필드 | 설명 |
|---|---|
username | 사용자명 |
password_hash | 비밀번호 해시. $알고리즘$salt$hash 형식. ! 또는 *면 로그인 잠금 |
lastchange | 마지막 비밀번호 변경일 (1970-01-01 기준 일수) |
min | 비밀번호 변경 후 최소 유지 일수 (0이면 즉시 변경 가능) |
max | 비밀번호 최대 유효 일수 (99999면 사실상 무제한) |
warn | 만료 전 경고 시작 일수 (기본 7일) |
inactive | 만료 후 비활성화까지 유예 일수 |
expire | 계정 만료일 (1970-01-01 기준 일수). 빈 값이면 만료 없음 |
reserved | 예약 필드 (미사용) |
비밀번호 해시 알고리즘 식별자:
$1$- MD5$5$- SHA-256$6$- SHA-512 (현재 대부분의 배포판 기본값)$y$- yescrypt (최신 배포판)
sudo cat /etc/shadow
sudo grep "^phh:" /etc/shadow1.3 /etc/group
그룹 정보 파일. 모든 사용자가 읽을 수 있다.
groupname:password:GID:member_list
| 필드 | 설명 |
|---|---|
groupname | 그룹명 |
password | 그룹 비밀번호. x면 /etc/gshadow에 저장 |
GID | 그룹 고유 번호 |
member_list | 보조 그룹 멤버 목록 (쉼표 구분) |
cat /etc/group
grep "docker" /etc/group # docker 그룹 멤버 확인
groups phh # phh가 속한 모든 그룹주의: 사용자의 기본 그룹(primary group)은 /etc/passwd의 GID 필드로 지정되며, /etc/group의 member_list에는 보조 그룹(supplementary group) 멤버만 표시된다.
1.4 /etc/gshadow
그룹의 암호화된 비밀번호 저장. root만 접근 가능.
groupname:password:admins:members
| 필드 | 설명 |
|---|---|
groupname | 그룹명 |
password | 그룹 비밀번호 해시. !면 그룹 비밀번호 미설정 |
admins | 그룹 관리자 목록 (멤버 추가/제거 가능) |
members | 그룹 멤버 목록 |
2. 사용자 관리 명령어
2.1 useradd - 사용자 생성
# 기본 사용
useradd username
# 주요 옵션 조합
useradd -m -s /bin/bash -g developers -G docker,sudo -d /home/newuser newuser| 옵션 | 설명 |
|---|---|
-m | 홈 디렉토리 자동 생성 (/etc/skel 복사) |
-M | 홈 디렉토리를 생성하지 않음 |
-s /bin/bash | 로그인 쉘 지정 |
-g developers | 기본 그룹(primary group) 지정 |
-G docker,sudo | 보조 그룹(supplementary groups) 지정 |
-d /home/newuser | 홈 디렉토리 경로 직접 지정 |
-u 1500 | UID 직접 지정 |
-e 2026-12-31 | 계정 만료일 설정 |
-c "설명" | GECOS 필드(코멘트) 설정 |
-r | 시스템 계정 생성 (UID < 1000, 홈 미생성) |
# 기본값 확인
useradd -D
# /etc/default/useradd 에서 기본값 설정 가능:
# GROUP=100, HOME=/home, INACTIVE=-1, EXPIRE=, SHELL=/bin/sh, SKEL=/etc/skel2.2 usermod - 사용자 수정
# 보조 그룹 추가 (기존 그룹 유지하며 추가 - -a 필수!)
usermod -aG docker phh
usermod -aG sudo phh
# 그룹을 완전히 교체 (주의: 기존 보조 그룹 모두 제거됨)
usermod -G newgroup1,newgroup2 phh
# 계정 잠금/해제
usermod -L phh # Lock - /etc/shadow 비밀번호 앞에 ! 추가
usermod -U phh # Unlock - ! 제거
# 쉘 변경
usermod -s /bin/zsh phh
# 홈 디렉토리 변경 (기존 파일도 이동)
usermod -d /home/newhome -m phh
# 사용자명 변경
usermod -l newname oldname주의: usermod -G에서 -a(append) 옵션을 빠뜨리면 기존 보조 그룹이 모두 삭제된다. 반드시 -aG로 사용할 것.
2.3 userdel - 사용자 삭제
userdel username # 계정만 삭제 (홈 디렉토리 유지)
userdel -r username # 계정 + 홈 디렉토리 + 메일스풀 삭제
userdel -f username # 강제 삭제 (로그인 중이어도)2.4 passwd - 비밀번호 관리
passwd # 현재 사용자 비밀번호 변경
passwd username # 특정 사용자 비밀번호 변경 (root만)
passwd -l username # 계정 잠금 (Lock)
passwd -u username # 계정 잠금 해제 (Unlock)
passwd -d username # 비밀번호 삭제 (비밀번호 없이 로그인 가능 - 위험)
passwd -e username # 비밀번호 즉시 만료 (다음 로그인 시 변경 강제)
passwd -S username # 비밀번호 상태 확인2.5 chage - 비밀번호 에이징 정책
chage -l username # 현재 정책 확인 (가장 많이 사용)
chage -M 90 username # 최대 유효일 90일
chage -m 7 username # 최소 유지일 7일
chage -W 14 username # 만료 14일 전부터 경고
chage -I 30 username # 만료 후 30일 유예
chage -E 2026-12-31 username # 계정 만료일 설정
chage -d 0 username # 다음 로그인 시 비밀번호 변경 강제3. 그룹 관리 명령어
3.1 groupadd - 그룹 생성
groupadd developers # 그룹 생성
groupadd -g 2000 developers # GID 지정하여 생성
groupadd -r sysgroup # 시스템 그룹 생성 (GID < 1000)3.2 groupmod - 그룹 수정
groupmod -n newname oldname # 그룹명 변경
groupmod -g 3000 groupname # GID 변경3.3 groupdel - 그룹 삭제
groupdel groupname제약: 어떤 사용자의 기본 그룹(primary group)으로 설정된 그룹은 삭제 불가. 해당 사용자의 기본 그룹을 먼저 변경해야 한다.
3.4 gpasswd - 그룹 비밀번호/멤버 관리
gpasswd groupname # 그룹 비밀번호 설정
gpasswd -a user groupname # 사용자를 그룹에 추가 (usermod -aG 대안)
gpasswd -d user groupname # 사용자를 그룹에서 제거
gpasswd -A user groupname # 사용자를 그룹 관리자로 설정
gpasswd -r groupname # 그룹 비밀번호 제거4. 사용자 확인 명령어
# 현재 사용자 정보
id # uid, gid, 소속 그룹 전체 표시
id phh # 특정 사용자 정보
id -u # UID만 출력
id -g # 기본 GID만 출력
id -G # 모든 GID 출력
id -nG # 모든 그룹명 출력
whoami # 현재 사용자명 (effective user)
# 로그인한 사용자 확인
who # 현재 로그인한 사용자 목록
who -b # 마지막 부팅 시각
who -q # 사용자명만 간략히
w # who 확장판 - 로그인 사용자 + 실행 중인 명령까지 표시
# 로그인 이력
last # 최근 로그인/로그아웃 이력 (/var/log/wtmp)
last -n 10 # 최근 10건
last reboot # 재부팅 이력
lastb # 실패한 로그인 시도 (/var/log/btmp, root만)
lastlog # 모든 사용자의 마지막 로그인 시각
finger username # 사용자 상세 정보 (설치 필요: apt install finger)5. sudo 메커니즘
5.1 sudo vs su
| 구분 | sudo | su |
|---|---|---|
| 인증 | 본인 비밀번호 | 대상 사용자 비밀번호 |
| 범위 | 명령 단위로 권한 부여 | 완전한 세션 전환 |
| 로그 | 모든 명령 /var/log/auth.log에 기록 | 세션 전환만 기록 |
| 보안 | 세분화된 권한 제어 가능 | root 비밀번호 공유 필요 |
sudo command # root 권한으로 명령 실행
sudo -u www-data command # 특정 사용자 권한으로 실행
sudo -i # root 로그인 쉘 시작
sudo -s # root 쉘 시작 (비로그인)
sudo -l # 현재 사용자의 sudo 권한 확인
sudo -k # sudo 타임스탬프 무효화 (다음에 다시 비밀번호 입력)
sudo !! # 직전 명령을 sudo로 재실행
su # root로 전환 (비로그인 쉘)
su - # root로 전환 (로그인 쉘 - 환경변수 초기화)
su - username # 특정 사용자로 전환 (로그인 쉘)
su -c "command" # 명령 하나만 다른 사용자로 실행5.2 /etc/sudoers와 visudo
반드시 visudo 명령으로 편집해야 한다. 문법 오류를 검증해주기 때문에 직접 편집 시 문법 오류가 나면 sudo를 사용할 수 없게 되는 사태를 방지한다.
sudo visudo # /etc/sudoers 편집
sudo visudo -f /etc/sudoers.d/custom # 추가 파일 편집sudoers 문법:
# 기본 형식
# 사용자 호스트=(실행할사용자:실행할그룹) 명령
root ALL=(ALL:ALL) ALL
phh ALL=(ALL:ALL) ALL
# 그룹 지정 (% 접두사)
%sudo ALL=(ALL:ALL) ALL
%admin ALL=(ALL:ALL) ALL
# 비밀번호 없이 sudo 허용 (NOPASSWD)
phh ALL=(ALL) NOPASSWD: ALL
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 특정 명령만 허용
developer ALL=(ALL) /usr/bin/docker, /usr/bin/docker-compose
operator ALL=(ALL) /usr/bin/systemctl restart *, /usr/bin/journalctl
# 별칭 사용
Cmnd_Alias WEB = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
User_Alias WEBADMINS = user1, user2
WEBADMINS ALL=(ALL) NOPASSWD: WEB
실무 팁: /etc/sudoers를 직접 수정하기보다 /etc/sudoers.d/ 디렉토리에 별도 파일을 만드는 것이 관리하기 좋다.
# /etc/sudoers 마지막 줄에 다음이 있어야 함:
# #includedir /etc/sudoers.d
# (# 은 주석이 아니라 include 지시자)
sudo visudo -f /etc/sudoers.d/phh6. 로그인 쉘 vs 비로그인 쉘
쉘이 시작될 때 읽는 설정 파일이 달라지므로, 환경변수 설정 위치를 결정할 때 중요하다.
로그인 쉘 (Login Shell)
사용자가 시스템에 로그인할 때 실행되는 쉘. su -, ssh, 콘솔 로그인 등.
설정 파일 읽는 순서 (Bash):
/etc/profile(시스템 전역)/etc/profile.d/*.sh(시스템 전역 추가)~/.bash_profile→~/.bash_login→~/.profile(사용자별, 첫 번째 존재하는 것만)- 로그아웃 시:
~/.bash_logout
비로그인 쉘 (Non-login Shell)
이미 로그인된 상태에서 새로 여는 쉘. 터미널 에뮬레이터, bash 명령, 스크립트 실행 등.
설정 파일 읽는 순서 (Bash):
/etc/bash.bashrc(시스템 전역, 일부 배포판)~/.bashrc(사용자별)
대화형 vs 비대화형
| 쉘 종류 | 대화형(Interactive) | 비대화형(Non-interactive) |
|---|---|---|
| 로그인 | SSH 접속, su - | 드물지만 bash --login script.sh |
| 비로그인 | 터미널에서 bash 실행 | bash script.sh, cron 작업 |
# 현재 쉘이 로그인 쉘인지 확인
shopt -q login_shell && echo "Login shell" || echo "Non-login shell"
# 또는
echo $0 # 앞에 - 가 붙으면 로그인 쉘: -bash실무 권장: ~/.bash_profile에서 ~/.bashrc를 source 하도록 설정하면 양쪽 모두에서 일관된 환경을 유지할 수 있다.
# ~/.bash_profile
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi7. /etc/skel 디렉토리
useradd -m으로 사용자를 생성할 때, 새 사용자의 홈 디렉토리에 복사되는 기본 파일들이 저장된 템플릿 디렉토리.
ls -la /etc/skel/
# 일반적으로 포함:
# .bash_logout
# .bashrc
# .profile# 커스텀 템플릿 추가 예시
sudo cp /path/to/custom_vimrc /etc/skel/.vimrc
sudo mkdir /etc/skel/.ssh
sudo chmod 700 /etc/skel/.ssh
# 이후 생성되는 모든 사용자에게 자동 적용
sudo useradd -m newuser8. PAM (Pluggable Authentication Modules)
리눅스의 인증 체계를 모듈화한 프레임워크. 로그인, sudo, ssh 등 다양한 서비스의 인증 방식을 유연하게 구성할 수 있다.
핵심 개념
PAM은 4가지 **관리 그룹(management group)**으로 구성된다:
| 그룹 | 설명 |
|---|---|
auth | 사용자 인증 (비밀번호 확인, 2FA 등) |
account | 계정 유효성 검사 (만료, 접근 시간 제한 등) |
password | 비밀번호 변경 처리 |
session | 세션 전후 작업 (로그 기록, 홈 디렉토리 마운트 등) |
설정 파일 위치
ls /etc/pam.d/ # 서비스별 PAM 설정 파일
# common-auth, common-account, common-password, common-session
# sshd, sudo, login, su 등PAM 설정 파일 형식
# type control module-path [module-arguments]
auth required pam_unix.so nullok
auth required pam_nologin.so
account required pam_unix.so
password required pam_unix.so sha512 shadow
session required pam_unix.so
control 값:
required- 실패해도 나머지 모듈 계속 실행, 최종 실패 반환requisite- 실패 시 즉시 중단sufficient- 성공 시 이후 모듈 건너뜀 (이전 required가 실패하지 않았다면 성공)optional- 결과가 다른 모듈에 의해 결정될 때만 고려
주요 PAM 모듈
| 모듈 | 역할 |
|---|---|
pam_unix.so | 전통적 Unix 비밀번호 인증 (/etc/shadow) |
pam_nologin.so | /etc/nologin 파일 존재 시 root 외 로그인 차단 |
pam_limits.so | 리소스 제한 적용 (/etc/security/limits.conf) |
pam_pwquality.so | 비밀번호 강도 정책 |
pam_tally2.so / pam_faillock.so | 로그인 실패 횟수 제한 (무차별 대입 방지) |
pam_google_authenticator.so | Google OTP 2FA |
실전 예시: 비밀번호 정책 강화
# /etc/pam.d/common-password (또는 /etc/security/pwquality.conf)
password requisite pam_pwquality.so retry=3 minlen=12 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
# minlen=12: 최소 12자
# ucredit=-1: 대문자 최소 1개
# lcredit=-1: 소문자 최소 1개
# dcredit=-1: 숫자 최소 1개
# ocredit=-1: 특수문자 최소 1개9. root 계정과 UID 0
root의 특수성
- UID 0은 커널이 인식하는 슈퍼유저. 사용자명이
root가 아니어도 UID가 0이면 root 권한을 가진다. - 모든 파일 접근 권한 무시 (DAC: Discretionary Access Control 우회)
- 모든 시스템 호출 가능
kill -9로 모든 프로세스 종료 가능
root 계정 보안 모범 사례
# 1. root 직접 로그인 비활성화 (SSH)
# /etc/ssh/sshd_config
PermitRootLogin no
# 2. root 계정 잠금 (비밀번호 로그인 불가)
sudo passwd -l root
# 3. root 쉘을 nologin으로 변경 (극단적)
# sudo usermod -s /usr/sbin/nologin root # 주의: 복구 모드에서도 접근 불가
# 4. sudo 사용 권장 - 모든 명령이 로깅됨
sudo command
# 5. su 제한: wheel 그룹만 su 사용 가능하게 설정
# /etc/pam.d/su
# auth required pam_wheel.soUID 체계 정리
| UID 범위 | 용도 |
|---|---|
0 | root (슈퍼유저) |
1-999 | 시스템 계정 (데몬, 서비스용) |
1000-60000 | 일반 사용자 (배포판마다 다름) |
65534 | nobody (권한 없는 사용자) |