infra
Platform

모듈 맵

[Infra Ops] Linux 사용자/그룹/권한 체계와 서비스 계정 관리

0 / 52 완료

펼치기
0 / 52 완료0%

Infra-ops · 06 / 52

[Infra Ops] Linux 사용자/그룹/권한 체계와 서비스 계정 관리

useradd/groupadd, chmod/chown, sudo 설정, 서비스 전용 계정 생성까지 — 인프라 엔지니어가 매일 쓰는 권한 관리 실무

🚨INCIDENT ALERT
HIGH

신입 엔지니어 재현 씨가 온보딩 첫 주에 Tomcat을 root 계정으로 실행했습니다. 서비스는 잘 돌아갔고 아무도 몰랐습니다. 두 달 뒤, 보안 감사팀이 서버 접근 로그를 분석하다가 발견합니다. "이 WAS, root로 실행 중이네요. 즉시 수정 요청합니다." 긴급 조치 티켓이 열리고 서비스 재배포와 권한 재설정 작업이 주말을 날렸습니다.

root로 실행된 서비스가 공격당하면 서버 전체가 뚫립니다. 계정과 권한 설계는 선택이 아닙니다.

이번 챕터에서 배울 것
  • 1useradd/usermod/userdel로 사용자를 생성·수정·삭제할 수 있다
  • 2chmod 숫자 표기로 파일 권한을 읽고 설정할 수 있다
  • 3visudo로 특정 명령어만 sudo를 허용하는 제한 설정을 할 수 있다
  • 4서비스 전용 계정을 생성하고 디렉터리 소유권을 올바르게 설정할 수 있다
  • 5/etc/passwd와 /etc/shadow의 구조를 읽고 해석할 수 있다
실습 환경 준비
현재 사용자 및 그룹 확인
id && groups
useradd, groupadd 경로 확인
which useradd groupadd usermod userdel
sudo 설치 확인
which sudo && sudo -V | head -1

사용자와 그룹 관리

💡개념

사용자 계정의 구조 — /etc/passwd와 /etc/shadow

보안 감사에서 "서비스 계정으로 SSH 로그인이 가능한 상태입니다"라는 지적을 받았습니다. /etc/passwd를 보니 Tomcat 계정의 쉘이 /bin/bash로 설정되어 있었고, 비밀번호도 설정된 상태였습니다. 공격자가 이 계정을 탈취하면 서버에 접속해 쉘을 열 수 있습니다. 계정이 어떻게 저장되는지 이해해야 서비스 계정을 올바르게 설정하고 감사 지적을 받지 않을 수 있습니다.

Linux는 모든 사용자를 /etc/passwd에 기록하고, 실제 패스워드 해시는 루트만 읽을 수 있는 /etc/shadow에 분리 저장합니다. 이 분리 덕분에 일반 사용자가 암호화된 패스워드를 볼 수 없어 무차별 대입 공격을 막습니다.

로컬 터미널
cat /etc/passwd | tail -3
OUTPUT
# 형식: 사용자명:x:UID:GID:주석(GECOS):홈디렉터리:로그인쉘
nginx:x:997:995:Nginx Web Server:/var/cache/nginx:/sbin/nologin
appuser:x:1001:1001::/opt/app:/sbin/nologin
로컬 터미널
sudo cat /etc/shadow | grep appuser
OUTPUT
# '!' = 패스워드 로그인 비활성화 (서비스 계정의 정상 상태)
appuser:!:19800:0:99999:7:::

UID 범위 의미:

범위의미
0root — 모든 권한
1 ~ 999시스템 계정 (서비스용)
1000+일반 사용자 (로그인 계정)
로컬 터미널
# useradd — 일반 vs 서비스 계정
sudo useradd -m -s /bin/bash devuser          # 일반 사용자
sudo useradd -r -s /sbin/nologin -d /opt/app -m appuser  # 서비스 계정
# -r: 시스템 계정(UID < 1000), -s: 쉘 지정, -d: 홈 경로, -m: 홈 생성

# usermod — 계정 수정
sudo usermod -aG appgroup appuser   # 그룹 추가 (-a 없으면 기존 그룹 제거됨)
sudo usermod -L devuser             # 계정 잠금
sudo usermod -U devuser             # 잠금 해제

# groupadd / gpasswd
sudo groupadd appgroup
sudo gpasswd -a appuser appgroup    # 그룹에 사용자 추가
sudo gpasswd -d appuser appgroup    # 그룹에서 제거

# 확인
id appuser
# uid=1001(appuser) gid=1001(appuser) groups=1001(appuser),1002(appgroup)

파일 권한 체계

💡개념

rwx 권한 구조와 chmod

파일 권한은 서비스의 보안과 안정성을 동시에 결정합니다. 설정 파일에 실행 권한이 없으면 배포 자동화가 멈추고, DB 비밀번호가 든 파일에 644를 걸어두면 서버에 접근한 누구나 그 내용을 읽을 수 있습니다. 숫자 세 자리의 의미를 체계적으로 이해해야 의도한 대로 접근을 제어하고, 보안 감사에서 지적받지 않을 수 있습니다.

