트러블슈팅

3-cert-chain 인증서 만들기

wwns 2023. 4. 18. 22:43
반응형

웹서버에 SSL/TLS 통신을 위한 인증서를 Openssl 라이브러리를 사용해 자체 서명 인증서로 만들었는데, 제대로 이해하지 못해 조금 더 자세하게 파헤쳐봤고, 발생했던 문제점들을 보완한 점들을 기록하려고 한다.


문제 발생 상황

 

초기에는 검색하면 나오는 블로그들을 참고해서 인증서를 만들었었고

rootCA.crt와 rootCA로 서명한 server.crt를 만들어 server.crt 인증서를 Apache2 웹 서버 인증서로 사용했었다.

참고 사이트

 

자체 서명 사설 SSL 인증서 만들기

사설 인증서를 만들고 웹 서버 설정 후 브라우저에서 사용하기까지 전체 과정을 살펴보고, 실습을 통해 쉽게 적용하고 사용할 수 있습니다.

www.runit.cloud

그 후 윈도우에서 인증서를 등록하고, 사이트에 접속했지만 보안 연결이 사용되지 않는다는 문구가 뜨며 신뢰할 수 있는 인증서로 등록되진 않았었다.

웹 서버 접속 시 인증서 검증 실패

내게 필요한 것은 TLS 통신이 이루어지는 지가 핵심이었기 때문에 개발자 모드로 TLS 통신이 이루어지는지 확인해 보았다.

TLS 통신 확인

TLS 통신은 문제없이 잘 되었고 신뢰할 수 있는 인증서로 등록되지 않은 부분은 내 멋대로 추정하고 넘어갔었다.

  • 인증기관에서 발급한 인증서가 아닌 자체 서명 인증서
  • DNS를 구매하지 않았고 IP로 직접 연결하는 과정에서 CN이 제대로 매핑되지 않음

시간이 지나면서 다른 서버와 통신이 필요할 때 TLS연결이 되지 않아 이 문제를 좀 자세히 살펴보고자 인증서에 대해 조금 더 자세히 알아보았다. 사실 인증서의 문제는 아니었지만..


Openssl 인증서 생성 시 사용 옵션 config, extensions 알아보기

 

Naver의 인증서는 어떻게 다른가 하고 인증서를 다운받아 다음 명령어로 내용을 확인해 보았다.

 

openssl x509 -in 인증서.pem -text -noout

맨 위에서 링크를 걸었던 사이트를 참고하여 인증서를 생성하게 되면 x509 v3 extentions와 같은 옵션이 없었고 생각보다 여러 옵션들이 있었다. 옵션들을 간단하게 살펴보자

 

