sudo는 모든 권한이 있는 sudoer만 명령을 실행할 수 있는지 여부를 어떻게 결정합니까?

sudo는 모든 권한이 있는 sudoer만 명령을 실행할 수 있는지 여부를 어떻게 결정합니까?

sudo가 설치된 데비안 시스템에서 기본 사용자가 실행할 수는 있지만 바이너리는 동일한 권한을 가지기 때문에 왜 실행할 수 ls없는지 궁금합니다 .ifconfig

-rwxr-xr-x 1 root root 114032 Jan 26  2013 /bin/ls
-rwxr-xr-x 1 root root 72296 Sep  7  2012 /sbin/ifconfig

그렇다면 명령을 실행할 수 있는 사람과 실행할 수 없는 사람을 시스템에 알려주는 일종의 데이터베이스나 정책이 있어야 한다고 생각합니다. 그런데 이를 어디서 찾을 수 있습니까? 불가능합니다. /etc/sudoers이 파일에는 누가 루트 sudoer이고 누가 다음이 아닌지 정의되어 있지 않기 때문입니다.

%admin  ALL=(ALL)   ALL
john ALL=/usr/sbin/useradd, /usr/sbin/userdel, /usr/bin/passwd

그러면 john실행할 수 없습니다 /sbin/ifconfig. 그러나 시스템은 그것이 허용되지 않는다는 것을 어떻게 알 수 있습니까?

답변1

sudo이 작은 차이에도 불구하고 한계는 커널에 더 가깝습니다. 모든 사람이 프로그램을 실행할 권리가 있지만 /sbin/ifconfig이것이 프로그램이 실행된다는 의미는 아닙니다.일반 사용자 권한으로 작업을 완료할 수 있는 충분한 권한이 있어야 합니다.

기본적으로 UNIX 권한 설정을 사용하면 다음과 같은 권한이 있습니다./sbin/ifconfig실행 가능한 코드가 있는 프로세스를 생성합니다.. 사실, 그들이 나중에 어떻게 ls행동 ifconfig하든, 그들의 과정은그런 일이 일어났습니다. 그러나 ifconfig이를 실행하는 사용자에게 충분한 권한이 부여되지 않았기 때문에 조기에 종료됩니다. Frank Thomas의 의견을 인용하면 다음과 같습니다.

[그것은 할 수 없습니다] 네트워크 카드 개체를 잡아

노트:ifconfig --help실제로는 권한 없이 실행될 수도 있습니다 . 이 작업에는 네트워크 카드가 필요하지 않으므로 실패하지 않으며 루트 권한이 필요하지 않습니다.

이제 낮은 권한으로 거부되는 작업에 대해 더 구체적으로 알고 싶다면 다음을 시도해 ifconfig볼 수 있습니다 strace. 다음은 의 예입니다 ls.

strace - 시스템 호출 및 신호 추적

이것에러 코드권한 거부 값은 13( EACCES)입니다. 다음을 사용하여 strace어떤 시스템 호출이 트리거되는지 확인할 수 있습니다 EACCES.

$ strace ls ~ 2>&1 | grep EACCES
# No output, I can read my home directory just fine.
$ strace ls /root 2>&1 | grep EACCES
openat(AT_FDCWD, "/root", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 EACCES (Permission denied)

openat거기에서 시스템 호출이 실패한 것을 볼 수 있습니다 . 사실, 현재 사용자로서 저는 해당 디렉토리를 읽을 수 있는 권한이 없으므로 /root커널이 ls관련 정보를 얻으려고 시도할 때 실패했다는 사실을 깨닫고 /root반환 하면 다음과 같이 알려줍니다.lsopenatEACCES

ls: 디렉토리를 열 수 없습니다. /root: 권한이 거부되었습니다.

이제 시스템 호출이 실패할 때 사용자에게 알리는 것은 프로그램에 달려 있습니다. 예를 들어 C에서는 다음과 같습니다.

if((rootdir = opendir("/root")) == NULL){
    perror("myprogram");
    exit(1);
}

권한이 낮은 상황에서는 다음과 같은 결과가 발생합니다.

$ ./myprogram
myprogram: Permission denied

이제 를 실행하면 사용자로 실행할 때 어떤 시스템 호출이 거부되었는지 strace /sbin/ifconfig확인할 수 있습니다 . ifconfig다음은 무선 인터페이스를 끄려고 시도하는 예입니다.

$ strace ifconfig wlan0 down 2>&1 | grep EPERM
ioctl(4, SIOCSIFFLAGS, {ifr_name="wlan0", ???}) = -1 EPERM (Operation not permitted)

보시다시피 ioctl시스템 호출이 실패합니다. 이 경우 오류 호출은 EPERM(1: 작업이 허용되지 않습니다.). 프로그램은 ifconfig다음 위치에서 경고합니다.setifflags기능:

// ...
if (ioctl(s, SIOCSIFFLAGS, &ifreq) == -1)
    err(EXIT_FAILURE, "SIOCSIFFLAGS");
// ...

관련 정보