Linux 권한 시스템 setuid,capabilities

greenTea·2025년 5월 24일

Linux를 공부하면서 capabilities와 setuid에 대하여 보았습니다.

1. setuid와 setgid: 전통적 권한 상승

setuid/setgid란?

setuid(Set User ID)와 setgid(Set Group ID)는 Unix/Linux에서 파일 실행 시 권한을 변경하는 특별한 권한 비트입니다.

  • setuid: 파일을 실행할 때 실행자가 아닌 파일 소유자의 권한으로 실행
  • setgid: 파일을 실행할 때 실행자의 그룹이 아닌 파일 소유 그룹의 권한으로 실행

실습: setuid 설정하기

[user1@localhost ~]$ ls -l $(which sleep)
-rwxr-xr-x. 1 root root 69088 117  2024 /usr/bin/sleep

[user1@localhost ~]$ cp /usr/bin/sleep ./mysleep
[user1@localhost ~]$ ls -l mysleep 
-rwxr-xr-x. 1 user1 user1 69088  524 17:32 mysleep

[user1@localhost ~]$ chmod +s mysleep 
[user1@localhost ~]$ ls -l mysleep 
-rwsr-sr-x. 1 user1 user1 69088  524 17:32 mysleep

[user1@localhost ~]$ ./mysleep 100
user1       2291    1722  0 18:04 pts/0    00:00:00 ./mysleep 100
-> user1으로 실행되었다.

[user1@localhost ~]$ sudo chown root:root ./mysleep
[user1@localhost ~]$ sudo chmod +s mysleep
[user1@localhost ~]$ ./mysleep 100

[user1@localhost ~]$ ps -ef
root        2273    1722  0 18:01 pts/0    00:00:00 ./mysleep 100
-> root로 실행되었다.

권한 표시에서 주목할 점:

  • 첫 번째 s: setuid 비트 (소유자 실행 권한 위치)
  • 두 번째 s: setgid 비트 (그룹 실행 권한 위치)

setuid의 주요 용도

# passwd 명령어 - 일반 사용자가 비밀번호 변경 시 root 권한 필요
[user1@localhost ~]$ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 33600  415  2024 /usr/bin/passwd

# sudo - 권한 상승 도구
[user1@localhost ~]$ ls -l /usr/bin/sudo
-rwsr-xr-x. 1 root root 143304  320  2024 /usr/bin/sudo

2. Linux Capabilities: 세분화된 권한 제어

위 setid의 경우는 root/non-root로 구분해서 사용하기 위한 방식으로 오래전 설계된 방식이였고 한계가 존재합니다.

이러한 root/non-root 이분법의 한계를 극복하기 위해 Linux는 capabilities 시스템을 도입했습니다.

Capabilities의 개념

Capabilities는 root 권한을 40개 이상의 세분화된 권한으로 나눈 시스템입니다:

  • CAP_CHOWN: 파일 소유권 변경
  • CAP_DAC_OVERRIDE: 파일 권한 무시
  • CAP_KILL: 임의 프로세스에 시그널 전송
  • CAP_NET_ADMIN: 네트워크 관리
  • CAP_NET_RAW: 원시 소켓 생성
  • CAP_SYS_ADMIN: 시스템 관리 작업
  • CAP_SYS_TIME: 시스템 시간 변경

프로세스 Capabilities 확인

[user1@localhost ~]$ sudo bash
[root@localhost user1]# ps
    PID TTY          TIME CMD
   2161 pts/1    00:00:00 sudo
   2163 pts/1    00:00:00 bash
   2182 pts/1    00:00:00 ps

[root@localhost user1]# getpcaps 2161
2161: =ep
[root@localhost user1]# getpcaps 2163
2163: =ep

Capabilities 표기법 해석

=ep의 의미:

  • =: 모든 capabilities
  • e: effective - 현재 활성화된 권한
  • p: permitted - 허용된 권한
  • i: inheritable - 상속 가능한 권한 (여기서는 없음)

