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_logaccess_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"

로그를 효과적으로 분석하려면:

  1. 관련 시간대의 로그 항목을 찾습니다.
  2. 오류 메시지의 의미를 이해합니다.
  3. 요청 정보와 클라이언트 정보를 검토합니다.
  4. 필요한 경우 디버그 로그 수준을 높입니다 (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

  • 원인: 요청된 파일이나 리소스가 없음
  • 해결: 파일 경로 확인, rootalias 지시문 확인
# 올바른 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_namelisten 지시문을 가짐
  • 해결: 각 가상 호스트에 고유한 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. 정확한 매치 (=)
  2. 접두사 매치, 정규식 아님 (^~)
  3. 정규식 매치 (~ 또는 ~*)
  4. 접두사 매치, 정규식 아님 (접두사 수정자 없음)
# 정확한 매치 (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 지시문이 무시됩니다.

문제를 해결하려면:

  1. 모든 필요한 헤더를 각 컨텍스트에 명시적으로 추가하거나,
  2. 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 관리를 위한 몇 가지 핵심 조언:

      1. 설정 변경 전에 항상 nginx -t로 구문을 테스트하세요.
      2. 문제 해결에 로그를 효과적으로 활용하세요.
      3. 가능하면 설정을 재로드(reload)하고, 완전 재시작은 필요한 경우에만 사용하세요.
      4. TLS 설정을 정기적으로 검토하고 업데이트하여 보안을 유지하세요.
      5. 성능 병목 현상을 모니터링하고 식별하기 위한 모니터링 솔루션을 구현하세요.

      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) 학습 가이드

        NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

        * indicates required