파일 · 권한 · 사용자 관리 07 / 50 · Part 1. Linux 파일 관리 기초
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 11. Linux 파일과 디렉터리 관리

1. 들어가며

mkdir은 디렉터리를 만든다. 여기까지는 누구나 안다. 그런데 새 디렉터리의 권한은 누가 정하는가? 라는 질문에는 답이 바로 나오지 않는다.

이번 글에서는 같은 mkdir normal 명령이 Rocky Linux 9.8에서는 755, Ubuntu 24.04에서는 775를 만드는 실제 결과를 보여 주고, 그 차이가 umask 에서 나온다는 것을 설명한다. umask 자체는 25편에서 깊게 다루고, 이번 글은 mkdir이 권한을 결정하는 흐름에 집중한다.


2. 핵심 개념

2-1. mkdir 주요 옵션

옵션의미사용 예
(없음)디렉터리 1개 생성, 상위가 없으면 실패mkdir logs
-p필요한 상위 디렉터리까지 생성, 이미 있어도 오류 없음mkdir -p a/b/c
-v생성한 디렉터리마다 메시지 출력mkdir -pv a/b/c
-m MODE권한을 직접 지정 (umask 무시)mkdir -m 700 private

2-2. 새 디렉터리 권한의 결정 공식

최종 권한 = 요청 모드(mkdir 은 0777) AND NOT umask
  • umask 0022 → 0777 - 0022 = 0755
  • umask 0002 → 0775
  • umask 0077 → 0700

(엄밀히는 뺄셈이 아니라 비트 AND NOT 연산이다. 25편에서 차이를 설명한다.)

2-3. -m 옵션과 umask

mkdir -m 700은 umask와 관계없이 지정한 권한을 만든다. GNU mkdir은 -m이 주어지면 umask 적용 결과가 아니라 지정한 모드가 최종 권한이 되도록 처리한다. 단, -p로 함께 만들어지는 상위 디렉터리 에는 -m이 적용되지 않고 umask 기준 권한이 적용된다.


3. 동작 원리

mkdir 이 만드는 권한 = 요청 모드 & ~umask

mkdir 명령은 내부적으로 mkdir("normal", 0777) 시스템 콜을 호출한다. 커널은 이 요청 모드에서 프로세스의 umask에 해당하는 비트를 지운 값 으로 inode를 만든다. 그리고 새 디렉터리의 소유자는 요청한 프로세스의 UID, 그룹은 기본적으로 프로세스의 GID 가 된다 (상위 디렉터리에 SGID가 있으면 예외, 29편).

동시에 커널은 다음 작업을 함께 수행한다.

  1. 새 디렉터리 안에 .(자기 자신)과 ..(상위) 엔트리 생성
  2. 상위 디렉터리에 새 이름 엔트리 추가 → 상위 디렉터리의 w·x 권한 필요
  3. 상위 디렉터리의 링크 수 +1 (새 디렉터리의 ..이 상위를 가리키므로)
  4. 상위 디렉터리의 mtime·ctime 갱신

Rocky와 Ubuntu의 umask 차이는 다음에서 나온다.

배포판umask근거
Rocky 9.80022/etc/pam.d/postlogin의 pam_umask → /etc/login.defs의 UMASK 022 적용
Ubuntu 24.040002/etc/pam.d/common-session의 pam_umask + USERGROUPS_ENAB yes — 사용자 이름과 기본 그룹 이름이 같으면 그룹 비트를 소유자와 같게 맞춰 022 → 002

이 값은 이번 실습 컨테이너에서 su - 로그인 세션으로 확인한 결과다. 서버의 /etc/profile, /etc/bashrc, ~/.bashrc 설정에 따라 달라질 수 있으므로 항상 umask로 직접 확인한다.


4. 명령어 실습

Rocky와 Ubuntu에서 같은 명령 을 실행했다.

mkdir ~/lab07 && cd ~/lab07

# 1) 상위 디렉터리가 없으면 실패 / -p 로 한 번에 생성
mkdir a/b/c
mkdir -pv a/b/c

# 2) umask 와 기본 권한
umask
mkdir normal
mkdir -m 700 private
ls -ld normal private

# 3) 하위 디렉터리가 생길 때 상위 링크 수 변화
ls -ld a && mkdir a/x a/y && ls -ld a

# 4) 8진수로 확인
stat -c '%a %A %n' normal private a

5. 실행 결과

Rocky Linux 9.8

