모든 배포 가이드 배포

curl, Git, Python, Node.js에서 SSL 인증서 오류 해결하기

SSL certificate problem: unable to get local issuer certificate 오류(및 그 변형)는 가장 흔한 개발 환경 문제 중 하나입니다. 도구가 서버의 인증서 체인을 검증할 수 없다는 것을 의미합니다 — 보통 시스템의 CA 루트 인증서가 오래되었거나 누락되었기 때문입니다.

이 가이드에서는 -k / --insecure 같은 보안을 비활성화하는 임시방편이 아닌 올바른 해결 방법을 다룹니다.

근본 원인

도구들은 CA 번들 — 신뢰할 수 있는 루트 인증서가 포함된 파일 — 을 기준으로 SSL 인증서를 검증합니다. 이 번들이 오래되었거나, 누락되었거나, 서버의 체인이 불완전하면 검증이 실패합니다.

도구 → "이 인증서가 내가 신뢰하는 CA에 의해 서명되었나?"
CA 번들 → "해당 CA의 루트 인증서가 없습니다"
→ ERROR: unable to get local issuer certificate

curl

오류

curl: (60) SSL certificate problem: unable to get local issuer certificate

해결 1: CA 인증서 업데이트 (올바른 방법)

# Debian/Ubuntu
sudo apt update && sudo apt install ca-certificates
sudo update-ca-certificates

# CentOS/RHEL
sudo yum update ca-certificates

# macOS (Homebrew curl)
brew install ca-certificates

해결 2: CA 번들 경로 지정

curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com

해결 3: 환경 변수 설정

export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

이렇게 하지 마세요 (테스트 목적 외)

curl -k https://example.com  # 모든 인증서 검증을 비활성화합니다

Git

오류

fatal: unable to access 'https://...': SSL certificate problem: unable to get local issuer certificate

해결 1: CA 인증서 업데이트 (curl과 동일)

sudo apt update && sudo apt install ca-certificates

해결 2: Git이 올바른 CA 번들을 가리키도록 설정

git config --global http.sslCAInfo /etc/ssl/certs/ca-certificates.crt

해결 3: Windows (Git for Windows)

Git for Windows는 자체 CA 인증서를 번들로 포함합니다. Git을 최신 버전으로 업데이트하거나:

git config --global http.sslBackend schannel

이렇게 하면 Git이 번들된 인증서 대신 Windows 내장 인증서 저장소를 사용합니다.

프로덕션에서는 이렇게 하지 마세요

git config --global http.sslVerify false  # Git의 모든 SSL 검증을 비활성화합니다

Python (requests / pip)

오류 (requests)

requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]

오류 (pip)

pip install ... Could not fetch URL https://...: connection error: [SSL: CERTIFICATE_VERIFY_FAILED]

해결 1: certifi 업데이트 (Python의 CA 번들)

pip install --upgrade certifi

Python의 requests 라이브러리는 시스템 저장소가 아닌 certifi 패키지를 CA 인증서에 사용합니다.

해결 2: 시스템 CA 번들 지정

import requests
response = requests.get('https://example.com', verify='/etc/ssl/certs/ca-certificates.crt')

또는 환경 변수 사용:

export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

해결 3: macOS Python (일반적인 문제)

macOS Python은 설치 후 인증서 저장소가 비어 있는 경우가 많습니다. 실행:

# Python 설치 위치 확인
python3 -c "import ssl; print(ssl.get_default_verify_paths())"

# 인증서 설치 (python.org에서 받은 macOS Python)
/Applications/Python\ 3.x/Install\ Certificates.command

pip 전용 해결

pip install --upgrade pip
pip config set global.cert /etc/ssl/certs/ca-certificates.crt

Node.js

오류

Error: unable to get local issuer certificate
  code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'

해결 1: NODE_EXTRA_CA_CERTS 설정

export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt

Node의 내장 번들을 대체하지 않고 추가 CA를 등록합니다.

해결 2: 개발 환경의 자체 서명 인증서용

// Only for development — adds a specific CA
const https = require('https');
const fs = require('fs');

const agent = new https.Agent({
  ca: fs.readFileSync('/path/to/custom-ca.pem'),
});

fetch('https://internal-service.local', { agent });

