파일과 디렉터리 권한
95분 안팎
학습 목표
소유자·그룹·디렉터리 탐색 권한을 바꿔 서비스 계정의 접근 성공과 실패를 재현합니다.
개념
접근 실패를 작업 단위로 분해합니다
서비스가 기동 중 Permission denied를 냈다면 무엇을 하려다 실패했는지부터 구분합니다. 설정 읽기, 기존 파일 덧쓰기, 새 파일 생성, 파일 삭제는 서로 다른 권한을 사용합니다. 이 레슨은 앞에서 준비한 bcweb로 이 동작들을 직접 시도하고 성공해야 할 동작과 거부해야 할 동작을 분리합니다. 관리자 계정으로 열리는 파일이 서비스에도 열린다고 가정하지 않습니다.
실습 대상은 /srv/bootcamp-m02/lab-root 아래 config와 data입니다. config에는 웹 앱 기동 설정 app.conf가 있고 data에는 실행 중 생성되는 자료가 들어갑니다. 설정은 bcops가 변경하며 서비스는 읽습니다. 데이터 디렉터리는 bcweb가 소유해 자료를 만들 수 있도록 합니다. config 파일을 서비스 소유로 주면 읽기 전용 모드를 설정했더라도 소유자의 chmod로 쓰기를 열 수 있어 경계가 약해집니다.
모드와 소유자를 함께 읽습니다
일반 파일의 r은 내용을 읽기, w는 내용 변경, x는 실행 시도 권한입니다. 소유자·그룹·기타 세 범주에 r=4, w=2, x=1을 합한 8진수 모드를 적용합니다. 640인 app.conf는 소유자 읽기/쓰기, 그룹 읽기, 기타 접근 없음입니다. 서비스는 bcapp 그룹으로 설정을 읽지만 쓰기는 하지 못하도록 app.conf 소유자를 bcops, 그룹을 bcapp으로 지정합니다.
일반적인 모드 검사에서는 현재 UID가 소유자이면 소유자 비트를, 아니면 해당 그룹 자격이 있으면 그룹 비트를, 아니면 기타 비트를 선택합니다. 세 칸을 합쳐 유리한 권한을 모으는 방식이 아닙니다. 소유자 권한이 0인데 기타 읽기를 허용한 파일을 소유자가 읽지 못하는 상황도 가능하므로 숫자만 보고 접근 결과를 단정하지 않습니다.
chmod는 모드를 바꾸고 chown은 소유자를 바꾸며 chgrp는 그룹을 바꿉니다. 둘의 역할을 섞으면 모드가 맞는데도 잘못된 주체가 변경할 수 있습니다. Linux VM에서는 stat -c로 UID·GID·모드를 함께 읽습니다. 표시 이름은 이름 서비스에 따라 달라질 수 있어 UID도 대조합니다. 재귀로 전체에 같은 모드를 주면 설정 파일까지 실행 가능해지는 등 의도하지 않은 결과가 생길 수 있습니다.
디렉터리의 x는 길을 통과하는 권한입니다
디렉터리 r은 이름 목록을 읽는 권한, x는 경로를 탐색하는 권한입니다. 어떤 파일의 전체 경로를 알고 있더라도 상위 디렉터리를 통과할 x가 없으면 파일에 도달하지 못합니다. app.conf가 640이어도 /srv/bootcamp-m02 또는 lab-root에서 서비스 그룹 탐색을 막으면 읽기가 실패합니다. 최종 파일만 반복해서 chmod하지 말고 namei -l로 경로 구성요소를 관찰합니다.
디렉터리 w와 x가 있으면 그 안에서 새 이름을 만들거나 항목을 삭제할 수 있습니다. 파일 자체에 w가 없다는 사실만으로 삭제나 교체를 막았다고 판단하면 안 됩니다. config 디렉터리에 서비스 그룹 쓰기를 주지 않고 750으로 두는 이유가 여기에 있습니다. bcops는 소유자로 편집할 수 있고 bcweb는 그룹 r/x로 읽고 탐색하되 설정 이름을 바꾸지 못합니다.
data 디렉터리는 bcweb:bcapp 750으로 설정합니다. 서비스는 소유자 r/w/x로 새 자료를 만들고 지울 수 있습니다. data 아래 이전 자료의 소유권을 전부 서비스로 바꾸지는 않습니다. 새 자료 저장 권한과 과거 증거 변경 권한은 요구가 다르기 때문입니다. 이 미션은 data 루트에 검사 파일을 만들고 지워 런타임 쓰기 능력을 확인합니다.
허용과 거부를 한 쌍으로 시험합니다
check.sh는 sudo -u bcweb id -u 결과가 계정 DB의 서비스 UID와 같은지 먼저 확인합니다. 관리자 인증 실패가 모든 접근을 막았는데 이를 최소 권한 성공으로 해석하는 오류를 줄입니다. 그 뒤 app.conf 읽기 성공과 data/probe.txt 쓰기 성공을 검사합니다. 검사는 임시 자료를 지우고 이전 앱 설정 내용은 유지합니다.
거부 검사는 app.conf 덧쓰기, config에 새 파일 만들기, 기존 app.conf 삭제를 각각 시도합니다. 하나라도 성공하면 FAIL입니다. /srv/bootcamp-m02/protected/marker.txt는 root 전용 디렉터리에 둔 가짜 보호 자료이며 서비스 읽기가 실패해야 합니다. 실제 운영 비밀 파일이나 /etc/shadow를 시험 대상으로 삼지 않습니다. 보호 자료의 값도 인계 문서에 넣을 필요가 없습니다.
권한이 잘못 열려 있을 때 삭제 검사까지 진행하면 실습 설정을 지울 수 있습니다. 그래서 준비 전 스냅샷이 있는 전용 VM을 사용하며 이전 모듈 원본 lab-root는 별도 보존합니다. starter를 고칠 때 요구 모드를 먼저 확인하고 검사합니다. 부정 검사 성공으로 파일이 변했다면 이전 원본에서 복원한 뒤 재검사하며 오류 출력을 단순히 숨겨 완료로 처리하지 않습니다.
실패 원인과 변경 이유를 연결합니다
Permission denied는 권한 검사 실패를 나타내지만 어느 구성요소에서 막혔는지는 메시지 한 줄만으로 알기 어렵습니다. 실행 UID, 전체 경로, 상위 x, 파일 r/w 순으로 좁히고 stat 결과를 남깁니다. No such file or directory라면 생성 위치와 경로 철자를 먼저 확인합니다. 설정 파일이 없는데 모드만 변경하려 하면 chmod 자체가 다른 오류로 실패합니다.
모드가 충분한데도 실패하면 읽기 전용 마운트·ACL·SELinux 같은 다른 통제도 후보입니다. 이번 검사 환경은 기본 모드로 제어하는 전용 실습 경로이며 정책 전체를 다루지 않습니다. ls에서 추가 ACL 표시가 보이면 getfacl로 별도 확인하고, 보안 정책을 끄는 방식으로 해결하지 않습니다. mode check의 성공은 모든 운영 접근 제어를 검증했다는 뜻이 아닙니다.
권한 기록에는 경로, 소유자, 그룹, 모드, 실행 계정, 시도한 동작과 종료 결과를 함께 적습니다. chmod 777로 접근이 되는지는 제출 기준이 아닙니다. 읽기를 살리면서 설정 변경을 막았는지 설명해야 합니다. 디렉터리 탐색과 권한 범주 선택의 기준은 Linux의 path_resolution 문서를 참고했고 명령 옵션은 더 읽기의 chmod 장에서 확장합니다.
경로 탐색 기준: Linux path_resolution(7).
따라하기
640의 세 범주 분해
Python으로 접근 비트만 계산합니다. 파일 소유자와 서비스 UID 확인은 Linux VM에서 이어 합니다.
mode = 0o640
for name, shift in [('owner', 6), ('group', 3), ('other', 0)]:
bits = (mode >> shift) & 7
print(f'{name}: read={bool(bits & 4)} write={bool(bits & 2)} execute={bool(bits & 1)}')실행 결과
owner: read=True write=True execute=False group: read=True write=False execute=False other: read=False write=False execute=False
파일과 상위 경로 관찰
앞 레슨의 준비 VM을 그대로 쓰면 setup.sh를 다시 실행하지 않습니다. file-modes ZIP에서 작업합니다. GNU stat으로 모드·소유 UID·GID, namei로 상위 탐색 경로를 확인합니다.
sudo -u bcweb stat -c "%a %u %g %n" /srv/bootcamp-m02/lab-root/config/app.conf
sudo namei -l /srv/bootcamp-m02/lab-root/config/app.conf작업과 서비스 권한 구분
task.sh를 완성할 때 설정은 bcops:bcapp 640, config 디렉터리는 bcops:bcapp 750, data는 bcweb:bcapp 750으로 맞춥니다. 변경 대상 경로를 확인한 뒤 실행합니다.
bash task.sh
sudo -u bcweb id -u
sudo -u bcweb cat /srv/bootcamp-m02/lab-root/config/app.conf성공과 거부를 검증
check.sh가 data 쓰기 성공과 config 추가·덧쓰기·삭제 및 가짜 보호 자료 읽기 실패를 검사합니다. 실패 stderr를 확인하고 UID 확인 단계의 실패와 구분합니다.
bash check.sh
cat evidence/config-denied.txt
cat evidence/protected-denied.txt확인 문제
실습
앞 레슨의 VM을 사용해 설정 소유자·그룹·모드와 데이터 쓰기 권한을 구현합니다. 파일 수정뿐 아니라 설정 생성·삭제 거부를 검사합니다.
실행 명령
bash check.sh
기대 결과
PASS modes: read, data write, config append/create/delete denied, protected denied
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 파일 권한 때문에 서비스가 실패하는 상황을 설명합니다.