Linux 파일 권한 체계 — rwx 구조와 숫자 표기

배포한 설정 파일에 DB 비밀번호가 들어있었는데 권한이 644로 열려있어서, 서버에 접근 가능한 모든 계정이 그 파일을 읽을 수 있었습니다. 보안 감사 항목 중 가장 흔하게 적발되는 것이 이 권한 설정 오류입니다. 반대로 실행 스크립트에 실행 권한을 빠뜨려 배포 자동화가 멈추는 경우도 마찬가지입니다. 숫자 세 자리의 의미를 정확히 이해해야 의도대로 접근을 제어할 수 있습니다.

모든 파일·디렉터리에는 소유자(owner) / 그룹(group) / 기타(others) 세 계층으로 읽기(r=4) · 쓰기(w=2) · 실행(x=1) 권한이 독립적으로 설정됩니다.

로컬 터미널
ls -la /opt/app/
OUTPUT
# 형식: 권한(10자) 링크수 소유자 그룹 크기 날짜 이름
drwxr-x---  3 appuser appgroup 4096 Jan 15 09:00 .
-rwxr-xr-x  1 appuser appgroup 8192 Jan 15 09:00 start.sh   # 755
-rw-r--r--  1 appuser appgroup  512 Jan 15 09:00 app.conf    # 644
-rw-------  1 appuser appgroup  128 Jan 15 09:00 secret.key  # 600

자주 쓰는 권한 조합:

숫자권한용도
755rwxr-xr-x실행 스크립트, 디렉터리
644rw-r--r--설정 파일, HTML
600rw-------개인 키, 비밀 파일
750rwxr-x---서비스 디렉터리 (others 차단)
로컬 터미널
# 숫자 표기 (권장)
chmod 755 start.sh
chmod 644 app.conf
chmod 600 secret.key
chmod 750 /opt/app/

# 문자 표기 (부분 변경 시 유용)
chmod +x deploy.sh          # 실행 권한 추가
chmod o-rwx secret.key      # others 권한 전체 제거

# 소유자·그룹 변경
sudo chown appuser:appgroup /opt/app/log.txt
sudo chown -R appuser:appgroup /opt/app/   # 재귀

특수 권한 (보안 감사 필수 확인 항목):

SUID(s)가 root 소유 실행 파일에 설정되면 일반 사용자도 root 권한으로 실행됩니다. /tmp의 Sticky Bit(t)는 자신이 만든 파일만 삭제 가능하게 합니다.

로컬 터미널
# 서버 내 SUID 파일 전체 목록 (의심 파일 확인)
sudo find / -perm -4000 -type f 2>/dev/null
# passwd, sudo, ping 등 정상 파일 외 항목은 즉시 조사
파일 권한 설정 및 검증 실습
🔍실행 후 확인할 것
  • deploy.sh(700): -rwx------ 소유자만 실행 가능, 다른 사람은 읽지도 못함
  • secret.key(600): -rw------- 소유자만 읽기/쓰기 — DB 패스워드, SSL 개인키 표준 권한
  • config.yml(640): -rw-r----- 소유자 읽기/쓰기, 그룹 읽기만 — 설정 파일 표준
  • app.jar(644): -rw-r--r-- 소유자 읽기/쓰기, 나머지 읽기만 — 일반 배포 파일 표준

sudo 설정

💡개념

/etc/sudoers — 최소 권한으로 sudo 제한

배포 계정에 NOPASSWD: ALL을 설정해뒀다가 보안 감사에서 "root 권한과 동일한 계정"으로 지적을 받았습니다. 해커가 이 계정 하나를 탈취하면 서버 전체를 장악할 수 있습니다. 반대로 권한을 너무 좁게 설정하면 배포 스크립트가 중간에 실패합니다. 어떤 명령어에만 sudo를 허용할지 정밀하게 지정하는 것이 보안과 운영 자동화를 동시에 잡는 방법입니다.

sudo는 일반 계정이 특정 명령어를 root 권한으로 실행하게 합니다. ALL=(ALL) ALL은 사실상 root와 동일합니다. 실무에서는 필요한 명령어만 허용하는 최소 권한(least privilege) 원칙을 적용합니다.

/etc/sudoers반드시 visudo로만 편집합니다. visudo는 저장 전 문법을 검사해 오류로 인한 sudo 잠금을 방지합니다.

로컬 터미널
# 전용 파일로 관리 (권장 — 메인 파일 직접 수정하지 않음)
sudo visudo -f /etc/sudoers.d/appuser
로컬 터미널
# /etc/sudoers.d/appuser 내용 예시
# 형식: 사용자 호스트=(실행계정) [NOPASSWD:] 명령어

# 전체 허용 (위험 — 피할 것)
appuser ALL=(ALL) ALL

# 특정 명령어만, 패스워드 없이 (서비스 재시작용 — 실무 표준)
appuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart tomcat

# 여러 명령어
appuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart tomcat, /usr/bin/systemctl status tomcat

