루트 권한 삭제
루트로 시작되는 데몬이 있습니다 (낮은 포트에 바인딩 할 수 있음). 초기화 후 안전상의 이유로 루트 권한을 삭제하고 싶습니다.
누구든지 이것을 할 C 로 알려진 올바른 코드 조각을 가리킬 수 있습니까 ?
매뉴얼 페이지를 읽었고 다양한 응용 프로그램에서 다양한 구현을 살펴 보았으며 모두 다르며 일부는 정말 복잡합니다. 이것은 보안 관련 코드이며 다른 사람들이 저지르는 동일한 실수를 재발견하고 싶지 않습니다. 제가 찾고있는 것은 모범 사례, 잘 알려진 좋은 이식 가능한 라이브러리 함수입니다.이 함수는 그것이 올바르게 될 것이라는 지식에서 사용할 수 있습니다. 그런 것이 존재합니까?
참고로 저는 루트로 시작합니다. 다른 uid 및 gid에서 실행되도록 변경해야합니다. 보조 그룹을 올바르게 설정해야합니다. 나중에 루트 권한으로 다시 변경할 필요가 없습니다.
이 기사를 찾고 있습니다.
POS36-C. 권한을 포기하는 동안 올바른 해지 순서를 준수하십시오.
해당 페이지의 내용을 복제하지 않고 몇 가지 정보를 가장 잘 넣는 방법을 모르겠습니다 ...
모든 권한 (사용자 및 그룹)을 삭제하려면 사용자보다 먼저 그룹을 삭제해야합니다. 점을 감안 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 () 도 원할 수 있지만 프로세스가 루트 소유인 경우 setuid () 및 setgid ()가 이미 모든 ID를 설정했기 때문에 필요하지 않습니다.
보충 그룹을 설정하는 POSIX 함수가 없기 때문에 보충 그룹 목록이 문제가됩니다 ( getgroups () 는 있지만 setgroups () 없음). 사용할 수있는 BSD 및 Linux 확장 setgroups () 가 있습니다.
당신은 또한해야 chdir("/")
또는 다른 디렉토리에, 그래서 프로세스는 루트 소유의 디렉토리에 남아 있지 않습니다.
귀하의 질문은 일반적으로 유닉스에 관한 것이기 때문에 이것은 매우 일반적인 접근 방식입니다. Linux에서는 더 이상 선호되는 접근 방식이 아닙니다. 현재 Linux 버전에서는 실행 파일에 대한 CAP_NET_BIND_SERVICE
기능 을 설정하고 일반 사용자로 실행해야합니다. 루트 액세스가 필요하지 않습니다.
이것이 제가 최선을 다할 수있는 것입니다.
#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
'programing' 카테고리의 다른 글
IE8에서 http 응답 헤더 검사 (0) | 2021.01.15 |
---|---|
Javascript의 중첩 함수에서 반환 값 (0) | 2021.01.15 |
Python 실행 파일 : py2exe 또는 PyInstaller? (0) | 2021.01.15 |
.gitignore에 Linux 실행 파일을 추가하는 방법은 무엇입니까? (0) | 2021.01.15 |
원격 거부 된 마스터-> 마스터 (사전 수신 후크 거부 됨) (0) | 2021.01.15 |