본문으로 건너뛰기

안동민 개발노트

본문 시작

리눅스 권한 체계

Linux의 사용자·그룹·기타 권한 판정과 chmod·chown·umask를 익히고 특수 권한과 sudo를 안전하게 사용합니다.

Linux는 모든 것이 파일입니다.

일반 파일, 디렉토리, 장치, 소켓까지 파일로 표현됩니다.

따라서 파일 권한 체계가 곧 시스템 보호의 기초입니다.

이 권한 체계는 40년 넘게 Unix의 핵심으로 동작해 왔습니다.

권한 판정 3계층

리눅스 권한은 사용자 범주를 먼저 고르고, 그 범주에 부여된 읽기·쓰기·실행 비트를 해석한다.

  1. 범주
    u / g / o

    범주 소유자, 소유 그룹, 기타 사용자 중 하나의 규칙만 최종 적용된다.

  2. 비트
    4 + 2 + 1

    비트 읽기 4, 쓰기 2, 실행 1을 더해 chmod 숫자 권한을 만든다.

  3. 디렉터리
    x는 진입 권한

    디렉터리 디렉터리에서 실행 비트는 파일 실행이 아니라 내부 접근 가능성을 뜻한다.

  4. 기본값
    umask가 뺀다

    기본값 새 파일과 디렉터리가 만들어질 때 기본 권한에서 일부 비트를 제거한다.


사용자, 그룹, 기타

Linux 파일 권한은 세 범주로 나뉩니다.

  • 소유자(Owner, u): 파일을 만든 사용자
  • 그룹(Group, g): 소유자가 속한 그룹의 멤버들
  • 기타(Others, o): 나머지 모든 사용자

각 범주에 세 가지 권한이 있습니다.

권한비트파일에 대한 효과디렉토리에 대한 효과
읽기(r)4파일 내용 읽기디렉토리 목록 보기(ls)
쓰기(w)2파일 내용 수정파일 생성·삭제·이름 변경
실행(x)1프로그램으로 실행디렉토리에 진입(cd)

디렉토리의 권한은 파일과 의미가 다릅니다.

디렉토리에 읽기 권한만 있으면 파일 목록은 볼 수 있지만, 파일의 내용이나 상세 정보(크기, 시각)는 볼 수 없습니다(inode 접근에 x가 필요).

실행 권한이 없으면 cd로 디렉토리에 진입할 수 없습니다.

즉 디렉토리에 rx가 함께 있어야 실질적으로 내용을 볼 수 있습니다.

권한_읽기.sh
ls -la
# -rw-r--r-- 1 user group 1024 Jan 15 10:30 report.txt
# │├──┤├──┤├──┤
# │  u    g    o
# └ 파일 유형 (- = 일반, d = 디렉토리, l = 심볼릭 링크)

# drwxr-x--- 디렉토리: 소유자 rwx, 그룹 rx, 기타 접근불가

rw-r--r--은 소유자가 읽기+쓰기, 그룹과 기타는 읽기만 가능하다는 뜻입니다.

숫자(8진수)로 표현하면 644입니다 (6=4+2, 4=4, 4=4).

권한 확인 순서

프로세스가 파일에 접근할 때, 커널은 다음 순서로 권한을 확인합니다.

  1. 프로세스의 EUID(유효 사용자 ID)가 파일 소유자와 같으면 → 소유자 권한 적용
  2. 프로세스의 EGID가 파일 그룹과 같으면 → 그룹 권한 적용
  3. 둘 다 아니면 → 기타 권한 적용

중요: 소유자가 그룹에도 속하지만, 소유자 권한이 먼저 평가됩니다.

소유자 권한이 rw-이고 그룹 권한이 rwx인 경우, 소유자는 실행 불가입니다.

유닉스 권한 선택 순서

