Nginx와 PHP-FPM을 연동해서 웹 서버를 구동할 때 브라우저에 502 Bad Gateway 에러가 발생하는 경험을 해봤을 것이다. 웹 서버 프로세스는 정상적으로 실행 중인데 Nginx 에러 로그를 확인해보면 connect() to unix:... failed (13: Permission denied) 메시지가 찍혀 답답했던 경험이 있을 것이다. 다만 정확한 원인이나 해결책을 몰라 인터넷에 나오는 대로 소켓 파일이나 디렉터리 권한을 777로 무작정 풀어버리는 경우가 많다. 이번에는 이 에러가 왜 발생하는지, 안전하고 올바른 권한 설정 방법은 무엇인지, SELinux 환경에서의 해결책까지 완벽하게 정리해서 소개하겠다.

 

1. Nginx와 PHP-FPM 소켓 통신 문제의 원인 이해하기

Nginx는 PHP 코드를 직접 해석하지 못하므로, FastCGI 프로토콜을 통해 백엔드의 PHP-FPM 프로세스로 요청을 전달한다. 이때 통신 방식은 크게 TCP 소켓(127.0.0.1:9000) 방식과 유닉스 도메인 소켓(Unix Domain Socket, .sock 파일) 방식 두 가지가 있다.

유닉스 도메인 소켓은 네트워크 오버헤드가 없어 처리 속도가 빠르기 때문에 실무 서비스 환경에서 많이 사용된다. 하지만 이 방식은 파일 시스템에 실제 소켓 파일이 생성되므로 리눅스 파일 권한의 영향을 직접 받는다. Nginx의 워커 프로세스(Worker Process) 계정이 PHP-FPM 소켓 파일에 접근하여 읽기 및 쓰기를 할 수 있는 권한이 없으면 13: Permission denied 에러가 발생하며 502 Bad Gateway를 반환한다.

통신 방식장점단점흔한 에러 원인
TCP Socket (127.0.0.1:9000)설정이 간단하고 서버 분산 가능네트워크 인터페이스를 거쳐 성능 약간 저하포트 충돌, 방화벽 차단
Unix Domain Socket (.sock)메모리 내부 통신으로 속도가 매우 빠름단일 서버 내에서만 사용 가능파일 권한(Permission denied), 소유자 불일치

 

2. Nginx error.log 확인 및 소켓 소유권 점검

문제 해결의 첫 단추는 로그 확인이다. Ubuntu/Debian 기준 /var/log/nginx/error.log 파일이나 CentOS/RHEL 기준 동일 디렉터리의 에러 로그를 열어보면 다음과 같은 형태의 로그를 발견할 수 있다.

2026/03/30 10:15:22 [crit] 1234#1234: *1 connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"

위 메시지는 Nginx가 /run/php/php8.2-fpm.sock 파일에 접속하려 했으나 권한 거부(Permission denied)로 실패했음을 명확히 보여준다. 이 경우 먼저 Nginx 실행 유저와 소켓 파일의 소유자를 확인해야 한다.

# Nginx 워커 프로세스 실행 유저 확인
ps aux | grep nginx

# 소켓 파일 소유자 및 권한 확인
ls -la /run/php/php8.2-fpm.sock

만약 Nginx 프로세스는 www-data 계정으로 실행 중인데, 소켓 파일 소유자가 root나 apache로 되어 있거나 일반 유저 권한이 막혀 있다면 에러가 터지게 된다.

 

3. PHP-FPM pool 설정 수정을 통한 권한 해결

이 에러를 해결하는 가장 올바른 방법은 PHP-FPM의 Pool 설정 파일에서 소켓 생성 시 부여되는 소유자와 권한을 Nginx 웹 서버 실행 계정에 맞추는 것이다.

Ubuntu 계열은 /etc/php/8.2/fpm/pool.d/www.conf, CentOS 계열은 /etc/php-fpm.d/www.conf 위치에 해당 설정 파일이 존재한다.

 

설정 파일 수정 (www.conf)

✗ 잘못된 설정 (소켓 소유자 설정 누락 또는 웹 서버 계정과 불일치)

; listen.owner 및 listen.group이 주석 처리되어 있거나 다른 계정으로 지정된 경우
listen = /run/php/php8.2-fpm.sock
;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0660

✓ 올바른 설정 (Nginx 실행 계정에 맞게 listen 설정 명시)

listen = /run/php/php8.2-fpm.sock

; Nginx 실행 유저가 www-data인 경우 (CentOS는 nginx)
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

설정을 변경한 후에는 반드시 PHP-FPM 서비스와 Nginx 서비스를 재시작해야 적용된다.

# PHP-FPM 및 Nginx 재시작
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx

재시작 후 소켓 파일의 권한을 다시 확인해 보면, listen.owner 지정에 따라 소유권이 정상적으로 변경되어 502 에러가 깔끔하게 사라진 것을 볼 수 있다.

 

4. SELinux 보안 환경에서의 흔한 실수와 올바른 대처

CentOS, RHEL, AlmaLinux 같은 RedHat 계열 OS를 사용하는 환경에서는 PHP-FPM 설정을 올바르게 맞춰도 여전히 13: Permission denied 에러가 발생할 수 있다. 이는 SELinux(Security-Enhanced Linux) 보안 정책이 Nginx 프로세스의 소켓 접근을 차단하고 있기 때문이다.

 

잘못된 대처법 vs 올바른 대처법

✗ 잘못된 대처: SELinux 완전히 끄기 또는 소켓 디렉터리 777 권한 부여

# 서버 전체 보안을 해치는 위험한 명령
sudo setenforce 0
sudo chmod -R 777 /run/php/

소켓 권한을 chmod 777로 변경하더라도 프로세스 재시작 시 원래대로 원복될 뿐만 아니라 보안상 심각한 허점이 생긴다. 또한 SELinux를 아예 비활성화하는 것도 운영 서버에서는 피해야 할 행동이다.

✓ 올바른 대처: SELinux 정책 허용 설정 및 컨텍스트 변경

# Nginx가 네트워크 및 유닉스 소켓 통신을 할 수 있도록 부울값 설정
sudo setsebool -P httpd_can_network_connect 1

# 또는 소켓 파일 위치에 웹 서버 읽기/쓰기 보안 컨텍스트 부여
sudo chcon -t httpd_sys_rw_content_t /run/php/php8.2-fpm.sock

SELinux 환경에서는 위와 같이 Nginx 보안 맥락(Context)에 소켓 파일 접근 권한을 명시적으로 추가해주는 것이 가장 안전하고 올바른 해결법이다.

 

5. 핵심 요약 및 마무리

Nginx 502 Bad Gateway와 함께 나타나는 connect() failed (13: Permission denied) 에러는 웹 서버 계정과 PHP-FPM 소켓 파일 간의 권한 불일치에서 비롯되는 대표적인 연동 문제다. 무작정 chmod 777을 적용하거나 보안 옵션을 꺼버리는 단기 처방은 더 큰 보안 문제로 이어질 수 있다.

PHP-FPM 소켓 권한 설정은 올바른 웹 서비스 구축을 위한 기본적인 보안 프로세스다. 무심코 지나치기 쉬운 소켓 권한과 웹 서버 프로세스 계정 점검이라는 작은 습관이 모여서 안정적이고 견고한 서버 환경을 만든다는 점을 잊지 말자. 이 글의 PHP-FPM pool 설정 가이드와 SELinux 대처법을 참고해 서버 설정을 점검하면, 502 Bad Gateway 에러를 근본적으로 해결하고 원활하게 웹 서비스를 운영할 수 있을 것이다.