즉, =ep모든 capabilities가 effective와 permitted 상태로, 사실상 완전한 root 권한을 의미합니다.

3. ping의 진화: setuid에서 capabilities 그리고 현대적 접근법

전통적 ping (setuid 방식)

과거 ping은 ICMP 패킷을 보내기 위해 원시 소켓(raw socket)이 필요했고, 이는 root 권한을 요구했습니다:

# 전통적 방식
[user1@localhost ~]$ ls -l /bin/ping
-rwsr-xr-x 1 root root 44168 May  7 23:51 /bin/ping

Capabilities를 이용한 개선

setuid 대신 CAP_NET_RAW capability만 부여하는 방식:

# setuid 제거 후 capability 설정
[user1@localhost ~]$ sudo chmod u-s /bin/ping
[user1@localhost ~]$ sudo setcap cap_net_raw+p /bin/ping
[user1@localhost ~]$ getcap /bin/ping
/bin/ping = cap_net_raw+p

이 방식의 장점:

  • 최소 권한 원칙: ping에 필요한 권한만 부여
  • 보안 강화: 전체 root 권한 대신 네트워크 관련 권한만 획득
  • 위험 감소: 버그나 취약점 악용 시 피해 최소화

현대적 접근: 비특권 ICMP 소켓

Linux 3.0부터 도입된 혁신적 기능으로, 권한 없이도 ping이 가능합니다.

기술적 배경

2011년에 추가된 SOCK_DGRAM + IPPROTO_ICMP 조합을 통해 일반 사용자도 ICMP Echo 패킷을 보낼 수 있게 되었습니다.

현대 ping의 동작 과정

# 현대 ping의 소켓 생성 순서 (strace로 확인)
socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) = 3     # 비특권 방식 시도
# 실패 시에만
socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) = 3       # 특권 방식 fallback

ping 복사본으로 테스트

[user1@localhost ~]$ cp /usr/bin/ping ./myping
[user1@localhost ~]$ ls -l myping
-rwxr-xr-x. 1 user1 user1 70072  524 17:36 myping

# setuid나 capability 없이도 작동!
[user1@localhost ~]$ ./myping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=10.2 ms

시스템 설정 확인

비특권 ICMP 소켓 사용 가능 여부는 sysctl 설정으로 제어됩니다:

[user1@localhost ~]$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0 2147483647  # 모든 그룹 허용
 0부터 2147483647의 그룹은 모두 사용할 수 있다(그냥 전체 허용)
 
# 또는
net.ipv4.ping_group_range = 1 0           # 비활성화 상태

4. sudo 권한 시스템

sudo 설정 확인

[user1@localhost ~]$ sudo -l
user1 사용자는 localhost에서 다음 명령을 실행해야 합니다:
    (ALL) NOPASSWD: ALL

이 설정의 의미:

  • (ALL): 모든 사용자로 실행 가능
  • NOPASSWD: 비밀번호 없이 실행 가능
  • ALL: 모든 명령어 실행 가능

매우 강력한 권한이지만 개발/테스트 환경에서는 편리합니다.

5. 권한 시스템의 발전 과정 요약

1단계: 전통적 setuid

사용자 → setuid 바이너리 → 전체 root 권한 획득
  • 장점: 단순하고 확실
  • 단점: 과도한 권한, 보안 위험

2단계: Capabilities

사용자 → capability 설정된 바이너리 → 필요한 권한만 획득
  • 장점: 최소 권한 원칙, 보안 강화
  • 단점: 복잡성 증가, 호환성 문제

마무리

  1. Capabilities 사용 (세분화된 권한 필요시에 사용하자)
  2. setuid는 최후 수단 (레거시 호환성이 필요할 때 사용하자)

ping의 사례에서 볼 수 있듯이, 같은 기능을 구현하는 방법이 시대에 따라 진화하고 있으며 이에 맞는 적절한 방법을 선택해야 합니다.
최소한의 권한으로 실행하도록 하는게 가장 좋을 것 같습니다.

참고자료

container security

profile
greenTea입니다.

0개의 댓글