김현우
  • 리눅스 한 학기 살기 - 8주차
    2025년 05월 01일 01시 22분 37초에 업로드 된 글입니다.
    작성자: kugorang

    TL;DR — 3줄 핵심 요약

    • 문제: curl이나 docker를 설치할 때 ca-certificates가 함께 설치되는데, 이 패키지가 무엇을 하는지 모르면 "인증서 오류"가 났을 때 원인을 찾을 수 없다.

    • 기술/원인: HTTPS 통신은 서버가 보낸 인증서의 서명을 확인하는 것에서 시작한다. 그 서명을 검증하려면 "이 기관은 믿어도 된다"는 루트 인증서 목록이 필요한데, ca-certificates가 그 목록을 /usr/share/ca-certificates에 넣고 /etc/ssl/certs/ca-certificates.crt 하나로 묶어 준다.

    • 해결/인사이트: 사내 CA처럼 직접 만든 인증서는 /usr/local/share/ca-certificates에 .crt로 넣고 update-ca-certificates를 실행하면 된다. 브라우저는 자체 저장소를 쓰므로 시스템 설정이 자동 적용되지 않는다(p11-kit으로 통합 가능).

    인증서 검증이 필요한 이유

    든-든

    HTTPS로 연결할 때 서버는 인증서를 보낸다. 인증서에는 서버의 공개 키와 도메인, 그리고 그것을 발급한 기관의 서명이 들어 있다. 클라이언트는 그 서명을 검증해 "연결한 상대가 진짜 그 도메인의 서버인지"를 확인한다.

    검증은 사슬로 이어진다. 서버 인증서는 중간 CA가 서명하고, 중간 CA는 루트 CA가 서명한다. 클라이언트는 루트 CA의 공개 키를 이미 가지고 있어야 사슬 끝을 확인할 수 있다. ca-certificates는 그 루트 인증서 묶음이다.

    패키지가 설치하는 것

    • /usr/share/ca-certificates/: Mozilla가 관리하는 목록을 기반으로 한 루트 인증서. 패키지 관리자가 관리하므로 직접 고치지 않는다.
    • /etc/ca-certificates.conf: 그중 어떤 인증서를 신뢰할지 적은 목록. 줄 앞에 ! 를 붙이면 비활성화된다.
    • /usr/local/share/ca-certificates/: 관리자가 직접 추가한 인증서. 여기 있는 파일은 자동으로 신뢰된다.
    • /etc/ssl/certs/: 인증서별 심볼릭 링크와 ca-certificates.crt 번들 파일.
    • update-ca-certificates: 위 파일들을 모아 링크와 번들을 다시 만드는 유틸리티.
    sudo apt update
    sudo apt install ca-certificates
    dpkg -L ca-certificates | head

    사내 CA를 추가하는 절차

    1. 인증서를 PEM 형식(.crt)으로 준비한다. DER 형식이면 변환한다.
    2. /usr/local/share/ca-certificates/ 아래에 복사한다.
    3. update-ca-certificates를 실행한다.
    4. 번들 파일에 들어갔는지 확인한다.
    openssl x509 -inform der -in ca.cer -out ca.crt
    sudo cp ca.crt /usr/local/share/ca-certificates/company-ca.crt
    sudo chmod 644 /usr/local/share/ca-certificates/company-ca.crt
    sudo update-ca-certificates
    grep -c "BEGIN CERTIFICATE" /etc/ssl/certs/ca-certificates.crt

    제거와 비활성화

    • 직접 넣은 인증서: 파일을 지우고 update-ca-certificates (필요하면 --fresh)
    • 시스템 제공 인증서: /etc/ca-certificates.conf에서 해당 줄 앞에 ! 를 붙이고 update-ca-certificates
    • 대화형 관리: sudo dpkg-reconfigure ca-certificates

    검증 상태 확인

    # 신뢰하는 CA 목록
    trust list --filter=ca-anchors | head
    
    # 서버가 제시한 인증서 사슬과 검증 결과
    openssl s_client -connect example.com:443 -showcerts < /dev/null | tail -5
    
    # 로컬 인증서 파일 검증
    openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.crt
    
    # curl로 상세 확인
    curl -v https://example.com 2>&1 | grep -i "SSL certificate"

    Verify return code: 0 (ok)이면 신뢰 저장소 기준으로 검증에 성공한 것이다. 실패하면 대개 세 가지다. 중간 인증서가 빠졌거나, 만료되었거나, 체인 끝의 루트가 시스템 목록에 없는 경우다.

    자주 만나는 상황

    • Docker 이미지에서 apt update가 인증서 오류로 실패 → slim 이미지에는 ca-certificates가 없다. apt install -y ca-certificates를 먼저 실행한다.
    • 회사 프록시 뒤에서 SSL 오류 → 프록시가 연결을 가로채므로 그 프록시의 CA를 추가해야 한다.
    • Firefox에서만 인증서 경고 → 브라우저가 자체 저장소를 쓴다. p11-kit의 신뢰 모듈을 연결하거나 브라우저 정책으로 지정한다.
    • Ubuntu 24.04에서 update-ca-certificates가 메모리를 많이 쓰는 사례 보고가 있다(주로 CI 컨테이너). 재현되는 환경이면 메모리 한도를 확인한다.

    자주 묻는 질문 (FAQ)

    Q1. ca-certificates를 지우면 어떻게 되나요?

    A. HTTPS로 통신하는 거의 모든 도구가 실패한다. apt 저장소, curl, wget, docker pull이 모두 인증서 검증에서 멈춘다. 복구하려면 패키지를 다시 설치하거나 다른 경로로 인증서 묶음을 복원해야 한다.

    Q2. 인증서를 추가했는데 curl이 여전히 실패합니다.

    A. update-ca-certificates를 실행하지 않았거나, 파일 확장자가 .crt가 아니거나, PEM 형식이 아닐 수 있다. 또 애플리케이션이 --cacert 같은 옵션으로 다른 파일을 쓰고 있는지 확인한다.

    Q3. 브라우저에 사내 CA가 적용되지 않는 이유는 무엇인가요?

    A. Firefox와 Chromium 계열은 시스템 신뢰 저장소가 아니라 자체 NSS 저장소를 쓰기 때문이다. p11-kit-trust 모듈을 브라우저에 연결하거나, 브라우저 정책 파일로 신뢰 모듈을 지정해야 적용된다.

    728x90
    728x90
    댓글