Nginx와 PHP-FPM을 연동해서 웹 서버를 구동할 때 브라우저에 502 Bad Gateway 에러가 발생하는 경험을 해봤을 것이다. 웹 서버 프로세스는 정상적으로 실행 중인데 Nginx 에러 로그를 확인해보면 connect() to unix:... failed (13: Permission denied) 메시지가 찍혀 답답했던 경험이 있을 것이다. 다만 정확한 원인이나 해결책을 몰라 인터넷에 나오는 대로 소켓 파일이나 디렉터리 권한을 777로 무작정 풀어버리는 경우가 많다. 이번에는 이 에러가 왜 발생하는지, 안전하고 올바른 권한 설정 방법은 무엇인지, SELinux 환경에서의 해결책까지 완벽하게 정리해서 소개하겠다.
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), 소유자 불일치 |
문제 해결의 첫 단추는 로그 확인이다. 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로 되어 있거나 일반 유저 권한이 막혀 있다면 에러가 터지게 된다.
이 에러를 해결하는 가장 올바른 방법은 PHP-FPM의 Pool 설정 파일에서 소켓 생성 시 부여되는 소유자와 권한을 Nginx 웹 서버 실행 계정에 맞추는 것이다.
Ubuntu 계열은 /etc/php/8.2/fpm/pool.d/www.conf, CentOS 계열은 /etc/php-fpm.d/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 에러가 깔끔하게 사라진 것을 볼 수 있다.
CentOS, RHEL, AlmaLinux 같은 RedHat 계열 OS를 사용하는 환경에서는 PHP-FPM 설정을 올바르게 맞춰도 여전히 13: Permission denied 에러가 발생할 수 있다. 이는 SELinux(Security-Enhanced Linux) 보안 정책이 Nginx 프로세스의 소켓 접근을 차단하고 있기 때문이다.
✗ 잘못된 대처: 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.sockSELinux 환경에서는 위와 같이 Nginx 보안 맥락(Context)에 소켓 파일 접근 권한을 명시적으로 추가해주는 것이 가장 안전하고 올바른 해결법이다.
Nginx 502 Bad Gateway와 함께 나타나는 connect() failed (13: Permission denied) 에러는 웹 서버 계정과 PHP-FPM 소켓 파일 간의 권한 불일치에서 비롯되는 대표적인 연동 문제다. 무작정 chmod 777을 적용하거나 보안 옵션을 꺼버리는 단기 처방은 더 큰 보안 문제로 이어질 수 있다.
PHP-FPM 소켓 권한 설정은 올바른 웹 서비스 구축을 위한 기본적인 보안 프로세스다. 무심코 지나치기 쉬운 소켓 권한과 웹 서버 프로세스 계정 점검이라는 작은 습관이 모여서 안정적이고 견고한 서버 환경을 만든다는 점을 잊지 말자. 이 글의 PHP-FPM pool 설정 가이드와 SELinux 대처법을 참고해 서버 설정을 점검하면, 502 Bad Gateway 에러를 근본적으로 해결하고 원활하게 웹 서비스를 운영할 수 있을 것이다.