시작...
우리는 HTTPS 통신을 위해 SSL 인증서를 사용합니다. SSL 인증서를 발급 받기 위해, 보통 중간 공급업자인 가비아나 한국정보인증 같은 기관에서 인증서를 구매하고 발급 받게 됩니다.
이렇게 인증서를 발급 받은 뒤, HTTPS 통신을 위해 일반 레거시 시스템의 경우 아래 그림처럼 인증서를 웹서버 config에 넣고 있습니다.
(이런 인증서는 유효기간이 있어 보통 2년을 주기로 교체해주게 됩니다.)
하지만 AWS를 사용하면서 저런 인증서를 볼 필요가 없었습니다. 왜냐하면 AWS의 Certificate Manager를 사용하면 중간 공급업체에서 인증서를 따로 살 필요도 없고, 2년을 주기로 웹서버에서 교체를 해줄 번거로움이 필요 없기 때문입니다. (알아서 다 해줌)
그런데 AWS에서도 인증서를 외부에서 따로 구매해 Certificate Manager에 심어주고 사용하는 경우도 있었습니다. (아래 그림처럼)
SSL 통신 과정
HTTPS 인증을 위한 인증서 파일들의 역할을 알기 전, SSL 통신이 어떻게 이루어지는지부터 알아보겠습니다.
먼저 클라이언트는 서버와 SSL 통신을 위해 랜덤 데이터와 클라이언트에서 사용 가능한 암호화 방식에 대해 보냅니다.
요청을 받은 서버는 클라이언트에 랜덤데이터, 암호화 방식을 선정하여 전달하고 SSL 인증서(star.shinsegae.com.crt)를 함께 보냅니다. (이때 인증서에는 인증서 발급자(CA), 도메인 등의 정보가 담겨있습니다.)
이제 클라이언트는 서버로부터 받은 SSL 인증서를 검증하는 과정을 진행합니다.
SSL 인증서는 발급한 CA(인증기관)의 비밀키로 서명되었기 때문에, 클라이언트는 CA 인증서(ca-bundle.crt)와 자신의 Root CA를 이용해 SSL 인증서(star.shinsegae.com.crt)의 서명을 검증할 수 있습니다.
즉, 클라이언트에서 CA키를 이용해 서명을 검증하여 서명이 유효하다면, 해당 인증서는 신뢰할 수 있는 CA에서 발급된 것임을 증명할 수 있습니다.
SSL 인증서 검증 (인증서 체인 구축)
그럼 SSL 인증서가 어떻게 CA(인증기관)를 통해 신뢰성 검증이 되는지 좀 더 자세하게 알아보겠습니다.
1. Root CA를 통한 SSL 인증서 검증
SSL 인증서의 검증은 위 그림처럼 체인이 구성되어 검증됩니다.
(일반적으로 3계층으로 구성 / SSL 인증서(star.shinsegae.com.crt) – 중간 인증서(ca-bundle.crt) – Root 인증서(OS나 브라우저의 Root CA) / 중간 인증서는 여러 개가 될 수 있음)
오른쪽 그림처럼 네이버 블로그를 예시로 든다면 아래와 같습니다.
인증서 | 내용 |
Root CA | DigiCert라는 미국 회사가 Root CA를 만들었습니다. |
중간인증서 | Root CA가 인증 전 네이버의 SSL 인증서를 확인하기 위해 한번 더 만들어진 인증서 입니다.blog.naver.com 도메인의 전용 인증서 |
SSL 인증서 | blog.naver.com 도메인의 전용 인증서 |
먼저 HTTPS 프로토콜을 사용하기 위해서는 신뢰할 수 있는 기관(CA, ex) DigiCert)를 통해 인증서를 발급 받아야합니다.
우리는 이렇게 발급받은 인증서를 통해 SSL 통신을 할 수 있는데요,
사실 SSL 인증서는 아래 그림의 리눅스 openssl 명령어로도 얼마든지 생성이 가능합니다.
하지만 SSL 인증서를 단순히 이렇게 생성하고 웹서버에 적용한다면, 클라이언트는 이 인증서가 믿을만한 곳에서 발급된 인증서라고 판단하기 어렵습니다.
그래서 이렇게 만들어진 인증서를 그대로 사용하게 된다면, 클라이언트에서 해당 인증서가 사용된 웹 서버 접근 시 우리가 많이 봤던 아래 페이지가 보이게 되는 것입니다.
그래서 클라이언트는 서버에서 제공하는 SSL 인증서가 내가 신뢰할 수 있는 인증서인지의 반드시 검증이 필요하고,
클라이언트는 OS나 웹 브라우저에 자신이 신뢰할 수 있는 Root CA 목록을 통해 인증서를 검증하는 과정을 거친 후에야 SSL 인증서를 신뢰하게 되는 것입니다.
2. Root CA 목록 확인
OS나 브라우저 별로 루트 CA 목록과 위치가 다릅니다.
먼저 Amazon Linux 같은 경우 /etc/ssl/certs/ca-bundle.trust.crt에 파일이 존재하며 PEM 파일 형식으로 Root CA 목록을 확인할 수 있습니다.
Windows는 아래처럼 확인이 가능하며
브라우저에서도 따로 Root CA 목록을 확인할 수 있습니다.
정리
SSL 통신 과정의 정리와 SSL 인증서를 검증하는 방법을 확인했습니다. 내용을 최종적으로 정리해보면
- 먼저 인증서(star.shinsegae.com.crt) 파일은 당연히 빠질 수 없습니다. SSL 인증 통신 자체가 안되기 때문입니다.
- 비밀키(shinsegae_ssl.key) 역시 빠질 수 없습니다. 이 파일이 빠지면 클라이언트가 보낸 암호화된 데이터를 해독할 수 없기 때문입니다.
- CA키(ca-bundle.crt)는 선택사항 일 수 있습니다.
클라이언트가 OS나 브라우저를 통해 Root CA 목록을 가지고 있고, 인증서체인이 중간인증서가 빠진 (RootCA-SSL 인증서) 구조라면 루트 CA 목록만 통해서도 인증서를 검증할 수 있기 때문입니다.
만약 발급된 서버 인증서가 클라이언트의 OS/브라우저의 신뢰할 수 있는 루트 CA 목록에도 없거나, ca-bundle.crt 파일이 빠져(중간인증서 없음) 인증서의 신뢰성 검증을 하지 못한다면
위 그림처럼 "연결이 비공개로 설정되어 있지 않습니다" 페이지가 보이게 되는 것입니다.
추가
위 내용을 통해 이번 작업의 이슈 원인을 추청해보면...
- CA인증서 누락으로 인해 중간 인증서가 빠져 SSL인증서 - 중간 인증서 - Root CA 인증서 순차적 검증이 불가하여 이슈가 발생 (클라이언트 서버에서도 중간 인증서를 찾을 수 없음)
- CA인증서를 누락했는데도 브라우저에서 인증서에 대한 신뢰성 검증이 가능했던 이유는 (클라이언트 측 서버는 불가) 브라우저의 특성 때문임.
- 브라우저의 특성1) 브라우저는 서버가 제공해주는 인증서 중에, 브라우저가 가지고 있는 중간 인증서나 Root CA 인증서 중 하나만 매칭되면 서버가 내려주는 다른 인증서는 무시한다고 함
(때문에 브라우저에 표시된 인증서와 서버 제공해준 인증서와 같을 보장이 없음) - 브라우저의 특성2) 인증서가 만료되거나 신규로 바뀌어도, 무시하고(curl 명령에서 -k 옵션 같이...) HTTPS 통신을 가능하게 하는 브라우저도 있다고 함
- 브라우저의 특성1) 브라우저는 서버가 제공해주는 인증서 중에, 브라우저가 가지고 있는 중간 인증서나 Root CA 인증서 중 하나만 매칭되면 서버가 내려주는 다른 인증서는 무시한다고 함
'Operating System' 카테고리의 다른 글
Max user processes & Open files (0) | 2022.10.18 |
---|---|
[Kubernetes] Container Runtime (0) | 2022.01.26 |
[Linux] 메모리 재할당 (0) | 2022.01.10 |
[Linux] TCP KeepAlive에 대한 고찰 (0) | 2021.12.13 |