Develope/Node.js

Node.js에서 인증서 오류가 나는 이유와 확인 방법

oper0116 2026. 4. 15. 21:18
반응형

1. 개요

Node.js에서 HTTPS 요청을 보내다 보면
인증서 관련 오류를 만나는 경우가 있다.

대표적으로 다음과 같은 메시지다.

  • UNABLE_TO_VERIFY_LEAF_SIGNATURE
  • SELF_SIGNED_CERT_IN_CHAIN
  • DEPTH_ZERO_SELF_SIGNED_CERT
  • CERT_HAS_EXPIRED
  • ERR_TLS_CERT_ALTNAME_INVALID

이런 오류를 처음 보면
"서버가 이상한가?" 정도로 생각하기 쉽다.

하지만 실제로는
인증서 체인, 만료, 호스트명, CA 신뢰 목록 등
여러 원인으로 발생할 수 있다.

이 글에서는 Node.js에서 인증서 오류가 나는 이유
어떻게 확인해야 하는지 정리한다.


2. 왜 인증서 오류가 발생하는가

HTTPS 연결에서는
단순히 암호화만 하는 것이 아니다.

Node.js는 서버가 보낸 인증서를 보고
다음 항목을 검증한다.

  • 신뢰할 수 있는 CA가 발급했는가
  • 인증서 체인이 올바른가
  • 인증서가 만료되지 않았는가
  • 접속한 도메인과 인증서의 호스트명이 일치하는가

즉, 인증서 오류는
대부분 이 검증 과정 중 하나가 실패했다는 의미다.


3. 가장 자주 보는 오류 1: UNABLE_TO_VERIFY_LEAF_SIGNATURE

이 오류는 보통
서버 인증서를 신뢰 체인 끝까지 검증하지 못할 때 발생한다.

대표적인 원인은 다음과 같다.

  • Intermediate 인증서 누락
  • 신뢰하지 않는 CA 사용
  • 사설 인증서 체인 문제

즉, 서버 인증서 자체는 있어도
그 인증서를 "누가 보증하는지"를 끝까지 따라가지 못하는 상황이다.

확인할 것

  • 서버가 Intermediate 인증서를 함께 보내는가
  • 사용하는 CA가 Node.js에서 신뢰되는가
  • 사내 프록시나 보안 장비가 인증서를 바꾸고 있지는 않은가

4. 가장 자주 보는 오류 2: SELF_SIGNED_CERT_IN_CHAIN

이 오류는 인증서 체인 안에
신뢰되지 않는 self-signed 인증서가 포함되어 있을 때 발생한다.

주로 다음과 같은 상황에서 나타난다.

  • 사내망 프록시가 자체 인증서를 끼워 넣는 경우
  • 개발 환경에서 self-signed 인증서를 사용하는 경우
  • 내부 서비스가 사설 CA를 사용하는 경우

즉, 인증서가 형식상 잘못된 것이 아니라
Node.js가 기본적으로 신뢰하지 않는 인증서라는 의미다.

확인할 것

  • 사내 프록시 인증서를 사용 중인가
  • 로컬/개발 서버에서 self-signed 인증서를 쓰고 있는가
  • 별도 CA 등록이 필요한 환경인가

5. 가장 자주 보는 오류 3: DEPTH_ZERO_SELF_SIGNED_CERT

이 오류는 서버가 self-signed 인증서를 직접 사용하고 있을 때 자주 발생한다.

즉, 인증서 체인을 따라 올라갈 CA가 없고,
서버 인증서 자신이 곧 서명자 역할까지 하고 있는 경우다.

이 상황은 로컬 개발에서는 흔하지만,
기본 설정의 Node.js에서는 신뢰되지 않는다.

확인할 것

  • 개발용 인증서인가
  • 운영 환경에서도 self-signed 인증서를 쓰고 있지는 않은가
  • 테스트 환경에서만 예외 처리가 필요한가

6. 가장 자주 보는 오류 4: CERT_HAS_EXPIRED

이 오류는 비교적 단순하다.

인증서의 유효 기간이 끝났다는 뜻이다.

대표적인 원인은 다음과 같다.

  • 서버 인증서 만료
  • Intermediate 인증서 만료
  • 시스템 시간 문제

겉으로는 "서버는 잘 열리는데 Node.js만 실패한다"처럼 보일 수 있지만,
실제로는 인증서 만료가 원인인 경우가 많다.

확인할 것

  • 서버 인증서 만료일
  • Intermediate 인증서 만료일
  • 서버와 클라이언트 시스템 시간이 정확한가

7. 가장 자주 보는 오류 5: ERR_TLS_CERT_ALTNAME_INVALID

이 오류는 도메인과 인증서 대상이 맞지 않을 때 발생한다.

예를 들어:

  • api.example.com에 접속했는데
  • 인증서에는 www.example.com만 포함된 경우

이 경우 인증서는 유효할 수 있어도
현재 접속 대상과 일치하지 않기 때문에 실패한다.

