sudo 및 SSH 터미널 접속 권한을 보유한 운영자 계정
보안 취약점 조치 · 웹 런타임 업그레이드
PHP 보안 취약점 조치 및 PHP-FPM 패치 판올림
PHP 긴급 보안 권고(CVE-2024-4577 CGI 인자 인젝션 및 RCE)에 대응하여 NGINX + PHP-FPM 환경에서 최신 보안 패치 버전으로 업그레이드하고, 풀(Pool) 설정 백업·이전과 php.ini 위험 함수 비활성화를 적용하는 표준 조치 절차입니다.BEFORE YOU START
시작 전에 준비하세요
현재 서비스 중인 웹 애플리케이션의 PHP 요구 버전 및 필수 확장 모듈(extension) 목록
기존 /etc/php/*/fpm/pool.d/www.conf 및 php.ini 설정 파일의 백업 저장 경로
NGINX 가상 호스트 설정(fastcgi_pass 소켓 경로) 및 헬스체크 URL
권장 대상 운영 중인 웹 서버(NGINX + PHP-FPM)에서 긴급 PHP 보안 취약점 패치 및 버전 판올림을 무중단에 준하는 안전한 절차로 수행하려는 시스템 관리자·DevOps 엔지니어
FOLLOW THE RECIPE
8단계 구성·점검 레시피
현재 PHP 취약 버전 및 확장 모듈(Extension) 진단
현재 서버의 PHP CLI 및 PHP-FPM 버전이 최근 공지된 CVE 취약점 대상인지 확인하고, 현재 로드된 확장 모듈 목록과 실행 중인 PHP-FPM 서비스를 읽기 전용으로 진단합니다.
php -v
php --iniphp -m | sortsystemctl list-units 'php*-fpm*' --no-pager
sudo ss -lxnp | grep php- 현재 구동 중인 PHP 버전과 취약 CVE 보안 패치 릴리스 대조 완료
- 애플리케이션이 요구하는 필수 확장 모듈(pdo_mysql, mbstring, opcache, curl 등) 목록 파악
- 현재 서비스 중인 FPM 유닉스 소켓 경로 확인
구버전(EOL 버전)이거나 보안 패치 이전 빌드인 경우, 신규 보안 패키지 설치 시 확장 모듈이 누락되지 않도록 현재 모듈 목록을 기록합니다.
NGINX 연동 소켓 경로 및 디스크 여유 공간을 점검합니다.
NGINX 연동 소켓 경로 및 기존 풀(Pool) 설정 점검
NGINX 설정에서 PHP-FPM과 통신 중인 fastcgi_pass 유닉스 소켓 경로와 기존 풀 파일의 사용자(user/group), listen 권한을 사전에 점검합니다.
sudo grep -rn 'fastcgi_pass' /etc/nginx/sudo find /etc/php -path '*/fpm/pool.d/*.conf' -type f -printdf -h / /var /tmp- NGINX 가상 호스트가 참조하는 fastcgi_pass 유닉스 소켓 경로 확인
- 기존 FPM 풀 파일의 user, group, listen.owner 설정 확인
- 신규 PHP 패키지 및 모듈 설치를 위한 디스크 여유 공간 확보
기존 소켓 경로가 /run/php/php8.2-fpm.sock과 같이 특정 버전으로 고정되어 있다면 NGINX 설정과의 무중단 전환 경로를 계획합니다.
공식 보안 저장소를 통해 최신 보안 패치 PHP-FPM을 설치합니다.
공식 보안 저장소 갱신 및 최신 패치 PHP-FPM 설치
Ubuntu(PPA) 또는 Rocky Linux(Remi)의 공식 검증 보안 저장소에서 취약점이 해결된 최신 PHP-FPM 패키지와 필수 확장 모듈을 설치합니다.
sudo apt-get update
sudo apt-get install -y php8.3-fpm php8.3-cli php8.3-common php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl php8.3-opcache php8.3-zip php8.3-intlsudo dnf makecache
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.3 -y
sudo dnf install -y php-fpm php-cli php-common php-mysqlnd php-mbstring php-xml php-opcache php-curl php-zipphp -v
php8.3 -v 2>/dev/null || true- 공식 보안 패치가 적용된 최신 PHP 8.3 바이너리 설치 완료 확인
- 기존에 사용하던 필수 모듈(mysql, mbstring, curl 등)이 누락 없이 함께 설치됨을 확인
신규 패키지 설치 완료 후에도 NGINX는 여전히 구버전 소켓을 가리키고 있으므로 서비스 중단 없이 풀 설정을 마이그레이션할 수 있습니다.
기존 FPM 풀 설정 백업 및 신규 풀 파일을 구성합니다.
기존 FPM 풀·php.ini 백업 및 신규 버전 이전
기존 풀 설정 파일(www.conf)과 php.ini를 백업하고, 신규 버전의 풀 설정에 프로세스 매니저(pm), 소켓 경로, 소유자 권한을 정합성에 맞게 복사·반영합니다.
sudo cp -p /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/www.conf.bak 2>/dev/null || sudo cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak
sudo cp -p /etc/php/8.2/fpm/php.ini /etc/php/8.2/fpm/php.ini.bak 2>/dev/null || sudo cp -p /etc/php.ini /etc/php.ini.baksudoedit /etc/php/8.3/fpm/pool.d/www.confsudo php-fpm8.3 -t 2>/dev/null || sudo php-fpm -t[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
request_terminate_timeout = 60s
catch_workers_output = yes- 기존 풀 설정 및 php.ini 백업 파일(.bak) 생성 확인
- 신규 풀 설정에서 listen 소켓 경로와 권한(0660) 일치 확인
- php-fpm -t 문법 검증 성공(syntax is OK) 확인
설정 문법이 정상이면 신규 FPM 서비스를 가동하고 NGINX upstream을 무중단으로 전환할 준비가 완료되었습니다.
신규 PHP-FPM 서비스를 기동하고 NGINX FastCGI 소켓을 전환합니다.
신규 PHP-FPM 기동 및 NGINX 무중단 리로드
신규 보안 PHP-FPM 서비스를 실행하고 부팅 시 자동 시작으로 등록한 뒤, NGINX 설정의 fastcgi_pass를 새 소켓으로 전환하고 무중단 reload합니다.
sudo systemctl enable --now php8.3-fpm || sudo systemctl enable --now php-fpmsudo ls -la /run/php/php8.3-fpm.sock || sudo ls -la /run/php-fpm/www.socksudo nginx -t && sudo systemctl reload nginx- 신규 PHP-FPM 서비스가 active (running) 상태로 기동됨을 확인
- 소켓 파일 권한이 www-data 또는 nginx 사용자로 정상 생성됨을 확인
- nginx -t 성공 확인 후 reload로 무중단 트래픽 전환 완료
reload 명령은 기존 연결을 끊지 않고 새 연결부터 신규 PHP-FPM 소켓으로 라우팅하므로 서비스 중단이 발생하지 않습니다.
웹 요청 응답 및 PHP 런타임 보안 버전을 검증합니다.
PHP 런타임 보안 버전 대조 및 웹 응답 검증
HTTP 응답 헤더 및 실제 웹 요청을 호출하여 502/504 에러가 없는지 확인하고, FPM 에러 로그를 통해 신규 런타임의 정상 동작을 검증합니다.
curl -s -I http://127.0.0.1/ | grep -E '(HTTP/|Server|X-Powered-By)'sudo systemctl status php8.3-fpm --no-pager -l || sudo systemctl status php-fpm --no-pager -lsudo tail -n 30 /var/log/php8.3-fpm.log 2>/dev/null || sudo tail -n 30 /var/log/php-fpm/error.log- 웹 요청 시 502/504 없이 정상 HTTP 200 응답 확인
- FPM 서비스가 active 상태이며 에러 로그에 fatal 에러 없음 확인
- CLI 및 FPM이 모두 신규 보안 패치 버전으로 일치함을 확인
웹 서비스가 정상 응답하고 에러가 없다면 신규 취약점 패치 런타임으로 성공적으로 전환된 것입니다.
php.ini 위험 함수 비활성화 및 CGI 보안 설정을 적용합니다.
php.ini 위험 함수 비활성화 및 CGI 정보 노출 차단
원격 코드 실행(RCE) 및 CGI 인자 인젝션(CVE-2024-4577)을 원천 차단하기 위해 php.ini에서 위험 시스템 함수를 비활성화하고 버전 헤더 노출을 차단합니다.
sudoedit /etc/php/8.3/fpm/php.inisudo php-fpm8.3 -t 2>/dev/null && sudo systemctl reload php8.3-fpm || (sudo php-fpm -t && sudo systemctl reload php-fpm)php -r 'echo ini_get("disable_functions");' | grep -E "(exec|system|passthru)"expose_php = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
cgi.fix_pathinfo = 0
allow_url_fopen = Off
allow_url_include = Off
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,show_source- expose_php = Off로 HTTP 응답 헤더의 PHP 버전 노출 차단 확인
- cgi.fix_pathinfo = 0으로 FastCGI 경로 조작 취약점 차단 확인
- disable_functions에 system, exec 등 원격 실행 함수 비활성화 완료
위험 함수가 비활성화되면 악성 파일이 업로드되더라도 쉘 명령 실행을 통한 서버 장악이 차단됩니다.
장애 발생 시 안전하게 이전 FPM 버전으로 되돌리는 롤백 절차를 숙지합니다.
장애 발생 시 이전 PHP-FPM 서비스 복구 및 NGINX 소켓 원복
신규 PHP 버전과의 코드 비호환성이나 예기치 않은 오류 발생 시 NGINX의 fastcgi_pass 소켓을 이전 버전으로 원복하고 백업 설정을 복원합니다.
sudo nginx -t && sudo systemctl reload nginxsudo systemctl restart php8.2-fpm 2>/dev/null || sudo systemctl restart php-fpm
sudo systemctl status php8.2-fpm --no-pager 2>/dev/null || truesudo cp -p /etc/php/8.2/fpm/pool.d/www.conf.bak /etc/php/8.2/fpm/pool.d/www.conf 2>/dev/null || sudo cp -p /etc/php-fpm.d/www.conf.bak /etc/php-fpm.d/www.conf- NGINX fastcgi_pass가 이전 안정 소켓 경로로 원복되었음을 확인
- 이전 PHP-FPM 서비스가 정상 재기동되어 active 상태임을 확인
- 웹 요청이 이전 PHP 버전에서 정상 응답(HTTP 200)함을 확인
롤백 후 애플리케이션의 호환성 에러 로그(deprecated 함수, 라이브러리 충돌)를 분석하여 수정 후 재적용합니다.
서비스 정상 복구 확인 후 인시던트 로그를 정리합니다.
SECURITY CHECK
운영 전 마지막 보안 점검
- php.ini에서 expose_php = Off로 설정하여 HTTP 응답 헤더의 PHP 버전 노출 차단
- disable_functions에 system, exec, shell_exec 등 취약한 원격 실행 함수가 차단되었는지 확인
- cgi.fix_pathinfo = 0 설정으로 NGINX FastCGI 파일 경로 왜곡 취약점(CGI injection) 방지
- PHP-FPM 소켓 파일 권한이 0660으로 웹 서버 사용자(www-data/nginx)에게만 허용되었는지 확인
COMMON ERRORS
자주 막히는 지점
NGINX에서 502 Bad Gateway 발생
- 증상
- 웹 요청 시 NGINX 502 Bad Gateway 응답
- 가능한 원인
- NGINX fastcgi_pass 경로와 신규 PHP-FPM 소켓 파일 경로가 다르거나 FPM 서비스가 기동되지 않음
- 확인 순서
- sudo ls -la /run/php/ 소켓 파일 존재 여부와 NGINX 설정의 fastcgi_pass unix:/run/php/... 경로를 일치시킵니다.
필수 PHP 확장 모듈 누락으로 인한 500 내부 서버 오류
- 증상
- 로그에 Class 'PDO' not found 또는 Call to undefined function mb_strlen() 발생
- 가능한 원인
- 새 메이저/마이너 버전 설치 시 이전 버전에서 사용하던 extension 패키지가 누락됨
- 확인 순서
- php -m 목록을 대조하고 누락된 패키지(예: php8.3-mysql, php8.3-mbstring)를 추가 설치 후 FPM을 리로드합니다.
소켓 권한 오류 (Permission Denied)
- 증상
- NGINX 에러 로그에 connect() to unix:... failed (13: Permission denied) 기록
- 가능한 원인
- listen.owner / listen.group이 www-data(Ubuntu) 또는 nginx(Rocky)와 일치하지 않거나 listen.mode가 0660이 아님
- 확인 순서
- /etc/php/8.3/fpm/pool.d/www.conf에서 listen.owner, listen.group, listen.mode = 0660을 점검하고 FPM을 재기동합니다.
PRIMARY REFERENCES
공식 문서
- PHP Documentation · CGI and Command Injection Security
- PHP 8 ChangeLog and Security Releases
- NGINX ngx_http_fastcgi_module Reference
설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.