programing

루트 권한 삭제

shortcode 2022. 7. 16. 14:11
반응형

루트 권한 삭제

루트로 시작하는 데몬이 있습니다(낮은 포트에 바인드할 수 있습니다).초기화 후 안전상의 이유로 루트 특권을 폐기하고 싶습니다.

C에서 이 작업을 수행할 수 있는 올바른 코드 조각을 알려 주실 수 있는 분 계십니까?

man 페이지도 읽어보고 어플리케이션별로 다양한 구현에 대해 알아보았습니다.다르고 복잡한 것도 있습니다.이것은 보안 관련 코드입니다.다른 사람이 저지르는 실수를 재발명하고 싶지 않습니다.제가 찾고 있는 것은 베스트 프랙티스로 알려진 포터블 라이브러리 기능으로, 올바르게 기능할 수 있다는 것을 알기 위해 사용할 수 있는 것입니다.그런 게 있어요?

참조용:루트로 시작합니다.다른 uid 및 gid로 실행되도록 변경해야 합니다.보충 그룹을 올바르게 설정해야 합니다.이후 root 권한으로 다시 변경할 필요가 없습니다.

모든 권한(사용자 및 그룹)을 폐기하려면 사용자보다 먼저 그룹을 폐기해야 합니다.그 때문에userid그리고.groupid에는 드롭처의 사용자와 그룹의 ID가 포함되어 있습니다.유효 ID도 루트라고 가정하면 setuid()setgid()호출하여 이 작업을 수행합니다.

if (getuid() == 0) {
    /* process is running as root, drop privileges */
    if (setgid(groupid) != 0)
        fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
    if (setuid(userid) != 0)
        fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
}

편집증이 있는 경우 루트 권한을 되찾으려고 시도할 수 있습니다.이러한 권한은 실패할 수 있습니다.실패하지 않으면 구제금융을 받을 수 있다.

 if (setuid(0) != -1)
     fatal("ERROR: Managed to regain root privileges?");

또한 편집증이 있는 경우 seteuid()setegid()를 설정할 수도 있지만 프로세스가 root에 의해 소유되는 경우 setuid() 및 setgid()는 이미 모든 ID를 설정하기 때문에 필요하지 않습니다.

보조 그룹을 설정하는 POSIX 함수가 없기 때문에 보조 그룹 목록이 문제가 됩니다(getgroups()는 있지만 setgroups()는 없습니다).사용할 수 있는 BSD 및 Linux 확장 setgroups()가 있습니다.이것에 대해서는, 염려해 주세요.

프로세스가 루트 소유 디렉토리에 남아 있지 않도록 또는 다른 디렉토리로 이동해야 합니다.

당신의 질문은 Unix 전반에 대한 것이므로 이것이 매우 일반적인 접근법입니다.Linux 에서는 이 방법이 더 이상 선호되지 않습니다.현재 리눅스 버전에서는 실행 파일의 기능을 설정하고 일반 사용자로 실행해야 합니다.루트 액세스는 필요 없습니다.

다음 기사를 찾고 있습니다.

POS36-C권한을 포기하는 동안 올바른 해지 순서 준수

해당 페이지의 내용을 복제하지 않고 정보를 저장하는 것이 가장 좋은 방법인 것 같습니다.

내가 가장 잘 할 수 있는 일은 이것이었다.

#define _GNU_SOURCE  // for secure_getenv()


int drop_root_privileges(void) {  // returns 0 on success and -1 on failure
    gid_t gid;
    uid_t uid;

    // no need to "drop" the privileges that you don't have in the first place!
    if (getuid() != 0) {
        return 0;
    }

    // when your program is invoked with sudo, getuid() will return 0 and you
    // won't be able to drop your privileges
    if ((uid = getuid()) == 0) {
        const char *sudo_uid = secure_getenv("SUDO_UID");
        if (sudo_uid == NULL) {
            printf("environment variable `SUDO_UID` not found\n");
            return -1;
        }
        errno = 0;
        uid = (uid_t) strtoll(sudo_uid, NULL, 10);
        if (errno != 0) {
            perror("under-/over-flow in converting `SUDO_UID` to integer");
            return -1;
        }
    }

    // again, in case your program is invoked using sudo
    if ((gid = getgid()) == 0) {
        const char *sudo_gid = secure_getenv("SUDO_GID");
        if (sudo_gid == NULL) {
            printf("environment variable `SUDO_GID` not found\n");
            return -1;
        }
        errno = 0;
        gid = (gid_t) strtoll(sudo_gid, NULL, 10);
        if (errno != 0) {
            perror("under-/over-flow in converting `SUDO_GID` to integer");
            return -1;
        }
    }

    if (setgid(gid) != 0) {
        perror("setgid");
        return -1;
    }
    if (setuid(uid) != 0) {
        perror("setgid");
        return -1;    
    }

    // change your directory to somewhere else, just in case if you are in a
    // root-owned one (e.g. /root)
    if (chdir("/") != 0) {
        perror("chdir");
        return -1;
    }

    // check if we successfully dropped the root privileges
    if (setuid(0) == 0 || seteuid(0) == 0) {
        printf("could not drop root privileges!\n");
        return -1;
    }

    return 0;
}

언급URL : https://stackoverflow.com/questions/3357737/dropping-root-privileges

반응형