리눅스 기초 · 권한과 사용자 · 이론
권한은 파일이 아니라 동작에 붙는다
한 줄 요약
rwx 세 글자는 파일에 붙었을 때와 디렉터리에 붙었을 때 뜻이 다르다. 이 차이를 모르면 "읽기 전용 파일이 왜 지워지지" 같은 사고를 계속 만나게 된다.
왜 이게 필요했나
공유 디렉터리를 하나 만들어 팀에서 같이 쓰기로 했다. 각자 파일을 올리고, 남의 파일은 건드리지 않기로 약속했다. 그런데 어느 날 누군가의 파일이 사라졌다. 파일 권한은 644, 소유자도 그대로였다.
여기서 "권한이 644 인데 어떻게 지워졌지"라고 물으면 답이 안 나온다. 삭제는 파일에 대한 동작이 아니라 디렉터리에 대한 동작이기 때문이다. 파일을 지운다는 것은 디렉터리에서 이름 하나를 떼어내는 일이고, 그러려면 그 디렉터리에 쓰기 권한이 있으면 된다. 파일 자체가 읽기 전용이든 남의 것이든 상관없다.
유닉스는 이 문제를 위해 별도의 비트를 하나 더 뒀다. 그게 sticky 비트다.
어떻게 동작하나
먼저 같은 글자가 대상에 따라 어떻게 달라지는지 정리한다.
| 비트 | 파일에서 | 디렉터리에서 |
| --- | --- | --- |
| r | 내용을 읽을 수 있다 | 목록을 볼 수 있다(ls) |
| w | 내용을 고칠 수 있다 | 항목을 만들고 지울 수 있다 |
| x | 실행할 수 있다 | 그 안으로 들어가고 경로를 통과할 수 있다 |
디렉터리에 r만 있고 x가 없으면 이름은 보이는데 그 안의 파일 정보는 못 읽는다. 반대로 x만 있고 r이 없으면 목록은 못 보지만 정확한 이름을 알면 접근할 수 있다.
여기에 특수 비트 세 개가 얹힌다. 8진수 네 자리 중 맨 앞자리다.
- setuid(4): 실행 파일에 붙으면 실행하는 사람이 아니라 파일 소유자의 권한으로 돈다.
passwd명령이 대표적이다. - setgid(2): 디렉터리에 붙으면 그 안에 새로 만들어지는 파일이 만든 사람의 기본 그룹이 아니라 디렉터리의 그룹을 상속한다. 공유 디렉터리의 핵심 장치다.
- sticky(1): 디렉터리에 붙으면 그 안의 항목은 파일 소유자·디렉터리 소유자·root 만 지울 수 있다.
/tmp가1777인 이유가 이것이다.
그래서 팀 공유 디렉터리의 표준 형태는 2770(그룹 상속 + 그룹 밖 차단)이고, 아무나 올리되 남의 것은 못 지우게 하려면 1777이다.
현장에서 만나는 모습
첫째, 그룹을 추가했는데 적용이 안 된다. usermod -aG devs alice를 실행해도 alice 가 이미 로그인해 있던 셸에는 반영되지 않는다. 그룹 목록은 프로세스가 만들어질 때 정해지기 때문이다. 새 로그인 세션이 필요하다. 여기서 -a(append)를 빼면 기존 보조 그룹이 전부 날아간다 - 운영 서버에서 자주 나오는 사고다.
둘째, 8진수와 기호 표기. chmod 750 run.sh처럼 절대값으로 주는 방식과 chmod g+x,o-rwx run.sh처럼 상대적으로 고치는 방식이 있다. 배포 스크립트에서는 현재 상태와 무관하게 결과가 같아야 하므로 절대값이 안전하다. 반대로 대량 파일을 손볼 때는 기호 표기가 실수를 줄인다.
셋째, 권한 확인은 눈이 아니라 명령으로. ls -l의 -rwxr-x---를 사람이 세는 것보다 stat -c %a가 정확하다. 채점 스크립트나 점검 스크립트를 쓸 때는 항상 stat을 쓴다.
다음 실습에서 할 것
사용자와 그룹을 직접 만들고, setgid 와 sticky 를 건 공유 디렉터리를 구성한 뒤, 마지막에는 "이 파일이 기대한 권한인지"를 검사해 종료 코드로 알려 주는 점검 스크립트를 작성한다.