리눅스 Capabilities
IT 위키
- root 가 가진 특권을 기능 단위로 쪼개 프로세스나 실행 파일에 개별적으로 부여할 수 있게 한 리눅스의 권한 모델
전통적인 유닉스는 프로세스를 특권(uid 0)이거나 아니거나 둘로만 나누었다. 그래서 1024번 미만 포트를 열기 위해 웹 서버를 root 로 띄우면, 그 프로세스가 탈취당했을 때 파일 삭제부터 커널 모듈 적재까지 전부 가능해진다. Capabilities 는 이 문제를 해결하려고 커널 2.2 에서 도입되었다. 필요한 특권만 주는 최소 권한의 원칙을 커널 수준에서 구현한 장치다.
SetUID와 혼동하기 쉬운데, SetUID 는 실행자를 파일 소유자로 바꾸는 것이고 Capabilities 는 특권을 항목별로 나눠 주는 것이다.
| 이름 | 허용되는 동작 |
|---|---|
CAP_CHOWN
|
파일의 소유자·소유 그룹 변경 |
CAP_DAC_OVERRIDE
|
파일 읽기·쓰기·실행 권한 검사 무시 |
CAP_KILL
|
소유자가 다른 프로세스에 시그널 전송 |
CAP_NET_BIND_SERVICE
|
1024번 미만 포트에 바인딩 |
CAP_NET_RAW
|
RAW 소켓 사용. ping, tcpdump 가 필요로 한다
|
CAP_NET_ADMIN
|
네트워크 인터페이스·라우팅·방화벽 설정 |
CAP_SYS_MODULE
|
커널 모듈의 적재와 제거 |
CAP_SYS_ADMIN
|
마운트 등 광범위한 시스템 관리. 사실상 root 에 가까워 남용하면 안 된다 |
CAP_SYS_TIME
|
시스템 시각 변경 |
CAP_SYS_BOOT
|
재부팅 |
CAP_AUDIT_CONTROL
|
커널 감사 기능의 활성화·비활성화와 규칙 변경 |
CAP_MAC_ADMIN
|
MAC(강제적 접근통제) 정책 설정 변경 |
CAP_SETUID, CAP_SETGID
|
프로세스의 UID·GID 조작 |
전체 목록은 man 7 capabilities 에 있다.
프로세스는 여러 개의 capability 집합을 가진다.
- Permitted : 가질 수 있는 상한
- Effective : 지금 실제로 행사되는 것. 커널이 권한 검사에 쓰는 값이다
- Inheritable : exec 후에도 물려줄 수 있는 것
- Bounding : 이 프로세스와 자손이 절대로 넘을 수 없는 한계
- Ambient : 상속 조건을 완화해 일반 실행 파일에도 전달되게 한 집합
# 실행 파일에 부여된 capability 확인 # getcap /usr/bin/ping /usr/bin/ping = cap_net_raw+ep # 부여 # setcap cap_net_bind_service=+ep /usr/local/bin/myserver # 제거 # setcap -r /usr/local/bin/myserver # 프로세스가 가진 capability 확인 # cat /proc/1234/status | grep Cap
ep 는 Effective + Permitted 를 뜻한다.
- 데몬에 필요한 항목만 주면 root 로 띄우지 않고도 동작시킬 수 있다.
- 반대로 잘못 부여하면 위험하다.
CAP_SYS_MODULE이 붙은 바이너리는 커널 모듈을 올릴 수 있으므로 사실상 시스템 전체를 장악할 수 있고,CAP_SYS_ADMIN·CAP_DAC_OVERRIDE도 마찬가지다. - 점검 시에는 SetUID 파일 목록과 함께
getcap -r /로 capability 가 붙은 파일도 함께 확인해야 한다. - 컨테이너 런타임은 기본적으로 위험한 capability 를 떨어뜨린 상태로 컨테이너를 실행한다.