프로덕션에서는 이렇게 하지 마세요

export NODE_TLS_REJECT_UNAUTHORIZED=0  # 모든 SSL 검증을 비활성화합니다

기업 프록시 / 엔터프라이즈 환경

많은 기업 네트워크는 내부 CA로 트래픽에 재서명하는 TLS 검사 프록시를 사용합니다. 도구들이 이 내부 CA를 신뢰하지 않습니다.

해결: IT 부서에서 기업 CA 인증서를 받아 추가합니다:

# 시스템 전체 (Debian/Ubuntu)
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# Python
export REQUESTS_CA_BUNDLE=/path/to/corporate-ca-bundle.pem

# Node.js
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem

# Git
git config --global http.sslCAInfo /path/to/corporate-ca-bundle.pem

Docker 컨테이너

Docker 이미지는 CA 번들이 오래된 경우가 많습니다. 해결:

# Debian-based
RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates

# Alpine
RUN apk add --no-cache ca-certificates

빠른 진단

# openssl로 SSL 연결 테스트
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | grep "Verify return code"
# "0 (ok)" = 체인은 정상, 도구의 CA 번들이 문제
# "21 (unable to verify)" = 서버의 체인이 불완전

# 시스템이 사용하는 CA 번들 확인
python3 -c "import certifi; print(certifi.where())"
curl-config --ca 2>/dev/null || echo "Check /etc/ssl/certs/"

자주 묻는 질문

브라우저에서는 되는데 curl/Python에서는 왜 안 되나요?

브라우저는 자체 CA 저장소를 관리합니다(브라우저와 함께 업데이트). CLI 도구들은 시스템의 CA 번들이나 자체 번들을 사용합니다(Python은 certifi, Git for Windows는 자체 번들). 시스템 번들이 오래되면 CLI 도구는 실패하는 반면 브라우저는 정상 작동합니다.

SSL 검증을 비활성화해도 안전한가요?

빠른 테스트용으로: 서버 신원을 검증하지 않는다는 것을 이해한다면 가능합니다. 프로덕션 코드나 CI/CD에서는: 절대 안 됩니다. 검증 비활성화는 중간자 공격에 노출됩니다. 항상 근본 원인(CA 번들 업데이트 또는 서버 체인 수정)을 해결하세요.

서버 인증서는 정상인데 여전히 오류가 발생합니다

도구가 트래픽을 재서명하는 프록시를 통해 연결하고 있는지 확인하세요. 기업 네트워크, 일부 VPN, 바이러스 백신 소프트웨어가 이런 작업을 합니다. 프록시의 CA가 도구의 신뢰 저장소에 없는 것입니다.

관련 기사

SSL 및 인증서 2026-05-07
인증서 신뢰 체인 설명
브라우저가 루트 CA에서 중간 CA를 거쳐 인증서까지 체인을 통해 SSL 인증서를 확인하는 방법. 체인 순서가 왜 중요하고 '인증서를 신뢰할 수 없음' 오류를 수정하는 방법을 알아보세요.
SSL 및 인증서 2026-05-08
자체 서명 vs CA 서명 SSL 인증서
자체 서명 인증서는 브라우저 경고를 발생시킵니다. CA 서명 인증서는 자동으로 신뢰됩니다. 각각이 적합한 경우, 생성 방법, 무료 CA 인증서가 프로덕션에서 자체 서명을 대체한 이유를 알아보세요.
배포 2026-05-08
로컬 개발을 위한 localhost HTTPS 인증서
mkcert을 사용하여 localhost에서 신뢰할 수 있는 HTTPS를 설정합니다 - 브라우저 경고 없이. mkcert 설정, 자체 서명 인증서, Let's Encrypt가 localhost에 인증서를 발급할 수 없는 이유를 다룹니다.
SSL 및 인증서 2026-05-08
SSL 인증서를 위한 OpenSSL 명령어 치트시트
가장 일반적인 OpenSSL 명령어 빠른 참조: 인증서 만료 확인, 체인 검증, 키 생성, 형식 변환, TLS 연결 디버그.
브라우저에서 무료 SSL 인증서 받기
설치 불필요, 계정 불필요. 개인키는 항상 기기에 남습니다.
인증서 발급