요즘은 보통 인증서의 SAN(Subject Alternative Name)을 기준으로 검증한다.

확인할 것

  • 접속 중인 도메인이 무엇인가
  • 인증서 SAN에 해당 도메인이 포함되어 있는가
  • 와일드카드 인증서 범위가 맞는가

8. 로컬에서는 되는데 서버에서만 실패하는 이유

실무에서 가장 헷갈리는 상황 중 하나다.

로컬에서는 정상인데
배포 서버에서만 인증서 오류가 나는 경우가 있다.

대표적인 이유는 다음과 같다.

  • 운영 서버의 CA 신뢰 목록 차이
  • 사내 네트워크 프록시 영향
  • 컨테이너 이미지에 루트 인증서가 부족한 경우
  • Node.js 버전 또는 OpenSSL 환경 차이

즉, 같은 코드여도
실행 환경이 다르면 인증서 검증 결과가 달라질 수 있다.


9. 인증서 오류를 확인할 때 가장 먼저 볼 것

인증서 오류를 만나면
다음 순서로 확인하는 것이 좋다.

  1. 인증서가 만료되었는가
  2. 접속 도메인과 SAN이 일치하는가
  3. Intermediate 인증서가 누락되지 않았는가
  4. 신뢰하지 않는 CA 또는 self-signed 인증서인가
  5. 실행 환경의 CA 저장소가 충분한가

즉, 오류 메시지만 보지 말고
검증 단계별로 확인해야 한다.


10. Node.js에서 기본 HTTPS 요청 예시

const https = require("https");

https.get("https://example.com", (res) => {
  console.log(res.statusCode);
}).on("error", (err) => {
  console.error(err);
});

이 코드는 단순하지만,
연결 과정에서 TLS 핸드셰이크와 인증서 검증이 함께 수행된다.

즉, 요청이 실패했다면
단순한 네트워크 오류가 아니라
인증서 검증 실패일 수도 있다.


11. 무엇을 확인하면 좋을까

실제 확인 포인트는 크게 네 가지다.

1. 인증서 만료일

  • 서버 인증서가 만료되지 않았는가
  • 중간 인증서도 만료되지 않았는가

2. 도메인 일치 여부

  • 현재 접속 URL과 SAN이 일치하는가

3. 인증서 체인

  • Intermediate 인증서가 빠져 있지 않은가
  • 서버가 체인을 올바르게 전달하는가

4. 신뢰할 수 있는 CA인가

  • 사설 CA 또는 self-signed 인증서인가
  • 실행 환경이 그 CA를 신뢰하는가

12. rejectUnauthorized: false로 넘기면 안 되는 이유

개발 중에는 아래처럼 우회하는 경우가 있다.

const agent = new https.Agent({
  rejectUnauthorized: false,
});

이렇게 하면 연결은 될 수 있다.

하지만 이는 문제 해결이 아니라
인증서 검증 자체를 끄는 것이다.

즉, 상대 서버가 진짜인지 확인하지 않고 통신하게 된다.

운영 환경에서는 매우 위험하다.

👉 인증서 오류의 핵심은
"어떻게 우회할까"가 아니라
"왜 검증이 실패했는가"를 찾는 것이다.


13. 실무에서 자주 하는 실수

인증서 오류를 다룰 때 자주 하는 실수는 다음과 같다.

  • 서버 인증서만 보고 Intermediate 인증서를 확인하지 않음
  • 도메인 불일치를 놓침
  • 로컬 환경에서만 테스트하고 배포 서버 차이를 보지 않음
  • 사내 프록시가 인증서를 바꾸는 상황을 놓침
  • rejectUnauthorized: false로 임시 처리한 뒤 그대로 배포함

즉, 인증서 오류는
단순한 코드 문제가 아니라
런타임 환경과 신뢰 체인 전체를 함께 봐야 하는 문제다.


14. 정리

  • Node.js 인증서 오류는 대부분 TLS 검증 실패에서 발생한다
  • 대표 원인은 체인 문제, 만료, 도메인 불일치, self-signed 인증서다
  • 로컬과 운영 환경의 CA 신뢰 목록 차이도 중요한 원인이다
  • 오류 메시지에 따라 확인 포인트가 조금씩 다르다
  • 우회보다 원인 파악이 먼저다

결국 핵심은
"서버 인증서가 있는가"가 아니라
"그 인증서를 지금 환경에서 신뢰할 수 있는가"다.


15. 결론

Node.js에서 인증서 오류가 나는 이유는
생각보다 다양하다.

하지만 대부분은 몇 가지 범주로 정리할 수 있다.

  • 신뢰 체인 문제
  • 만료 문제
  • 도메인 불일치
  • self-signed 또는 사설 CA 문제

이 흐름을 이해하고 나면
에러 메시지를 봤을 때도
어디부터 확인해야 할지 훨씬 명확해진다.

특히 실무에서는
우회 설정을 넣기보다
인증서 검증이 어떤 단계에서 실패했는지 파악하는 것이 더 중요하다.


반응형