소유자가 그룹에도 속해 있어도 owner 권한이 먼저 적용됩니다. 그래서 `rw-` 소유자는 그룹에 `rwx`가 있어도 실행할 수 없습니다.

  1. 프로세스 유효 사용자 확인

    EUID 프로세스 유효 사용자 확인 파일 소유자와 같으면 owner 권한만 봅니다.

  2. 소유자가 아니면 그룹 확인

    EGID 소유자가 아니면 그룹 확인 파일 그룹과 맞으면 group 권한으로 판정합니다.

  3. 둘 다 아니면 기타 권한

    Others 둘 다 아니면 기타 권한 나머지 사용자에게 허용된 권한만 적용됩니다.

  4. 선택된 범주의 비트만 사용

    Result 선택된 범주의 비트만 사용 다른 범주에 더 큰 권한이 있어도 보태지지 않습니다.

  5. 644 일반 파일

    소유자 읽기/쓰기, 그룹과 기타 읽기 전용입니다.

  6. 755 실행 파일 또는 디렉토리

    소유자는 관리하고 다른 사용자는 읽고 실행할 수 있습니다.

  7. 600 비밀 파일

    소유자만 읽고 쓸 수 있어 키 파일에 자주 씁니다.


chmod, chown, umask

chmod_examples.sh
# 숫자 방식 (8진수)
chmod 755 script.sh    # rwxr-xr-x
chmod 600 secret.key   # rw-------
chmod 644 readme.txt   # rw-r--r--

# 기호 방식
chmod u+x script.sh    # 소유자에 실행 권한 추가
chmod go-w secret.txt  # 그룹과 기타에서 쓰기 권한 제거
chmod a+r public.txt   # 모두(all)에게 읽기 권한 추가
chmod o= private.txt   # 기타의 모든 권한 제거

# 재귀적 변경
chmod -R 755 /var/www/html
permission_demo.c
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

int main() {
    /* 파일 생성 후 권한 변경 */
    FILE *fp = fopen("test.txt", "w");
    fprintf(fp, "sensitive data\n");
    fclose(fp);

    /* 소유자만 읽기/쓰기 가능하게 변경 */
    chmod("test.txt", S_IRUSR | S_IWUSR);  /* 0600 */

    /* 권한 확인 */
    if (access("test.txt", R_OK) == 0)
        printf("읽기 가능\n");
    if (access("test.txt", X_OK) != 0)
        printf("실행 불가 (errno=%d)\n", errno);

    return 0;
}
chown_examples.sh
# 소유자와 그룹 변경 (root만 가능)
chown user:group file.txt
chown -R www-data:www-data /var/www    # 재귀적 변경

# 그룹만 변경
chgrp developers project/

umask

umask는 새로 생성되는 파일의 기본 권한에서 제거할 권한을 지정합니다.

파일의 기본 권한은 666, 디렉토리는 777입니다.

umask파일 결과디렉토리 결과의미
022644 (rw-r--r--)755 (rwxr-xr-x)기본 (기타 쓰기 방지)
027640 (rw-r-----)750 (rwxr-x---)기타 접근 완전 차단
077600 (rw-------)700 (rwx------)소유자만 접근
umask_demo.sh
umask              # 현재 umask 확인 (보통 0022)
umask 027          # 설정: 기타 사용자의 모든 권한 제거
touch new_file.txt # 640으로 생성됨
mkdir new_dir      # 750으로 생성됨

SetUID, SetGID, Sticky Bit

일반 권한 외에 세 가지 특수 권한이 있습니다.

SetUID (4000)

이 비트가 설정된 실행 파일은 실행 시 파일 소유자의 권한으로 실행됩니다.

passwd 명령이 대표적입니다.

일반 사용자가 passwd를 실행하면 root 권한으로 /etc/shadow를 수정할 수 있습니다.

setuid_audit.sh
# SetUID가 설정된 파일 찾기
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root 59640 ... /usr/bin/passwd
#    ^ s = SetUID + 실행 권한

# 시스템에서 SetUID 파일 전체 검색 (보안 감사)
find / -perm -4000 -type f 2>/dev/null
# /usr/bin/passwd
# /usr/bin/sudo
# /usr/bin/su
# /usr/bin/newgrp

SetUID는 편리하지만 보안 위험이 큽니다.

SetUID root 프로그램에 취약점이 있으면 root 권한 탈취로 이어집니다.

불필요한 SetUID는 제거해야 합니다.

SetGID (2000)

파일에 설정하면 실행 시 파일 그룹의 권한으로 실행됩니다.

