리눅스의 권한은 파일에 적용되기도, 디렉터리에 적용되기도 한다.
일반 파일에 대한 읽기(r), 쓰기(w), 실행(x) 권한은 직관적으로 이해할 수 있지만,
디렉터리의 실행 권한이란 용어부터 난해한 구석이 있다.
이전에 리눅스 공부할 적에는 암기하고 넘어갔지만, 이번에 아주 제대로 이해하고자 한다.
일부 내용에 주관적 견해가 섞여있을 수 있음
1. 디렉터리 파일 뜯어보기
리눅스에서는 디렉터리를 비롯하여 장치, 소켓 등 모든 것을 파일로 취급한다.
디렉터리의 하위 항목은 '디렉터리 엔트리'라는 구조체로서 '디렉터리 파일'에 기록된다.
ℹ️ 디렉터리 엔트리에 대한 참고 포스트
링크
디렉터리 엔트리에는 i-node 번호와 파일명이 기록된다고 알고 있는데,
이번에 확실하게 까보고 눈으로 확인한다.
debugfs 명령
디렉터리 파일의 내용은 cat dir1 과 같은 명령으로 확인할 수 없다.
대신 파일시스템 내부를 직접 까보는 debugfs 명령을 사용하여 확인할 수 있다.
- 먼저, 직접 까볼 간단한 디렉터리를 만든다.
# 디렉터리 생성 (dir1 -> dir2)
mkdir -p ~/dir1/dir2
# 파일 생성 (dir1 -> f1)
touch ~/dir1/f1이후 debugfs 명령을 통해 dir1 디렉터리를 직접 들여다 볼 것이다.
- 홈디렉터리(~, /home/hyeonwoo)가 속한 파티션(= 루트디렉터리가 마운트된 파티션)을 찾는다.
# sudo lsblk
mmcblk0 179:0 0 116.5G 0 disk
├─mmcblk0p1 179:1 0 1G 0 part /boot/efi
└─mmcblk0p2 179:2 0 115.4G 0 part /
mmcblk0boot0 179:8 0 4M 1 disk
# sudo ls -al /dev | grep mmcblk0p2
brw-rw---- 1 root disk 179, 2 Jan 11 20:15 mmcblk0p2타겟 파티션은 mmcblk0p2 이며, /dev/mmcblk0p2 경로로 장치파일이 존재한다.
/etc/fstab명령으로 루트디렉터리를 마운트하는 장치명을 확인할 수도 있다.
장치명이 uuid로 작성되어 있는 경우,blkid명령으로 해당 uuid의 장치명을 확인한다.
- dir1 디렉터리 파일 내용 확인
다음과 같이 debugfs 명령을 실행하면 dir1 디렉터리 파일의 내용을 확인할 수 있다.
ℹ️ debugfs -R 옵션
debugfs는 기본적으로 대화형 프로그램으로,debugfs <장치명>만 입력 후 내부적으로 서브커맨드를 수행하며 이용할 수 있다.
-R 옵션 사용 시 내부에서 실행할 서브커맨드까지 한번에 입력하여, 별도의 대화 없이 서브커맨드만 실행하고 끝낸다.
# sudo debugfs -R "ls /home/hyeonwoo/dir1" /dev/mmcblk0p2
5898289 (12) . 5898242 (12) .. 5898341 (12) dir2
5898701 (4048) f1위 실행 결과와 같이 디렉터리 파일의 실제 내용을 확인했다.
"디렉터리 파일에는 "i-node (bytes) 파일명" 형식의 디렉터리 엔트리가 줄지어있다."
이제부터 이 사실에서 출발해서 디렉터리 권한에 대해 본격적으로 이해한다.
2. 디렉터리 권한에 대한 정확한 이해
디렉터리 라는 특수한 파일을 다룰 권한을 읽기, 쓰기, 실행으로 나누어 정확하게 파악한다.
이 중 실행 권한을 제대로 이해해야 이후 읽기, 쓰기 권한을 이해하기 편하므로 실행 권한을 먼저 다룬다.
실행 권한
일반 파일을 실행한다는 것은 파일의 내용을 해석해서 어떠한 동작을 수행 한다는 것이다.
이를 디렉터리(디렉터리 파일)에도 똑같이 적용한다.
디렉터리 파일에는 i-node와 파일명이 있는데,
디렉터리 파일의 내용을 해석해서 수행할 수 있는 동작은 무엇일까?
파일명을 보고 무언가 수행하기는 어려워 보이고,
i-node를 보고 해당 i-node에 저장된 세부정보를 읽어오는 동작을 수행할 수 있겠다.
즉, 실행 권한이 있으면 디렉터리 파일의 내용을 해석할 수 있으며, 파일을 해석하여 i-node 정보를 확인할 수 있다.
"실행 권한이 있으면 파일을 해석 -> i-node 정보 확인이 가능"
여기서 나아가면 cd나 ls, cat 등으로 해당 디렉터리 파일에 적힌 하위 항목을 다루는 것조차, 디렉터리 파일을 해석하여 하위 항목의 i-node를 얻어야 가능한 일이다.
가령, 디렉터리의 하위 파일을 cat으로 출력한다고 가정해보자.
단순하게 다음과 같은 절차가 진행된다.
(1) 디렉터리의 파일을 해석하여 하위 파일의 i-node 확인
(2) 하위 파일의 i-node에 적힌 권한 등을 확인하여 파일을 읽을 수 있는지 확인
(3) 하위 파일의 데이터블록을 읽어 write() 시스템콜을 호출 (= 터미널에 출력)
여기서 디렉터리에 실행 권한이 없다면 (1) 단계에서 실패하게 된다.
디렉터리 파일을 해석하지 못하면 '이 디렉터리를 지나 하위 항목에 접근'하거나 '하위 항목의 정보를 확인'하는 것이 불가능하다.
결론적으로 실행 권한은 다음과 같이 정리할 수 있다.
- 실행 권한은 근본적으로 파일의 해석에 대한 권한이다.
- 디렉터리의 경우, 하위항목(자신 포함)에 대한 접근 권한으로 이해할 수 있다.
읽기 권한
파일의 내용을 단순히 조회하는 권한이며, 디렉터리도 마찬가지로 디렉터리 파일을 조회한다.
파일의 내용을 조회하는 것과 이해(해석)하는 것의 차이가 여기에 있다.
- 조회: 영어 스펠링은 읽을 줄 알지만, 단어 뜻이나 문법을 몰라서 무슨 말인지 모름.
- 해석: 영어 단어와 문장을 이해함.
디렉터리 파일에는 i-node 번호와 파일명이 기록되어 있는데,
이 파일을 조회한다는 것은 실행 권한이 없더라도 i-node 번호와 파일명은 출력할 수 있다는 의미로 이해할 수 있다.
하지만 디렉터리 파일에 기록된 i-node는 보안 및 무결성을 위해, 읽기 권한이 있어도 i-node 번호는 노출시키지 않는다.
즉, i-node 번호는 단순히 조회하는 것 조차 파일 해석의 영역으로 분류되는 셈이다.
실행 권한 없이 읽기 권한만 있다면(r--), 해당 디렉터리의 파일명만 확인할 수 있다.
덧붙여, r-- 권한인 디렉터리(denied_dir1)에 대해 ls -i 명령을 실행하고, 이 때 호출되는 시스템콜 내역을 확인하면 다음과 같은 내용을 볼 수 있다.
# strace ls -i denied_dir1
(...)
openat(AT_FDCWD, "denied_dir1", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0774, st_size=4096, ...}) = 0
getdents64(3, 0x576388b8a920 /* 3 entries */, 32768) = 80
statx(AT_FDCWD, "denied_dir1/dir2", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_INO|STATX_SIZE, 0x7ffdc2080970) = -1 EACCES (Permission denied)denied_dir1의 하위항목인 dir2의 정보를 조회하기 위해 statx() 시스템콜을 호출했는데, Permission denied 에러가 발생한 것을 확인할 수 있다.
쓰기 권한
파일 자체와 그 내용을 추가/제거하는 권한이다.
디렉터리도 마찬가지로 디렉터리 파일의 내용을 추가/제거한다.
'파일을 쓴다'라는 행위는 일반 파일과 디렉터리 파일을 다룸에 차이가 없지만,
디렉터리 파일은 함부로 막 수정할 수 없기 때문에 일반 파일을 쓰는 것과 절차적인 차이가 생긴다.
"디렉터리 파일을 쓴다 = 디렉터리에 새 항목을 추가하거나 삭제한다"
라는 당연한 사실을 한번 더 상기하고 간다.
일반 파일을 수정할 때는 어느 부분에 뭐라고 쓸지/지울지 커널이 결정할 일이 없다.
사용자나 프로세스가 직접 결정하며, 파일시스템에 접근하는 커널은 해당 파일을 일절 해석하지 않는다.
반면에 디렉터리 파일을 수정할 때는 다음과 같은 절차가 필요하다.
(1) 파일명 형식 검사나 중복 확인 등의 validation.
(2) 삭제된 하위항목의 엔트리가 기록되어 있던 빈공간을 탐색.
이 절차를 수행하기 위해서는 파일의 내용을 해석해야 하는데,
알다시피 디렉터리 파일의 내용은 사용자나 프로세스가 직접 해석하고 수정하지 않는다.
따라서 디렉터리 파일의 내용을 수정하기 위해서는 쓰기 권한 뿐 아니라 실행 권한이 함께 필요하다.
사용자가 이 디렉터리(파일)을 해석하고 수정할 권한이 있어야, 커널이 권한을 확인하고(Authorization), 디렉터리 파일의 내용을 해석 및 수정한다.
결론적으로 쓰기 권한은 다음과 같이 정리할 수 있다.
"디렉터리의 쓰기 권한은 디렉터리 하위 항목을 추가/삭제 하는 권한이지만, 실행 권한을 동반해야 한다."
3. 정리
앞서 디렉터리 파일의 실제 내용을 뜯어보고, 읽기/쓰기/실행 각각의 권한이 정확히 어떤 의미이며 어떤 동작을 허용하는지 살펴보았다.
핵심적인 내용을 한번 더 정리하면서 갈무리한다.
- 디렉터리라는 특수한 파일에는 "i-node (bytes) 파일명" 형식의 디렉터리 엔트리가 줄지어있다.
실행 권한: '디렉터리 파일 내용을 해석할 수 있는가'에 대한 권한이며, 파일을 해석함으로써 하위 항목의 i-node 정보를 조회한다.쓰기 권한: 디렉터리 하위항목을 추가/제거하는 권한이며, 실행 권한을 동반해야 한다.읽기 권한: 디렉터리 파일의 내용을 조회하는 권한이다.- 보안 및 무결성을 위해, 디렉터리 파일에 적힌 i-node 번호는 단순히 조회하는 것 조차 파일 해석(실행 권한)의 영역으로 다룬다.
'Linux' 카테고리의 다른 글
| [Linux] 환경변수와 source 명령 파헤치기 (0) | 2026.01.29 |
|---|---|
| [Linux] sudo 파헤치기 (0) | 2026.01.20 |
| 안쓰는 디스크를 리눅스 NFS로 사용하기: Ubuntu 24.04 (0) | 2025.10.07 |
| [Linux] 하드링크 파헤치기 (0) | 2025.09.02 |