NGINX Troubleshoot (NGINX CA, F5N4) 학습 가이드
이 포스트에서는 NGINX 프로세스 제어 방법부터 기본적인 NGINX Troubleshoot, 그리고 TLS 보안 설정까지 다양한 NGINX 관련 문제를 해결하는 방법을 살펴보겠습니다. 웹 서버와 리버스 프록시로 널리 사용되는 NGINX는 높은 성능과 안정성으로 유명합니다. 하지만 모든 소프트웨어와 마찬가지로 NGINX도 때때로 문제가 발생할 수 있습니다.
목차
1. NGINX Troubleshoot: 프로세스 제어 및 재시작 방법
1-1. NGINX 프로세스에 시그널 전송하는 방법
1-2. 재시작(stop/start)과 재로드(reload)의 차이점
1-3. 설정 변경 전 테스트하는 방법
2. NGINX Troubleshoot: 기본적인 문제 해결 방법
2-1. 로그 해석을 통한 원인 분석
2-2. NGINX Troubleshoot: NGINX 시작 실패 원인 파악
2-3. HTTP 오류 코드 대응 전략
2-4. NGINX Troubleshoot: 응답 문제의 다양한 원인 분석
2-5. 다중 가상 호스트 및 포트 설정 문제 해결
2-6. location 우선순위 및 add_header 상속 문제 해결
2-7. 클라이언트 및 서버 연결 문제 해결
2-8. NGINX Troubleshoot: SELinux 관련 기본 이슈 해결
3. NGINX Troubleshoot: TLS 보안 설정 문제 해결
3-1. TLS 연결 오류 식별 및 분석
3-2. 인증서 오류 및 무효한 인증서 처리
1. NGINX Troubleshoot: 프로세스 제어 및 재시작 방법
NGINX는 마스터 프로세스와 워커 프로세스로 구성된 아키텍처를 가지고 있습니다. 마스터 프로세스는 설정을 읽고 평가하며, 워커 프로세스는 실제 요청을 처리합니다. 이러한 구조는 NGINX가 고성능을 유지하면서도 다운타임 없이 설정을 업데이트할 수 있게 해줍니다.
1-1. NGINX 프로세스에 시그널 전송하는 방법
NGINX 프로세스를 제어하는 가장 일반적인 방법은 시그널을 전송하는 것입니다. 이는 다음과 같은 방법으로 할 수 있습니다.
# PID 파일을 사용하여 시그널 전송
nginx -s signal
# 직접 마스터 프로세스에 시그널 전송
kill -s SIGNAL NGINX_MASTER_PID
주요 시그널에는 다음과 같은 것들이 있습니다:
stop: 빠르게 종료 (현재 요청 완료 대기 없음)quit: 정상 종료 (현재 요청 완료 대기)reload: 설정 파일 다시 로드reopen: 로그 파일 다시 열기
시스템 서비스로 설치된 경우, 다음 명령어도 사용할 수 있습니다.
systemctl start|stop|restart|reload nginx
service nginx start|stop|restart|reload
이러한 명령어는 내부적으로 적절한 시그널을 NGINX 프로세스에 전송합니다.
1-2. 재시작(stop/start)과 재로드(reload)의 차이점
NGINX를 재시작하는 방법에는 두 가지가 있으며, 각각 다른 상황에 적합합니다.
완전 재시작(stop/start):
nginx -s stop
nginx
또는
systemctl restart nginx
완전 재시작은 모든 NGINX 프로세스를 종료하고 다시 시작합니다. 이 방법은 바이너리 업그레이드나 근본적인 아키텍처 변경이 필요할 때 사용합니다. 단점은 재시작 과정에서 짧은 다운타임이 발생한다는 것입니다.
설정 Reload (reload):
nginx -s reload
또는
systemctl reload nginx
설정 재로드는 새 설정을 적용하면서도 서비스 중단 없이 진행됩니다. 마스터 프로세스는 새 설정 파일을 읽고 새 워커 프로세스를 시작합니다. 새 프로세스가 요청을 처리하기 시작하면 이전 프로세스는 점진적으로 종료됩니다. 이 방법은 대부분의 설정 변경에 권장됩니다.
1-3. 설정 변경 전 테스트하는 방법
NGINX 설정을 변경하기 전에, 구문 오류를 확인하는 것이 중요합니다. 잘못된 설정으로 서버가 시작되지 않는 상황을 방지할 수 있습니다.
# 설정 파일 테스트
nginx -t
# 특정 설정 파일 테스트
nginx -t -c /path/to/nginx.conf
이 명령은 설정 파일의 구문을 검사하고 오류가 있으면 표시합니다. 또한 설정 파일의 경로와 같은 유용한 정보도 출력합니다.
다음은 일반적인 성공 출력입니다.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
설정 테스트가 실패하면 오류 메시지가 표시되어 문제를 찾는 데 도움을 줍니다.
nginx: [emerg] unknown directive "srver" in /etc/nginx/nginx.conf:12
nginx: configuration file /etc/nginx/nginx.conf test failed
항상 설정 변경 후 재로드하기 전에 nginx -t 명령을 통해 테스트를 실행하는 습관을 들이는 것이 좋습니다.
2. 기본적인 문제 해결 방법
NGINX 문제를 효과적으로 해결하려면 체계적인 접근 방식이 필요합니다. 다음 섹션에서는 일반적인 문제를 진단하고 해결하는 방법을 살펴보겠습니다.
2-1. 로그 해석을 통한 원인 분석
NGINX는 두 가지 주요 로그 파일을 생성합니다:
- 액세스 로그: 서버에 대한 모든 요청을 기록합니다.
- 에러 로그: 오류 및 진단 정보를 기록합니다.
이러한 로그 파일은 일반적으로 다음 위치에 있습니다:
/var/log/nginx/access.log/var/log/nginx/error.log
하지만 설정에 따라 다른 위치에 있을 수 있습니다. 설정 파일에서 error_log 및 access_log 지시문을 확인하세요.
에러 로그는 문제 해결의 첫 번째 단계입니다. 다음은 일반적인 에러 로그 항목의 예입니다:
2025/04/10 12:34:56 [error] 12345#0: *67890 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "example.com"
이 로그 항목은 다음 정보를 제공합니다:
- 날짜 및 시간:
2025/04/10 12:34:56 - 로그 수준:
[error] - 프로세스 ID:
12345#0 - 연결 ID:
*67890 - 오류 메시지:
connect() failed (111: Connection refused) while connecting to upstream - 클라이언트 IP:
192.168.1.1 - 서버 이름:
example.com - 요청:
"GET / HTTP/1.1" - 업스트림 서버:
"http://127.0.0.1:8080/" - 호스트 헤더:
"example.com"
로그를 효과적으로 분석하려면:
- 관련 시간대의 로그 항목을 찾습니다.
- 오류 메시지의 의미를 이해합니다.
- 요청 정보와 클라이언트 정보를 검토합니다.
- 필요한 경우 디버그 로그 수준을 높입니다 (
error_log /var/log/nginx/error.log debug;)
2-2. NGINX Troubleshoot: NGINX 시작 실패 원인 파악
NGINX가 시작되지 않는 일반적인 원인은 다음과 같습니다.
1. 구문 오류: 설정 파일에 구문 오류가 있을 수 있습니다. nginx -t를 사용하여 확인하세요.
2. 포트 충돌: NGINX가 이미 사용 중인 포트를 사용하려고 할 수 있습니다.
# 현재 사용 중인 80 포트를 확인
sudo lsof -i:80
3. 권한 문제: NGINX가 필요한 파일이나 디렉토리에 접근할 수 없을 수 있습니다.
# NGINX 사용자에게 필요한 권한 부여
sudo chown -R nginx:nginx /var/www/html
4. 시스템 리소스 제한: 시스템 리소스(열린 파일 등)가 부족할 수 있습니다.
# 현재 제한 확인
ulimit -n
5. 로그 파일 또는 PID 파일 문제: 로그 파일 또는 PID 파일 디렉토리에 쓰기 권한이 없을 수 있습니다.
문제를 해결하려면 시스템 로그도 확인하세요.
journalctl -u nginx
2-3. HTTP 오류 코드 대응 전략
일반적인 HTTP 오류 코드와 그 원인 및 해결 방법.
400 Bad Request
- 원인: 클라이언트가 잘못된 요청을 보냄
- 해결: 클라이언트 요청 헤더 확인,
client_max_body_size값 조정
403 Forbidden
- 원인: 파일 권한 문제 또는 디렉토리 인덱싱 비활성화
- 해결: 파일 권한 확인, 필요한 경우 디렉토리 인덱싱 활성화
location /downloads/ {
autoindex on;
}
404 Not Found
- 원인: 요청된 파일이나 리소스가 없음
- 해결: 파일 경로 확인,
root및alias지시문 확인
# 올바른 root 경로 설정
root /var/www/correct-path;
502 Bad Gateway
- 원인: 업스트림 서버가 잘못된 응답을 반환하거나 연결할 수 없음
- 해결: 업스트림 서버 상태 확인, 연결 시간 초과 설정 조정
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
504 Gateway Timeout
- 원인: 업스트림 서버가 시간 내에 응답하지 않음
- 해결: 업스트림 서버 성능 최적화, 시간 초과 값 증가
2-4. NGINX Troubleshoot: 응답 문제의 다양한 원인 분석
NGINX 응답 문제의 일반적인 원인과 해결 방법:
1. 속도 저하:
- 원인: 정적 파일 캐싱 부족, 업스트림 서버 과부하
- 해결: 정적 콘텐츠 캐싱 활성화, 압축 사용, 업스트림 서버 성능 최적화
# 정적 파일 캐싱 및 압축
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
gzip on;
}
2. 간헐적인 연결 실패:
- 원인: 업스트림 서버 불안정, 네트워크 문제
- 해결: 업스트림 서버 상태 확인, 연결 풀링 최적화, 재시도 구성
# 업스트림 서버 상태 확인 및 재시도
upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com backup;
}
3. 불완전한 응답:
- 원인: 버퍼 크기 부족, 시간 초과 설정이 너무 짧음
- 해결: 버퍼 크기 및 시간 초과 설정 조정
proxy_buffers 16 16k;
proxy_buffer_size 16k;
proxy_busy_buffers_size 32k;
proxy_read_timeout 300s;
2-5. 다중 가상 호스트 및 포트 설정 문제 해결
NGINX에서 여러 가상 호스트나 포트를 설정할 때 흔히 발생하는 문제:
1. 가상 호스트 충돌:
- 원인: 여러 서버 블록이 동일한
server_name및listen지시문을 가짐 - 해결: 각 가상 호스트에 고유한
server_name또는listen값 할당
# 첫 번째 가상 호스트
server {
listen 80;
server_name example.com;
# ...
}
# 두 번째 가상 호스트
server {
listen 80;
server_name subdomain.example.com;
# ...
}
2. 기본 서버 선택:
- 문제: HTTP 호스트 헤더가 구성된 어떤
server_name과도 일치하지 않음 - 해결: 기본 서버 설정 정의
server {
listen 80 default_server;
server_name _;
return 444; # 일치하지 않는 호스트에 대한 연결 닫기
}
3. SSL/TLS 인증서 문제:
- 문제: 여러 HTTPS 가상 호스트에 대한 올바른 인증서 선택
- 해결: 각 가상 호스트의 포트와 인증서 구성 확인
# 첫 번째 SSL 가상 호스트
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/example.com.crt;
ssl_certificate_key /path/to/example.com.key;
# ...
}
# 두 번째 SSL 가상 호스트
server {
listen 443 ssl;
server_name subdomain.example.com;
ssl_certificate /path/to/subdomain.example.com.crt;
ssl_certificate_key /path/to/subdomain.example.com.key;
# ...
}
2-6. location 우선순위 및 add_header 상속 문제 해결
NGINX에서 location 블록의 우선순위와 add_header 지시문의 상속은 자주 혼란을 일으킵니다.
location 우선순위:
NGINX는 다음 순서로 location을 평가합니다(높은 우선순위에서 낮은 우선순위 순):
- 정확한 매치 (
=) - 접두사 매치, 정규식 아님 (
^~) - 정규식 매치 (
~또는~*) - 접두사 매치, 정규식 아님 (접두사 수정자 없음)
# 정확한 매치 (1순위)
location = /exact {
# ...
}
# 접두사 매치, 정규식 평가 중지 (2순위)
location ^~ /images/ {
# ...
}
# 대소문자 구분 정규식 매치 (3순위)
location ~ \.(gif|jpg|jpeg)$ {
# ...
}
# 대소문자 구분 없는 정규식 매치 (3순위)
location ~* \.(js|css)$ {
# ...
}
# 일반 접두사 매치 (4순위)
location /documents/ {
# ...
}
add_header 상속 문제:
add_header 지시문은 직계 자식 컨텍스트로 상속되지 않습니다. 대신, 하위 컨텍스트에 add_header 지시문이 하나라도 있으면 상위 컨텍스트의 모든 add_header 지시문이 무시됩니다.
문제를 해결하려면:
- 모든 필요한 헤더를 각 컨텍스트에 명시적으로 추가하거나,
include파일을 사용하여 일관성을 유지하세요:
# /etc/nginx/includes/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# nginx.conf
server {
include /etc/nginx/includes/security-headers.conf;
location / {
# 여기에 add_header가 없으면 서버 블록의 헤더가 상속됨
}
location /api/ {
# 여기에 add_header가 있으면 서버 블록의 헤더가 무시됨
include /etc/nginx/includes/security-headers.conf;
add_header Cache-Control "no-store" always;
}
}
2-7. 클라이언트 및 서버 연결 문제 해결
NGINX 연결 문제는 클라이언트 측과 서버 측 모두에서 발생할 수 있습니다.
클라이언트 연결 문제:
1. 연결 제한:
- 문제: 너무 많은 클라이언트가 동시에 연결 시도
- 해결: 연결 제한 매개변수 조정
# 연결 및 요청 제한 증가
worker_connections 4096;
worker_rlimit_nofile 20000;
2. 요청 크기 제한:
- 문제: 클라이언트가 너무 큰 요청 보냄
- 해결: 클라이언트 요청 크기 제한 증가
# 클라이언트 요청 크기 제한 조정
client_max_body_size 20M;
client_body_timeout 60s;
client_header_timeout 60s;
2-8. SELinux 관련 기본 이슈 해결
SELinux가 활성화된 시스템(Red Hat, CentOS, Fedora 등)에서는 NGINX에 추가적인 보안 제한이 적용됩니다. 이로 인해 권한이 올바르게 설정되어 있더라도 NGINX가 특정 파일이나 디렉토리에 접근하지 못할 수 있습니다.
일반적인 SELinux 관련 문제:
1. 파일 접근 문제:
- 증상: NGINX가 “Permission denied” 오류로 파일에 접근할 수 없음
- 해결: 적절한 SELinux 컨텍스트 설정
# NGINX가 접근할 수 있도록 파일 컨텍스트 설정
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/custom-path(/.*)?"
sudo restorecon -Rv /var/www/custom-path
2. 네트워크 연결 문제:
- 증상: NGINX가 특정 네트워크 포트에 바인딩할 수 없음
- 해결: 허용된 포트 확인 및 추가
# 허용된 HTTP 포트 확인
sudo semanage port -l | grep http_port_t
# 새 HTTP 포트 추가
sudo semanage port -a -t http_port_t -p tcp 8080
3. 업스트림 연결 문제:
- 증상: NGINX가 업스트림 서버에 연결할 수 없음
- 해결: NGINX에 네트워크 연결 권한 부여
4. 로그 파일 쓰기 문제:
- 증상: NGINX가 사용자 지정 로그 디렉토리에 쓸 수 없음
- 해결: 로그 디렉토리에 적절한 컨텍스트 설정
# 로그 디렉토리에 적절한 컨텍스트 설정
sudo semanage fcontext -a -t httpd_log_t "/var/log/nginx-custom(/.*)?"
sudo restorecon -Rv /var/log/nginx-custom
SELinux 문제를 디버깅하려면 감사 로그를 확인하세요.
sudo ausearch -m avc -ts recent | grep nginx
3. NGINX Troubleshoot: TLS 보안 설정 문제 해결
TLS 보안 설정은 NGINX 배포의 중요한 측면입니다. 많은 조직에서 HTTPS를 올바르게 구성하는 것은 필수적이지만, 몇 가지 일반적인 문제가 발생할 수 있습니다.
3-1. TLS 연결 오류 식별 및 분석
일반적인 TLS 연결 오류:
1. 핸드셰이크 실패:
- 증상: 클라이언트가 “핸드셰이크 실패” 오류를 보고함
- 원인: 지원되지 않는 TLS 버전, 암호화 불일치, 서버 설정 문제
- 해결: TLS 프로토콜 및 암호화 설정 최적화
# 최신 TLS 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5:!3DES;
ssl_prefer_server_ciphers on;
2. 성능 저하:
- 증상: TLS 연결이 너무 느림
- 원인: SSL 세션 캐시 부족, 비효율적인 암호화
- 해결: SSL 세션 캐싱 및 티켓 최적화
# SSL 세션 캐싱 최적화
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets on;
3. 서버 이름 불일치:
- 증상: 클라이언트가 “서버 이름 불일치” 오류를 보고함
- 원인: 인증서의 이름이 요청된 호스트 이름과 일치하지 않음
- 해결: 올바른 인증서 사용 또는 와일드카드 인증서 채택
# 와일드카드 인증서 사용 예
server {
listen 443 ssl;
server_name *.example.com;
ssl_certificate /path/to/wildcard.example.com.crt;
ssl_certificate_key /path/to/wildcard.example.com.key;
# ...
}
TLS 연결 문제를 진단하려면 디버그 모드에서 OpenSSL을 사용하여 연결을 테스트하세요.
openssl s_client -connect example.com:443 -servername example.com -debug
이 명령은 인증서 정보와 핸드셰이크 세부 정보를 포함한 상세한 연결 정보를 제공합니다.
3-2. 인증서 오류 및 무효한 인증서 처리
인증서 관련 일반적인 문제:
1. 자체 서명된 인증서:
- 문제: 클라이언트가 인증서를 신뢰하지 않음
- 해결: Let’s Encrypt와 같은 신뢰할 수 있는 인증 기관에서 인증서 획득 또는 클라이언트가 자체 서명된 인증서를 신뢰하도록 명시적으로 구성
2. 인증서 체인 불완전:
- 문제: 중간 인증서 누락
- 해결: 올바른 순서로 전체 인증서 체인 제공
# 전체 인증서 체인 제공
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
3. 만료된 인증서:
- 문제: 인증서가 만료됨
- 해결: 인증서 갱신 및 자동 갱신 설정
# Let's Encrypt 인증서 갱신
certbot renew
# 자동 갱신을 위한 cron 작업 설정
echo "0 3 * * * /usr/bin/certbot renew --quiet" | sudo tee -a /etc/crontab
4. 잘못된 인증서 권한:
- 문제: NGINX가 인증서 파일 읽기 권한 없음
- 해결: 적절한 파일 권한 설정
# 인증서 파일에 적절한 권한 설정
sudo chmod 644 /path/to/certificate.crt
sudo chmod 600 /path/to/private.key
sudo chown nginx:nginx /path/to/certificate.crt /path/to/private.key
5. 지원되지 않는 암호화 방식:
- 문제: 클라이언트와 서버 간 지원되는 공통 암호화 방식 없음
- 해결: 널리 지원되는 현대적인 암호화 방식 사용
# 현대적이고 호환성 있는 암호화 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
인증서 문제를 진단하는 유용한 명령어:
# 인증서 정보 확인
openssl x509 -in certificate.crt -text -noout
# 인증서 만료일 확인
openssl x509 -in certificate.crt -noout -dates
# 인증서와 키 일치 여부 확인
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
이 명령어들의 출력이 일치하면 인증서와 개인 키가 쌍으로 맞는 것입니다.
4. 결론
NGINX는 강력하고 유연한 웹 서버와 리버스 프록시 솔루션이지만, 모든 시스템과 마찬가지로 다양한 문제가 발생할 수 있습니다. 이 가이드에서 다룬 프로세스 제어 방법, 문제 해결 전략, TLS 설정 팁을 통해 더 효과적으로 NGINX를 관리하고 문제를 해결할 수 있기를 바랍니다.
효과적인 NGINX 관리를 위한 몇 가지 핵심 조언:
- 설정 변경 전에 항상
nginx -t로 구문을 테스트하세요. - 문제 해결에 로그를 효과적으로 활용하세요.
- 가능하면 설정을 재로드(reload)하고, 완전 재시작은 필요한 경우에만 사용하세요.
- TLS 설정을 정기적으로 검토하고 업데이트하여 보안을 유지하세요.
- 성능 병목 현상을 모니터링하고 식별하기 위한 모니터링 솔루션을 구현하세요.
NGINX는 웹 서버와 프록시 서버 시장에서 계속해서 인기를 얻고 있으며, 이러한 기술과 지식을 마스터하면 현대적인 웹 인프라를 효과적으로 관리할 수 있습니다.
NGINX CA에 대한 다양한 학습가이드는 아래에서 확인할 수 있습니다.
1. NGINX Management (NGINX CA, F5N1) 학습 가이드
2. NGINX Configuration: Knowledge (NGINX CA, F5N2) 학습 가이드
3. NGINX Configuration: Demonstrate (NGINX CA, F5N3) 학습 가이드
4. NGINX Troubleshoot (NGINX CA, F5N4) 학습 가이드