루트 권한을 사용하여 프로그래밍 방식으로 파일에 쓰는 가장 안전한 방법은 무엇입니까?

루트 권한을 사용하여 프로그래밍 방식으로 파일에 쓰는 가장 안전한 방법은 무엇입니까?

대규모 애플리케이션은 루트 권한이 필요한 파일에 대해 특정 시간에 소수의 쓰기를 수행해야 합니다. 실제로는 파일이 아니고 파일 형태로 Linux에 노출되는 하드웨어 인터페이스입니다.

전체 애플리케이션에 루트 권한을 부여하지 않기 위해 중요한 작업을 수행하는 bash 스크립트를 작성했습니다. 예를 들어 다음 스크립트는 하드웨어 인터페이스의 포트 17을 출력으로 활성화합니다.

echo "17" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio17/direction

그러나 suid내 시스템에서는 bash 스크립팅이 비활성화되어 있으므로 이를 달성하는 가장 좋은 방법이 무엇인지 알고 싶습니다.

  1. 제공된 해결 방법 중 일부를 사용하세요.여기

  2. 기본 애플리케이션에서 스크립트를 호출 sudo하고 그에 따라 sudoers 목록을 편집하여 스크립트를 호출할 때 비밀번호가 요구되지 않도록 하세요. sudo 권한을 부여하는 것이 약간 불편합니다 echo.

  3. C 프로그램을 작성하여 사용 fprintf하고 suid 루트로 설정하면 됩니다. 문자열과 파일 이름을 하드코딩하고 루트만 편집할 수 있는지 확인하세요. 또는 텍스트 파일에서 문자열을 읽어 누구도 파일을 편집할 수 없도록 다시 한번 확인하세요.

  4. 위에서 제안한 것보다 더 안전하거나 간단하지만 제가 생각하지 못한 다른 솔루션이 있습니까?

답변1

sudo액세스 권한을 부여할 필요는 없습니다 echo. 실제로 이는 예를 들어 sudo echo foo > bar리디렉션이 루트가 아닌 원래 사용자로 수행되므로 의미가 없습니다.

콜릿을 사용하여 액세스가 필요한 사용자에게만 해당 스크립트(및 기타 유사한 스크립트)에 대한 액세스를 허용합니다 sudo.NOPASSWD:

이것이 항상 가장 좋고 안전한 사용 방법입니다 sudo. 루트 권한이 필요한 몇 가지 명령을 별도의 스크립트로 분리하고 신뢰할 수 없거나 부분적으로 신뢰할 수 있는 사용자가 루트로만 스크립트를 실행할 수 있도록 허용합니다.

스크립틀릿은 sudo사용자로부터 매개변수(또는 입력)를 받아서는 안 됩니다(즉, 호출하는 다른 프로그램에는 하드 코딩된 옵션과 매개변수가 있어야 합니다). 또는 사용자로부터 받아야 하는 매개변수/입력을 매우 신중하게 검증해야 합니다.

검증 시 편집증을 가지십시오. 제외할 "알려진 나쁜" 항목을 찾지 말고 "알려진 좋은" 항목만 허용하고 불일치나 오류 또는 조금이라도 의심스러운 항목이 있으면 중단하십시오.

유효성 검사는 스크립트에서 가능한 한 빨리(바람직하게는 실행 전) 이루어져야 합니다.아무것그렇지 않으면 루트로).


진짜이 답변을 처음 작성할 때 언급했어야 했지만 스크립트가 쉘 스크립트인 경우~ 해야 하다올바른 인용모두변하기 쉬운. 사용자 제공 입력이 포함된 변수를 참조할 때는 특히 주의하세요.어느하지만 특정 변수가 안전하다고 가정하지 마세요.모두 인용.

여기에는 사용자가 제어할 수 있는 환경 변수가 포함됩니다( 예: "$PATH"CGI 스크립트의 등도 포함됩니다) . 사실, 그냥 인용해 보세요. 여러 인수가 포함된 명령줄을 작성해야 하는 경우 배열을 사용하여 인수 목록을 작성하고 - 를 인용하십시오 ."$HOME""$USER""$QUERY_STRING""HTTP_USER_AGENT""${myarray[@]}"

나는 항상 "모든 것을 인용하라"고 말합니까? 기억해. 해.

답변2

GPIO 파일의 소유자를 확인하십시오.

ls -l /sys/class/gpio/

대부분 그룹이 소유하고 있음을 알 수 있습니다 gpio.

-rwxrwx--- 1 root     gpio     4096 Mar  8 10:50 export
...

이 경우 gpiosudo를 사용하지 않고 간단히 사용자를 그룹에 추가하여 액세스 권한을 부여할 수 있습니다.

sudo usermod -aG gpio myusername

변경 사항을 적용하려면 로그아웃했다가 다시 로그인해야 합니다.

답변3

한 가지 솔루션(특히 Linux 데스크톱에서, 다른 경우에도 적용 가능)은 다음을 사용하는 것입니다.D-버스루트로 실행되는 소규모 서비스를 활성화하고폴킷승인합니다. 이것이 바로 폴킷의 핵심이다디자인됨그것으로부터;소개 문서:

polkit은 권한이 없는 프로그램("클라이언트")에 서비스를 제공하기 위해 권한이 있는 프로그램("메커니즘")에서 사용하도록 고안된 인증 API를 제공합니다. 시스템 아키텍처 및 개요는 polkit 매뉴얼 페이지를 참조하십시오.

도우미 프로그램을 실행하는 대신 권한이 없는 대규모 프로그램이 버스에서 요청을 보냅니다. 도우미는 시스템 부팅 시 시작되는 데몬으로 실행될 수 있으며 더 나은 방법도 있습니다.필요에 따라 systemd에서 활성화. 그런 다음 어시스턴트는 polkit을 사용하여 요청이 승인된 위치에서 왔는지 확인합니다. (또는 이 경우 과도하다고 느껴지면 다른 하드 코딩된 인증/권한 부여 메커니즘을 사용할 수도 있습니다.)

내가 하나 찾았어D-Bus를 통한 통신에 대한 좋은 기본 기사, 아직 테스트하지는 않았지만,폴킷을 추가하는 기본적인 예시인 것 같습니다..

이 접근 방식에서는 setuid로 아무것도 표시할 필요가 없습니다.

답변4

sudo의 echo 대신 Bless tee를 사용하는 것은 루트 권한을 제한해야 하는 상황을 해결하는 일반적인 방법입니다. /dev/null로 리디렉션하는 것은 출력 누출을 막는 것입니다. T-shirt는 원하는 대로 작동합니다.

echo "17" | sudo tee /sys/class/gpio/export > /dev/null
echo "out" | sudo tee /sys/class/gpio/gpio17/direction > /dev/null

관련 정보