디렉토리에 설정하면 더 유용합니다 — 그 안에 생성되는 모든 파일과 디렉토리가 부모 디렉토리의 그룹을 상속합니다.

setgid_directory.sh
# 팀 공유 디렉토리 설정
mkdir /shared/project
chgrp developers /shared/project
chmod 2775 /shared/project   # SetGID + rwxrwxr-x

# 이제 누가 파일을 만들든 그룹은 developers
touch /shared/project/test.txt
ls -la /shared/project/test.txt
# -rw-rw-r-- 1 alice developers ... test.txt

Sticky Bit (1000)

디렉토리에 설정하면, 해당 디렉토리의 파일은 파일 소유자와 디렉토리 소유자만 삭제할 수 있습니다.

/tmp에 설정되어 있어 다른 사용자의 임시 파일을 삭제하지 못하게 합니다.

sticky_bit.sh
ls -ld /tmp
# drwxrwxrwt 18 root root 4096 ... /tmp
#          ^ t = Sticky Bit + 실행 권한

# Sticky Bit 없으면: /tmp에 쓰기 권한이 있는 모든 사용자가
# 다른 사용자의 파일도 삭제 가능 (매우 위험!)
SetUID SetGID Sticky Bit

일반 rwx 권한 위에 4000, 2000, 1000 비트를 더하면 프로그램 실행과 공유 디렉토리 동작이 달라진다.

  1. SetUID

    4000 / rws `passwd`처럼 실행 순간 EUID가 파일 소유자 권한으로 바뀐다. 위험 지점 SetUID root 바이너리의 입력 검증 취약점은 root 권한 탈취로 이어진다.

  2. SetGID

    2000 / rws 실행 파일은 그룹 권한으로, 디렉토리는 새 파일의 그룹 상속으로 동작한다. 팀 디렉토리 `chmod 2775 /shared/project`는 developers 그룹 협업에 자주 쓰인다.

  3. Sticky Bit

    1000 / rwt `/tmp`처럼 누구나 쓸 수 있어도 남의 파일 삭제는 막는다. 삭제 조건 파일 소유자, 디렉토리 소유자, root만 해당 파일을 제거할 수 있다.

  4. 파일 유형

    `-`, `d`, `l` 다음 9칸에서 u/g/o 권한을 읽는다.

  5. 특수 문자

    `s`와 `t`는 실행 비트 자리에 표시되며 대문자는 실행 권한이 없다는 뜻이다.

  6. 8진수 합산

    `4755`는 SetUID 4000과 일반 권한 755가 함께 설정된 값이다.

  7. 감사 대상

    `find / -perm -4000 -type f`로 불필요한 SetUID 파일을 점검한다.


sudo와 root 권한 관리

root(UID 0)는 모든 권한 검사를 우회합니다.

root로 직접 로그인하는 것은 위험합니다.

실수 하나(rm -rf / 오타)로 시스템 전체가 망가질 수 있습니다.

sudo는 일반 사용자가 특정 명령만 root 권한으로 실행할 수 있게 합니다.

/etc/sudoers 파일에 정책을 정의합니다.

sudoers_examples.sh
# /etc/sudoers (visudo로만 편집!)

# 사용자 alice는 모든 명령을 root로 실행 가능
alice ALL=(ALL:ALL) ALL

# 사용자 deploy는 systemctl만 root로 실행 가능
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, \
                            /usr/bin/systemctl restart app

# dev 그룹은 docker 명령만 실행 가능
%dev ALL=(root) /usr/bin/docker
sudo_usage.sh
sudo apt update              # root 권한으로 패키지 업데이트
sudo -u postgres psql        # postgres 사용자로 psql 실행
sudo -l                      # 내가 실행할 수 있는 명령 목록

# sudo 로그 확인 (감사 추적)
grep sudo /var/log/auth.log

보안 모범 사례

  • root 직접 로그인 비활성화 (/etc/ssh/sshd_config에서 PermitRootLogin no)
  • sudo를 통해 최소한의 명령만 허용
  • SSH 키 기반 인증 사용 (패스워드 비활성화)
  • 2FA(Two-Factor Authentication) 적용
  • 정기적으로 SetUID 파일 감사
root 권한 축소 기준

