사용자가 명령을 실행할 때 절차
(참조)
Linux 파일은 16 bit로 접근 권한을 관리합니다. 4bit는 파일 종류 (-,d,c,b,s,l,p)에, 3bit는 특수권한(setuid, setgid, sticky bit)에 사용합니다.
setuid
사용자가 setuid 비트가 설정된 파일을 실행하면, 프로세스가 임시로 파일의 소유자 권한으로 실행됩니다.
root만 접근해야 하는 파일을 임시로 일반 사용자도 접근하도록 허용할 때 주로 사용합니다. 예를 들어 사용자가 자신의 비밀번호를 변경할 수 있도록 /etc/shadow
에 setuid를 설정합니다.
chmod할 때 4000나 u+x를 사용해 setuid 비트를 설정합니다 (예, chmod u+x file.txt
). setuid가 설정된 파일을 사용자가 실행할 권한이 있다면 소문자 s, 실행할 권한이 없다면 대문자 S로 표시가 됩니다.
u+x | u-x | |
---|---|---|
u+s | 소문자 s | 대문자 S |
u-s | x | - |
Q. /etc/shadow 명령을 o+x를 하면 모든 사용자가 실행할 수 있지 않아? 왜 굳이 u+s를 해야 해?
블로그 서비스를 제공하는 3 tier 아키텍처를 상상해볼게요. 저는 제가 쓴 블로그를 마음껏 수정하거나 삭제할 수 있습니다. 그렇다고 DB에 직접 접근해서 SQL을 실행하지는 않습니다. API 서버를 통해서 DB를 수정하지요. 왜 그럴까요?
DB만 가지고는 사용자를 인증하고 권한을 인가하는 등 권환을 관리하기 어렵습니다. 또 정말 복잡한 비즈니스 로직을 거쳐 블로그를 수정할 수 있기 때문이지요. 그래서 API 서버가 책임지고 사용자들의 권한에 맞춰 DB를 변경하도록 구성하는 것입니다.
setuid로 이러한 맥락에서 이해할 수 있습니다. 비밀번호에 대한 모든 정보는 /etc/shadow에 담겨 있습니다. 누구도 바로 접근해서는 안되고 /usr/bin/passwd 명령을 사용해 간접적으로 접근해야 합니다. 마치 API 서버처럼 말이지요.
API 서버는 DB의 admin 권한을 가졌기 때문에 DB의 모든 레코드를 수정할 수 있습니다. /usr/bin/passwd 명령도 /etc/shadow 파일을 수정할 수 있는 root이어야 합니다. 하지만 비밀번호는 누구든지 바꿀 수 있어야 하지요.
모든 사용자가 /usr/bin/passwd를 실행할 수 있어야 하다는 전제와 root로만 실행해야 한다는 전제가 충돌합니다. 이를 해결하기 위한 기능이 setuid 입니다. 일반 사용자도 실행할 수 있지만 실제로는 root 권한을 얻어서 실행이 됩니다.
Q. 일반 사용자가 Root 권한을 얻어서 실행한다면 다른 사용자의 비밀번호도 바꿀 수 있지 않나요?
그럴 수 없습니다. 누구나 API 요청을 보낼 수는 있지만, API 서버가 ‘내가 적은 블로그’만 수정할 수 있도록 제한하는 것과 같습니다.
Linux는 파일을 실행할 때 두 가지 사용자 정보를 명령(프로그램)에게 보냅니다.
- Real UID: 파일을 실행한 사용자 ID (
getuid()
함수) - Effective UID(EUID): setuid가 설정되어 있다면 파일 소유자의 ID (
geteuid()
함수)
/usr/bin/passwd 명령을 실행하면 EUID는 root가 되고, UID는 명령을 실행한 사용자의 ID가 됩니다. passwd 프로그램은 getuid 함수로 사용자 정보를 가져와 딱 그 사용자의 비밀번호만 수정할 수 있도록 제한합니다.
Sticky Bit
여러 사용자가 공동 작업하는 공유 디렉터리 /shared
를 만든다고 가정해볼게요. /shared
디렉터리는 공용이기 때문에 777 권한을 가지고 있습니다. 사용자는 /shared
디렉터리 아래에서 자유롭게 파일을 만들고 수정할 수 있어요. 그렇다고 다른 사용자가 만든 파일을 함부러 지우면 안됩니다. 파일을 소유한 사용자만 파일을 지울 수 있어야 해요.
이런 니즈를 만족하기 위해 sticky bit 기능이 나왔습니다. sticky 비트가 설정된 디렉토리는 파일의 소유자, 공용 디렉터리의 소유자, 그리고 root만 삭제, 이름변경할 수 있습니다. (예, chmod +t <directory>
)
Q. 파일 내용을 마음대로 바꿀 수 있는 건 곧 파일을 삭제하는 것과 같은 거 아닌가요? sticky bit는 왜 삭제만 제한하나요?
UNIX 구조상 파일 내용을 수정하는 것과 파일을 삭제하는 것의 동작 방식이 완전히 달라서 그렇습니다. 파일 내용을 수정할 때는 파일 자체에 접근합니다. 반면, 파일을 삭제하거나 이름을 변경할 때는 디렉터리의 엔트리(메타데이터)를 수정합니다.
따라서 이 권한을 각자 별도로 조작할 수 있어야 합니다. 파일을 삭제하는 것도, 내용을 수정하는 것도 막으려면 sticky bit를 설정하고 쓰기 권한을 제거해야 합니다.
Q. 디렉터리 권한과 파일 권한 중 어느 게 우선되나요?
디렉터리 권한이 우선됩니다. 파일 권한이 777(rwxrwxrwx
)이라 하더라도 디렉터리 권한이 700(rwx------
)라면 소유자만 해당 파일에 접근할 수 있습니다.
파일 종류
리눅스는 모든 것을 파일로 관리합니다.
- 일반 파일(-): 텍스트, 실행 파일 등 대부분의 파일
- 디렉토리(d)
- 심볼릭 링크(l): 다른 파일이나 디렉토리를 가리키는 소프트 링크
- 장치 블록 파일(b): 하드디스크, CD-ROM 등 블록 단위의 입출력 장치
- 문자 장치 파일(c): 키보드, 마우스, 터미널 등 문자(바이트) 단위의 입출력 장치
- 파이프(p): 프로세스 간 통신을 위한 특수 파일
- 소켓(s): 네트워크 통신 등 IPC를 위한 특수 파일