실제 실행 결과 — Rocky Linux 9.8 · analyst@rocky9-lab — mkdir 과 umask

Ubuntu 24.04.5

실제 실행 결과 — Ubuntu 24.04.5 · analyst@ubuntu-lab — mkdir 과 umask

텍스트 원본(실제 출력) — Rocky:

[analyst@rocky9-lab ~]$ mkdir ~/lab07 && cd ~/lab07
[analyst@rocky9-lab lab07]$ mkdir a/b/c
mkdir: cannot create directory ‘a/b/c’: No such file or directory
[analyst@rocky9-lab lab07]$ mkdir -pv a/b/c
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
[analyst@rocky9-lab lab07]$ umask
0022
[analyst@rocky9-lab lab07]$ mkdir normal
[analyst@rocky9-lab lab07]$ mkdir -m 700 private
[analyst@rocky9-lab lab07]$ ls -ld normal private
drwxr-xr-x 2 analyst analyst 4096 Sep 24 10:15 normal
drwx------ 2 analyst analyst 4096 Sep 24 10:15 private
[analyst@rocky9-lab lab07]$ ls -ld a && mkdir a/x a/y && ls -ld a
drwxr-xr-x 3 analyst analyst 4096 Sep 24 10:15 a
drwxr-xr-x 5 analyst analyst 4096 Sep 24 10:15 a
[analyst@rocky9-lab lab07]$ stat -c '%a %A %n' normal private a
755 drwxr-xr-x normal
700 drwx------ private
755 drwxr-xr-x a

텍스트 원본(실제 출력) — Ubuntu:

analyst@ubuntu-lab:~$ mkdir ~/lab07 && cd ~/lab07
analyst@ubuntu-lab:~/lab07$ mkdir a/b/c
mkdir: cannot create directory ‘a/b/c’: No such file or directory
analyst@ubuntu-lab:~/lab07$ mkdir -pv a/b/c
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
analyst@ubuntu-lab:~/lab07$ umask
0002
analyst@ubuntu-lab:~/lab07$ mkdir normal
analyst@ubuntu-lab:~/lab07$ mkdir -m 700 private
analyst@ubuntu-lab:~/lab07$ ls -ld normal private
drwxrwxr-x 2 analyst analyst 4096 Sep 24 10:15 normal
drwx------ 2 analyst analyst 4096 Sep 24 10:15 private
analyst@ubuntu-lab:~/lab07$ ls -ld a && mkdir a/x a/y && ls -ld a
drwxrwxr-x 3 analyst analyst 4096 Sep 24 10:15 a
drwxrwxr-x 5 analyst analyst 4096 Sep 24 10:15 a
analyst@ubuntu-lab:~/lab07$ stat -c '%a %A %n' normal private a
775 drwxrwxr-x normal
700 drwx------ private
775 drwxrwxr-x a

6. 결과 해석

출력해석
mkdir: cannot create directory 'a/b/c': No such file or directory상위 a/b가 없어서 실패. mkdir은 기본적으로 한 단계만 만든다
mkdir -pv 의 3줄 메시지a → a/b → a/b/c 순서로 생성
Rocky umask 0022 → normal = 755그룹·기타의 w 비트 제거
Ubuntu umask 0002 → normal = 775기타의 w만 제거. 그룹(= 사용자 전용 그룹 analyst)에 쓰기 허용
private = 700 (양쪽 동일)-m은 umask 영향을 받지 않는다
a 링크 수 3 → 5a/b가 있어 3, a/x, a/y 추가로 5. 2 + 하위 디렉터리 수 와 일치

Ubuntu의 775는 위험해 보이지만, 그룹이 사용자 전용 그룹(User Private Group) 이라 그룹 구성원이 사실상 본인뿐이다. 문제는 이 사용자를 다른 사용자와 같은 그룹에 넣거나, 공유 그룹이 기본 그룹으로 설정된 경우다. 이때는 775가 다른 사용자의 쓰기 허용 이 된다 (39편).


7. 보안 관점

위험설명대응
예측 가능한 임시 디렉터리스크립트가 /tmp/backup을 mkdir하기 전에 공격자가 먼저 만들어 두면, 이후 파일이 공격자 소유 디렉터리 에 저장된다mktemp -d로 임의 이름 생성
mkdir -p 오류 무시-p는 이미 존재해도 성공한다 → 기존 디렉터리의 소유자·권한을 검증하지 않음생성 후 stat으로 소유자·권한 확인
서비스 디렉터리 권한 과다업로드·캐시 디렉터리를 777로 생성서비스 계정 소유 + 750/770
umask 차이 무시같은 배포 스크립트가 Ubuntu에서 그룹 쓰기 가능한 디렉터리를 만듦스크립트에서 -m 또는 install -d -m 명시

