보호된 정보를 공개하지 않고 사용자가 스크립트를 실행할 수 있도록 허용하는 방법

보호된 정보를 공개하지 않고 사용자가 스크립트를 실행할 수 있도록 허용하는 방법

루트 사용자가 환경 변수에 설정된 일부 자격 증명(예: API 키)을 갖고 있고 권한이 없는 사용자 John이 있는 경우 John이 다음과 같은 스크립트를 실행하도록 하려면 어떻게 해야 합니까?용도John에게 그 가치가 유출될 위험 없이 API 키를 말했습니까?

답변1

질문이 좀 초점이 없는 것 같네요.

  • 질문,그 자체로, "수퍼유저 환경 변수"(예: "루트 환경 변수")에서 값을 얻는 방법에 대해 설명합니다. 그게 무슨 뜻인지도 잘 모르겠어요. John이 "root"로 로그인했거나 su또는를 통해 "root"로 실행 중인(다른) 사용자의 환경에서 값을 얻어야 한다는 뜻인가요 sudo? 아니면 환경에 대해 이야기하고 있습니까?프로세스 (아마도 백그라운드 프로세스) "루트"로 실행되고 있습니까?

    그러나 어떤 세부 사항을 염두에 두든 이는 핵심이 매우 역동적이고 일시적인 것처럼 들립니다. 이것이 무슨 뜻인지 이해하지 못하기 때문에 불가능하다고는 말 못하지만 어려울 것 같습니다.

  • 그런데 주석에서 스크립트를 실행 가능하지만 읽을 수 없게 만드는 것에 대해 이야기합니다. 이는 루트가 아닌 사용자가 키를 읽을 수 없는 한 스크립트에 키를 하드 코딩할 의향이 있음을 의미합니다. 이는 키가 매우 정적이고 거의 변경되지 않아 키가 변경될 때마다 스크립트를 수정할 의향이 있음을 의미합니다.

    유앤엘바로 이 주제에 대한 긴 스레드가 있습니다. 스크립트는 실행 가능하지만 읽을 수는 없습니까?  안타깝게도 대부분의 대답은 부정적이거나 편향, 전환 또는 해결 방법이며 그중 일부는 다른 것보다 더 잘 작동합니다. 예를 들어,산타나가 제안하다/etc/sudoers John이 다음을 수행할 수 있도록 하는 항목을 생성합니다 .달리다높은 권한으로 스크립트를 읽을 수는 없지만 스스로 읽을 수는 없습니다. 그러나 스크립트에 높은 권한이 필요하지 않은 경우(키 획득 이외의 경우) 높은 권한으로 스크립트를 실행하고 싶지 않습니다.

    그러나이 관련 질문(수퍼유저에서), 나는 스크립트를 C 프로그램으로 래핑하여 실행 가능하지만 읽을 수 없도록 만드는 복잡한 방법을 제시합니다. 제가 그 답변에서 설명했듯이 이 기술은 완벽하지는 않습니다. 정보가 유출될 수 있는 방법이 있습니다.

  • 가장 합리적이고 그럴듯한 해석인 IMHO는 John이 읽을 수 없는 파일에 키가 보관되어 있다는 것입니다. 이러한 배열을 구현하는 전통적인 방법은 setUID 및/또는 setGID입니다. ( sudo또한 유용합니다.)

이를 수행하는 방법에 대한 예는 다음과 같습니다. 다음과 같이 C 프로그램을 작성하세요.

#include <stdio.h>
#include <stdlib.h>

#KEY_FILE 정의        (적절한 경로 이름)
#스크립트 정의          (적절한 경로 이름)

기본()
{
        파일 *key_fp;
        문자 키[80];        (적절하게 조정하세요)
        gid_t gid;
        uid_t uid;
        char *args[10];      (적절하게 조정하세요)

        key_fp = fopen(KEY_FILE, "r");
        if (key_fp == NULL)
        {
                오류(KEY_FILE);
                출구(1);
        }
        (읽고 검증할 코드열쇠)
        fclose(key_fp);
        if (setenv("KEY", 키, 1) != 0)
        {
                fprintf(stderr, "setenv()에 문제가 있습니다.\n");
                출구(1);
        }
        gid = getgid();
        uid = getuid();
        // 사용
        // if (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0)
        // 사용 가능한 경우; 그렇지 않으면
        if (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0)
        {
                fprintf(stderr, "권한을 삭제하는 데 문제가 발생했습니다.\n");
                출구(1);
        }
        args[0] = "스크립트 이름";     (적절하게 조정하세요)
        인수[1] = NULL;
        execv(SCRIPT, args);
        오류(SCRIPT);
        출구(1);
}

KEY_FILE키가 포함된 파일의 전체 경로 이름을 정의하고 , SCRIPT스크립트가 포함된 파일의 전체 경로 이름을 정의합니다. John에게 스크립트에 대한 읽기 액세스 권한이 있지만 키 파일에 대한 액세스 권한은 없고 두 경로의 어떤 디렉터리에도 쓰기 액세스 권한이 없는지 확인하세요. setUID 및/또는 setGID를 만들어 이 프로그램이 키 파일을 읽을 수 있도록 준비합니다. 키를 읽고, 환경에 삽입하고, 권한을 삭제하고, 스크립트를 실행합니다. (프로그램에 제공된 명령줄 인수가 스크립트에 전달되도록 위 코드를 수정할 수 있습니다.)

위에서 설명한 대로 스크립트는 John의 UID 및 GID를 사용하여 실행되지만 환경의 키를 사용하여 실행됩니다. 일부 시스템에서는 John이 에서 또는 를 사용하여 스크립트 환경을 읽는 것이 가능할 수 있습니다 . 그렇다면 스크립트가 즉시 키를 로컬(내보내지 않은) 변수에 복사하고 변수를 설정 해제하도록 하는 것이 도움이 될 수 있습니다./proc/(pid_of_script)/environpsKEY

스크립트가 프로그램에 키를 전달하는 것이 안전할 것입니다.

  • 파이프(예: )를 통해,printf "%s" (key_value) | (program)
  • 여기 문서를 통해 또는
  • here 문자열을 통해.

환경을 통해 가치를 전달하는 데 따른 위험은 위에 언급되어 있습니다. 에서 확실히 볼 수 있으므로 명령줄 매개변수로 전달하지 마세요 ps.

를 통해 프로그램을 실행 가능하게 만들려면 sudoJohn의 UID 및 GID를 하드 코딩해야 할 수도 있습니다. 왜냐하면 sudo실제 ID와 유효 ID를 설정하기 때문입니다.

관련 정보