파일 권한이 맞아도 특수 비트와 sudoers 정책이 넓으면 일반 사용자의 실행 경로가 곧 특권 경로가 된다.

  1. SetUID 파일

    소유자 권한으로 실행되므로 root 소유 실행 파일은 취약점 하나로 전체 권한 상승이 될 수 있다.

  2. sudo 명령 목록

    사용자가 실행할 수 있는 명령을 서비스 재시작, 로그 조회처럼 필요한 작업 단위로 좁힌다.

  3. root 로그인

    직접 로그인은 추적과 통제를 어렵게 하므로 개인 계정에서 sudo로 상승하는 흐름을 남긴다.


프로세스 권한의 실제

프로세스에는 여러 ID가 있습니다.

ID이름용도
RUID실제 사용자 ID프로세스를 시작한 사용자
EUID유효 사용자 ID접근 제어 시 사용되는 ID
SUID저장된 사용자 IDSetUID 실행 시 원래 EUID 저장

일반적으로 RUID = EUID입니다.

SetUID 파일을 실행하면 EUID가 파일 소유자 ID로 바뀝니다.

프로그램은 seteuid()로 SUID에 저장된 원래 권한으로 돌아갈 수 있습니다.

커널 권한 판단

파일 권한은 소유자, 그룹, 기타 중 하나만 선택해 적용되며, 세트 사용자 식별자와 관리자 위임은 별도의 위험 지점이 된다.

  1. 첫 판정
    유효 사용자 식별자 확인

    첫 판정 프로세스의 유효 사용자 식별자가 파일 소유자와 같으면 소유자 권한만 적용한다.

  2. 다음 판정
    유효 그룹 식별자 확인

    다음 판정 소유자가 아니고 그룹이 맞으면 그룹 권한을 적용한다. 소유자 권한과 합치지 않는다.

  3. 마지막 판정
    기타 권한 적용

    마지막 판정 소유자와 그룹 어느 쪽도 아니면 나머지 사용자 권한으로 읽기, 쓰기, 실행을 결정한다.

  4. 디렉터리 권한 해석

    읽기 목록 이름을 볼 수 있지만, 실행 권한이 없으면 항목 세부 정보 접근이 막힌다. 쓰기 디렉터리 안에서 파일 생성, 삭제, 이름 변경을 허용한다. 실행 경로 탐색과 디렉터리 진입을 허용하므로 실제 접근에는 읽기와 함께 필요한 경우가 많다.

  5. 특수 권한의 판단 포인트

    세트 사용자 실행 중 유효 사용자 식별자가 파일 소유자로 바뀌므로 루트 파일은 특히 감사해야 한다. 세트 그룹 공유 디렉터리에서는 새 파일이 부모 디렉터리의 그룹을 상속하게 만든다. 고정 비트 공용 임시 디렉터리에서 파일 소유자와 디렉터리 소유자만 삭제할 수 있게 한다.

euid_demo.c
#include <stdio.h>
#include <unistd.h>

int main() {
    printf("Real UID:      %d\n", getuid());
    printf("Effective UID: %d\n", geteuid());

    /* SetUID root 프로그램에서:
     * getuid() = 1000 (일반 사용자)
     * geteuid() = 0 (root) */

    /* 특권 작업 완료 후 권한 내려놓기 (보안!) */
    /* seteuid(getuid()); */

    return 0;
}

다음 절에서는 OS를 위협하는 보안 공격과 방어 기법을 살펴보겠습니다.

Unix 권한 판정 흐름

Unix 권한은 사용자 id, 그룹 id, mode bit를 순서대로 대조합니다. ACL이나 capabilities가 붙으면 단순 rwx 표보다 판정 경로가 길어집니다.

  1. 02

    gid / groups

  2. 03

    rwx mode

  3. 04

    ACL / cap

  4. uid 파일 owner

    프로세스 effective uid가 같으면 user bit를 먼저 적용한다.

  5. gid / groups owner

    아니면 primary/secondary group이 파일 group과 맞는지 본다.

  6. rwx mode 디렉터리 execute

    진입 권한이고, write는 항목 생성·삭제 권한이다.

  7. ACL / cap 세밀한 예외

    ACL, 루트 권한 일부 위임은 capabilities로 표현한다.