install -d -m 750 -o app -g app /srv/app/data처럼 install 명령을 쓰면 생성·소유자·권한 지정을 한 번에 처리할 수 있어 배포 스크립트에서 자주 사용한다.


8. 보안관제 관점

관점내용
Detection디렉터리 생성은 기본 로그에 남지 않는다. auditd로 mkdir, mkdirat 시스템 콜을 감시하거나 FIM으로 특정 경로를 감시해야 한다
IOC위협 보고서에 자주 나오는 디렉터리명: /tmp/.X11-unix/.x, /var/tmp/.ICE-unix/..., /dev/shm/.cache 처럼 정상 이름을 흉내 낸 숨김 디렉터리
Evidence새 디렉터리가 생기면 상위 디렉터리의 mtime·ctime 이 바뀐다. 상위 디렉터리 타임스탬프가 사고 시간대와 일치하는지 확인한다
Investigation디렉터리 소유자 = 생성한 프로세스의 계정이다. /tmp의 수상한 디렉터리 소유자가 apache라면 웹 서버 경유 침입을 의심한다
[Detection]  FIM: /var/tmp/.ICE-unix/.. (공백 포함 디렉터리) 신규 생성, owner=apache
     ↓
[판단]       정상 서비스가 만들 이유 없는 위장 이름 + 웹 서버 계정 소유
     ↓
[Evidence]   stat 로 birth time 확인 → 웹 액세스 로그 동시간대 POST 요청 대조
     ↓
[Response]   디렉터리 내용 보존·해시 → 웹 취약점 점검

9. 실무에서 자주 발생하는 실수

실수결과예방
디렉터리를 만들고 나서 chmod 777모든 사용자가 파일 생성·삭제필요한 계정만 소유자·그룹으로 지정
mkdir -m 700 -p a/b/c로 상위도 700이라 생각상위 a, a/b는 umask 기준상위도 필요하면 따로 chmod
/tmp에 고정 이름 디렉터리 사용선점·심볼릭 링크 공격mktemp -d
배포판별 umask 차이 무시서버마다 권한 불일치umask 확인, 스크립트에서 모드 명시
링크 수를 "파일 개수"로 해석디렉터리 분석 오류링크 수 = 2 + 하위 디렉터리 수

10. 실습 체크리스트

[ ] mkdir 과 mkdir -p 의 차이를 확인했다
[ ] umask 값을 확인하고 기본 디렉터리 권한을 계산했다
[ ] Rocky 와 Ubuntu 의 mkdir 결과 차이를 비교했다
[ ] mkdir -m 이 umask 영향을 받지 않음을 확인했다
[ ] 하위 디렉터리 추가 시 상위 링크 수 변화를 확인했다
[ ] 공용 경로에서는 mktemp -d 를 써야 하는 이유를 이해했다

11. 핵심 정리

  • mkdir은 0777을 요청하고 커널이 umask 비트를 지워 최종 권한을 만든다.
  • 같은 명령도 Rocky(umask 022) → 755, Ubuntu(umask 002) → 775로 결과가 다르다.
  • -m은 umask와 무관하게 지정한 권한을 적용하지만, -p로 함께 생기는 상위 디렉터리에는 적용되지 않는다.
  • 디렉터리 생성에는 상위 디렉터리의 w·x 권한 이 필요하고, 상위의 mtime·ctime과 링크 수가 바뀐다.
  • 공용 경로의 예측 가능한 디렉터리명은 선점 공격 대상이다. mktemp -d를 사용한다.
  • 디렉터리 생성은 기본 로그에 남지 않는다. 상위 디렉터리 타임스탬프가 간접 증거가 된다.

12. 다음 편 예고

다음 글 「08. touch와 파일 생성」 에서는 touch로 빈 파일을 만드는 것 외에, 파일 시간을 임의의 과거로 바꾸는 기능 을 다룬다. 공격자가 흔적을 숨기는 타임스탬프 조작(timestomping)을 재현하고, 그래도 숨길 수 없는 시간(ctime)이 무엇인지 확인한다.


참고 자료


시리즈 이동

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글