
저는 LEMP 스택을 실행 중이고 이에 대한 간단한 제어판을 작성하고 싶습니다.
php-fpm
그래서 PHP 스크립트에서 다시 시작할 수 있기를 원합니다 . 이를 달성하기 위해 제가 한 일은 다음과 같습니다.
c
이와 같은 바이너리 래퍼를 만들었습니다.php-shell.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CMN_LEN 100
int main(int argc, char *argv[])
{
char cmd[MAX_CMN_LEN] = "", **p;
if (argc < 2)
{
fprintf(stderr, "Usage: ./php_shell terminal_command ...");
exit(EXIT_FAILURE);
}
else
{
strcat(cmd, argv[1]);
for (p = &argv[2]; *p; p++)
{
strcat(cmd, " ");
strcat(cmd, *p);
}
system(cmd);
}
return 0;
}
이 프로그램은 다음과 같이 컴파일됩니다.
gcc php_shell.c -o php_shell
그런 다음 다음과 같이 nginx 사용자를 추가했습니다 sudo visudo
.
Defaults:nginx !requiretty
nginx ALL=(ALL) NOPASSWD:/path/to/php_shell
그런 다음 PHP 스크립트에서 다음과 같이 명령을 실행합니다.
var_dump(shell_exec('sudo /path/to/php_shell "service nginx restart" 2>&1'));
이 스크립트 php 스크립트를 실행하면 502 Gateway Error
모든 php-fpm
프로세스가 종료되고 백업이 시작되지 않는 것을 볼 수 있습니다.
어떤 아이디어가 있나요? 내가 잘못하고 있는 걸까? php에서 스크립트를 실행하여 nginx 서버를 다시 시작하고 싶습니다 service nginx restart
. 이 목표를 어떻게 달성할 수 있나요?
답변1
축하해요! nginx 서버에서 임의의 코드를 실행하도록 할 수 있는 모든 사람에게 무제한 루트 액세스 권한을 부여하고 있습니다. 모든 CGI 스크립트와 PHP 페이지는 물론 임의의 코드를 실행하는 데 사용할 수 있는 모든 것이 안전한지 확인하는 것이 좋습니다.
C 래퍼는 nginx가 루트로 모든 명령을 실행할 수 있도록 sudo를 구성하는 것과 같습니다.
아니요그냥 그렇게 하세요.
특정 명령에 대해 별도의 셸 스크립트(또는 기타) 래퍼를 작성한 다음 해당 래퍼 스크립트에만 sudo 액세스 권한을 부여하세요. 예를 들어, /usr/local/sbin/restart-nginx.sh
이것은 실제로아무것도 없다그러나 service nginx restart
nginx sudo에 스크립트에 대한 액세스 권한을 부여하십시오.
dmidecode -s system-uuid
그런 다음 예를 들어 이전 질문에 표시된 것처럼 실행할 완전히 독립적인 또 다른 스크립트를 작성하십시오 . nginx sudo에 스크립트에 대한 액세스 권한을 부여합니다.
각 개별 스크립트는 더 간단하고 단순할수록 좋습니다. 가장 안전한 방법은 명령줄이나 환경 변수에서 사용자 입력을 전혀 받아들이지 않는 것입니다.
일부 래퍼 스크립트가 사용자 입력을 허용해야 하는 경우 사용하기 전에 온전성 검사를 수행하고 모든 사용자 제공 입력을 삭제합니다. 그리고 변수를 인용하십시오. 예를 들어 항상 인용 부호 "$variable"
없이 사용하십시오 $variable
.
래퍼 스크립트가 너무 길고 복잡해지면 루트로 실행해야 하는 최소 명령 또는 명령 집합만 식별하고 이를 sudo
기본 스크립트에서 호출하는 별도의 스크립트(또는 여러 스크립트)로 작성해 보세요. 즉, 가능한 한 루트로 실행하지 마십시오.