답변:
프로세스 자체는 setuid (2)를 호출해야합니다. 아직 chroot (8)에서 실행하지 않는지 조사해야합니다. 내가 아는 한 루트가 다른 프로세스의 uid를 변경할 수있는 방법이 없습니다.
루트로 실행하는 이유는 포트를 바인딩하는 것이므로 상위 포트에서 일반 사용자로 실행하고 OS X에서 ipfw (8)를 사용하여 포트 80 / 443 / etc를 상위 포트로 전달하는 것이 좋습니다.
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
setuid()
혼자 부르는 것만으로는 충분하지 않습니다.
sudo tcpdump -Z
initgroups (3), setgid (2) 및 setuid (2)를 사용하여 자체 프로세스의 루트 권한을 삭제합니다.
# code taken from:
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
initgroups
, setgid
, setuid
(마지막!)를 정확하게 유닉스의 오른쪽 패러다임, 항상 따라야한다. 또한 책임있는 "droproot"함수는 세 가지 기본 함수가 모두 성공을 반환하더라도 uid 및 gid가 실제로 설정되어 있는지 확인합니다.
다음을 사용하여 다른 사용자로 명령을 실행할 수 있습니다 su
.
su USERNAME -c COMMAND
에 COMMAND
삭제 된 권한으로 실행 됩니다 USER
.
기본적으로 su
대상 사용자의 쉘 인터프리터를 사용하여 명령을 실행합니다. 반대로 기본 동작은 현재 환경에서 실행되는 독립형 프로그램으로 sudo
취급하는 COMMAND
것입니다. 물론 이러한 기본 동작은 다양한 스위치 및 환경 변수를 사용하여 변경할 수 있습니다.
su
USERNAME가 정의 된 쉘이없는 (또는 경우 작동하지 않습니다 /bin/false
) sudo는이 작업을 수행하는 반면.
su
이 반영됩니다. 그러나 항상 -s
스위치 를 사용하여이를 무시할 수 있습니다 . 목적은 su
주어진 사용자의 행동을 모방하는 것입니다. 이는 보통 자신의 껍질에 의해 영향을받습니다. 반대로, sudo
기본적으로 대상 사용자의 쉘 설정은 무시합니다.
권한을 삭제하려면 비 루트 사용자가 필요합니다. 그런 다음 해당 사용자로 전환하면됩니다.
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
이는 랩퍼 스크립트가 아닌 프로그램 자체에서 수행 됩니다 . 많은 프로그램은 특정 목적 (예 : 낮은 번호의 포트에 바인딩)을 위해 루트 권한이 필요하지만 그 이후에는 루트가 필요하지 않습니다. 따라서 이러한 프로그램은 루트로 시작되지만 더 이상 필요하지 않으면 권한을 삭제합니다.
루트 권한이 전혀 필요하지 않으면 루트 권한으로 실행하지 마십시오. 예 :
# Change this:
myprog -C /my/config/file
# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
setuid
함수 는 실제 UID가 아닌 유효 UID 만 설정합니다 . setreuid
프로세스가 권한을 다시 얻지 못하도록 하려면 사용해야 합니다. (그리고 위의 코드는 보조 그룹 권한으로 취급하지 않습니다 중 하나 그것은 단지 대부분 신뢰할 수있는 코드를 실행하기에 적합합니다..)
setuid()
실제 사용자 ID와 저장된 사용자 ID를 설정합니다. 당신은 생각할 수 있습니다 seteuid()
. 모든 시스템에이있는 setreuid()
것은 아니므로 어느 곳에서나 사용할 수 없습니다. 정확한 의미 setuid()
는 복잡하지만 euid 0이 있으면 모든 기존 사용자 ID 권한을로 삭제할 수 있습니다 setuid()
. 이 대답에서 가장 큰 누락이 있다는 것이다 initgroups
나 setgroups
뿐만 아니라 호출해야 setgid
하고 setuid
, 그보다 철저한 주장이 마지막에 수행해야합니다.
다른 실행 파일을 실행하는 중입니다. 즉, 호출하는 기능 execve
이나 다른 exec
기능을 사용하는 경우 ( system
또는 같은 기능을 통해 간접적으로) popen
자식 프로세스를 처음부터 권한없이 실행해야하는 경우 가장 간단한 방법은 셸을 호출하고을 호출하십시오 su
. 다음은 Perl에서 코드가 어떻게 생겼는지에 대한 개요입니다.
$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
자식 프로세스가 루트로 시작해야하지만 나중에 권한을 삭제해야하는 경우 프로세스의 권한 을 다운 그레이드하는 방법을 보여주는 이 답변의 코드를 참조하십시오 .