x509v3 extentions 옵션

  • Authority key identifier
    • 인증서 발급자의 공개 키(즉, 인증서 발급자의 식별자)를 나타내는 확장 필드
    • 인증서 체인을 검증하는 데 사용
    • 일반적으로 공개 키의 해시 값 또는 발급자의 명시적인 식별자
  • Subject Key Identifier
    • 인증서의 소유자의 공개 키
    • AKI와 SKI를 비교하여 인증서 체인을 검증할 수 있다
    • 상위 인증서의 SKI와 하위 인증서의 Authority Key Identifier(AKI)를 비교
      • SKI 값이 일치하면 인증서가 신뢰할 수 있는 인증서 체인에 속한 것으로 간주
  • Subject Alternative Name(SAN)
    • 추가적인 이름을 인증서에 포함시켜, 단일 인증서로 여러 도메인 이름이나 IP 주소를 보호할 수 있게 해 준다
    • 유형 
      • DNS Name: 도메인 이름
      • IP Address: IP 주소 (IPv4 또는 IPv6)
      • URI: Uniform Resource Identifier (예: https://example.com)
      • Email Address: 이메일 주소
      • Other Name: 다른 형식의 이름 (예: Kerberos Principal Name)
  • Key Usage
    • 인증서에서 공개 키의 사용 방법을 정의
    • 인증서가 어떤 용도로 사용될 수 있는지 제한
      • Digital Signature: 디지털 서명
      • Non-Repudiation: 부인 방지
      • Key Encipherment: 공개 키를 사용한 암호화
      • Data Encipherment: 데이터 암호화
      • Key Agreement: Diffie-Hellman 등을 사용한 공개 키 합의
      • Certificate Sign: 인증서 서명
      • CRL Sign: CRL(Certificate Revocation List) 서명
      • Encipher Only: 암호화 전용
      • Decipher Only: 복호화 전용
    • 인증서를 받은 클라이언트는 인증서의 Key Usage를 확인하여 공개 키가 인증서 발급자가 지정한 목적에 맞게 사용되었는지 확인
  • Certificate Policies
    • 인증서 정책을 정의
    • 보안 강화 및 인증서 사용자에게 보안 수준을 보장하기 위한 목적으로 사용
    • Certificate Policies는 OID(객체 식별자) 값으로 구성
    • 인증서 발급 기관은 인증서 정책을 Certificate Policies 필드에 명시하여 웹사이트 방문자가 해당 인증서를 신뢰할 수 있도록 한다 
    • OID(객체 식별자)
      • 객체에 대해 유일한 식별자를 부여하기 위한 규칙
      • 특정 객체의 유형을 식별하기 위해 사용
        • 은행의 인증서에도 보면 OID값이 들어가 있음
  • Basic Constraints
    • 기본 제한 사항을 정의
    • CA:True 옵션을 넣으면 이 인증서가 인증기관 인증서임을 나타냄

이러한 옵션들을 통해 인증서의 사용 용도, 목적, 검증 방법을 명시함으로써 신뢰할 수 있는 인증서인지를 판단하는 것

 

따라서, 자체 서명 인증서를 생성할 때 chain구조로 depth3에 해당하는 인증서를 생성하며, 이러한 옵션들을 인증서에 저장하면 신뢰할 수 있는 인증서로 웹사이트에서 안전한 연결임을 검증받을 수 있을 것으로 판단하였다.

 


OpenSSL로 인증서 구성

 

rootCA config

 

middleCA.config
server.config

root CA 인증서 만들기

openssl req -new -x509 -key root.key -out root.crt -config rootca.cnf -extensions req_ext

middle CA 인증서 만들기

openssl x509 -req -in middle.csr -CA root.crt -CAkey root.key -CAcreateserial -out middle.crt -days 365 -sha256 -extfile middle.cnf -extensions ext

server 인증서 만들기

openssl x509 -req -in server.csr -CA middle.crt -CAkey middle.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile server.cnf -extensions req_ext

조금 문제였던 부분이 middle.csr, server.csr을 만드는 게 문제였다. 최상위 root CA를 만들 때는 한 번에 인증서를 생성할 수 있었지만, 상위 인증서가 서명한 인증서를 만드려면(chain) .csr파일을 먼저 만들고, 상위 인증서가 서명한 인증서(.crt)로 생성을 해야 했다.

 

 .csr 인증서 만들기

openssl req -new -key middle.key -out middle.csr -config middlecsr.cnf

middlecsr.cnf 파일은 req_extensions을 제거해줘야 한다. 안 그럼 오류가 발생 혹은 config파일을 사용하지 않고 직접 입력해도 가능하다


Apache 서버에 인증서 등록하기

 

웹 서버는 `mod_ssl`모듈을 사용해 <IfModule mod_ssl.c> 디렉티브 안에 설정을 해주었다.

IfModule mod_ssl.c은 Apache 웹 서버에서 SSL/TLS 암호화 기능을 지원하기 위해 사용되는 모듈인 mod_ssl이 로드되어 있는지 확인하는 Apache 디렉티브이다

디렉티브 인증서 path 설정

  • CACertificateFile의 경우 server 인증서를 발급한 middle CA와 middle 인증서를 발급한 root CA 인증서를 합친 crt파일을 저장해야 함
    • 상위 CA인증서의 정보가 모두 필요하며 하나의 인증서로 합쳐서 저장

직접 생성한 인증서를 윈도우 서버로 옮겨서 mmc 인증서 관리에 추가

root CA의 경우 `신뢰할 수 있는 루트 인증 기관`에 옮겨야 하고, middle, server는 개인용 인증서에 넣어두었다.

자체 서명한 인증서로도 인증서 검증을 받고 안전하다는 문구를 띄울 수 있었다!

하지만 내가 진짜 원했던 서버 간 통신에서 문제가 있었고 다음 글에서 정리하도록 하겠다.(특수 케이스이기 때문에 아마 웬만한 사람들은 이렇게 인증서를 등록하면 문제없을 것이다)


정리

  • 직접 인증서 Chain을 만들기 위해선 인증서 검증을 통과해야 신뢰할 수 있는 인증서로 등록할 수 있다
  • Openssl 옵션을 사용해 인증서 검증을 자세히 설정해주어야 한다.
  • 인증서를 자세히 뜯어보면 이 인증서의 용도와 역할을 알 수 있다.

인증서의 구성이 어떻게 되는지 잘 모르는 채로 만들고 설정했던 부분이 시간이 지나자 독으로 찾아왔고 처음부터 다시 뜯어보면서 구조가 이해가 됐다.

이전에 해놓은 짓은 다시 생각해 보면 당연히 신뢰할 수 없는 인증서였던 것이었다

 

사실문제를 해결한 부분은 Cipher Suit와 관련되어 있는데 글이 길어지고 좀 다른 내용이라 생각되어 다음 글에서 정리하도록 하겠다.. 

반응형