# 그룹 단위 설정
%appgroup ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart tomcat
서버 터미널
# sudo 로그 확인 (누가 언제 어떤 명령어를 실행했는지)
sudo journalctl _COMM=sudo --since "today" | grep appuser
OUTPUT
Jan 15 14:23:01 server01 sudo: appuser : TTY=pts/0 ; PWD=/home/appuser ; USER=root ; COMMAND=/usr/bin/systemctl restart tomcat

최소 권한 원칙 — sudoers 패턴과 서비스 계정 보안

서비스 계정 관리 — 실무 핵심

💡개념

왜 서비스를 root로 실행하면 안 되는가

root로 실행된 서비스는 프로세스가 탈취됐을 때 시스템 전체를 잃습니다. Tomcat에 원격 코드 실행 취약점이 있다면, 공격자는 Tomcat 프로세스 권한으로 명령어를 실행합니다. Tomcat이 root라면 백도어 계정 생성, 모든 파일 열람이 즉시 가능합니다. 서비스 전용 계정은 서비스가 동작하는 데 필요한 최소한의 권한만 가집니다.

로컬 터미널
# 위험한 상태 vs 안전한 상태
ps aux | grep -E 'tomcat|java' | grep -v grep
OUTPUT
# 위험: root가 WAS를 실행 중
root      1234  2.5  8.3 3145728 340000 ? Sl 09:00 java -jar /opt/app/app.jar

# 안전: 서비스 계정으로 격리됨
appuser   1234  2.5  8.3 3145728 340000 ? Sl 09:00 java -jar /opt/app/app.jar

서비스 계정 설계 원칙:

원칙내용
로그인 쉘 차단/sbin/nologin — 쉘 접속 불가
전용 홈 디렉터리서비스 루트 디렉터리를 홈으로 설정
패스워드 비활성화/etc/shadow!
최소 파일 소유서비스 디렉터리만 소유
서비스 계정 생성 및 디렉터리 권한 설정
🔍실행 후 확인할 것
  • id appuser 결과에 appgroup이 포함되는지 확인
  • ls -la /opt/app 소유자가 appuser:appgroup으로 표시되는지 확인
  • /opt/app 권한이 drwxr-x--- (750)인지 확인
  • sudo -u appuser 로 /opt/app 내 파일 생성이 성공하는지 확인
  • cat /etc/passwd | grep appuser 마지막 필드가 /sbin/nologin인지 확인
💼
실무 맥락
현업 패턴

실제 업무에서 이 지식이 쓰이는 상황:

현업 인프라 팀에서는 서비스마다 전용 계정을 두는 것이 표준입니다. Nginx는 nginx 계정, Tomcat은 tomcat 계정, PostgreSQL은 postgres 계정으로 실행합니다. 이 분리가 안 된 서버는 보안 감사를 통과하지 못합니다.

서버 초기화 스크립트 패턴 (실제 현장에서 쓰는 방식):

로컬 터미널
APP_USER="appuser"
APP_GROUP="appgroup"
APP_HOME="/opt/app"

if ! id "$APP_USER" &>/dev/null; then
    sudo groupadd "$APP_GROUP"
    sudo useradd -r -s /sbin/nologin -d "$APP_HOME" -g "$APP_GROUP" -m "$APP_USER"
fi

sudo chown -R "$APP_USER:$APP_GROUP" "$APP_HOME"
sudo chmod 750 "$APP_HOME"
sudo chmod 640 "$APP_HOME"/config/*.conf
sudo chmod 770 "$APP_HOME"/logs/

보안 사고 사례: 2021년 Log4Shell(CVE-2021-44228) 취약점이 발견됐을 때, root로 실행 중이던 WAS는 즉각 서버 전체 장악으로 이어졌습니다. 서비스 계정으로 격리된 서버는 피해가 /opt/app 내로 제한됐습니다. 계정 분리 하나가 사고의 반경을 결정합니다.

다음 모듈에서는 SSH 키 기반 인증과 서버 접근 제어 설정을 다룹니다.

지식 확인

퀴즈 — 4문제

Q1

chmod 755와 chmod 644의 차이로 올바른 것은?

Q2

서비스 계정 생성 시 로그인 쉘을 /sbin/nologin으로 설정하는 이유는?

Q3

visudo로 appuser가 systemctl restart tomcat 명령어만 sudo 실행할 수 있게 설정하는 올바른 방법은?

Q4

/etc/passwd의 각 필드가 올바르게 설명된 것은? (예: appuser:x:1001:1001::/opt/app:/sbin/nologin)

0 / 4 답변

🧪 실습으로 확인하기

Nginx 설치 및 기동

초급

Linux 서버에 Nginx를 설치하고 systemd 서비스로 등록하여 80포트에서 응답하는 상태까지 만든다.

30📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

infra-ops중급 · 60
[Infra Ops] OS 보안 패치와 미들웨어 버전 업 절차
인프라 서비스 운영 트랙 계속
linux입문 · 30
[Linux] 개발자가 왜 리눅스 서버와 커맨드라인을 반드시 배워야 하는가
Linux 트랙 시작점