사내에 올린 사이트에 들어가면 "연결이 비공개로 설정되어 있지 않습니다" 경고가 뜬다. 루트 CA 인증서를 브라우저에 등록하면 경고가 사라지는데, 공개 사이트에서는 왜 이런 일이 없는지, 그리고 이걸 사내 단말 전체에 어떻게 뿌리는지가 문제다.
TLS 에서 서버가 제시한 인증서는 그 자체로 신뢰의 근거가 되지 못한다. 클라이언트는 서버 인증서 → 중간 CA → 루트 CA 로 이어지는 체인을 따라 올라가, 마지막 루트 CA 가 자기 신뢰 저장소에 들어 있는지를 본다. 들어 있으면 통과, 없으면 경고다.
공개 사이트가 조용한 것은 그 사이트가 특별해서가 아니라, 발급자인 상용 CA 의 루트 인증서를 운영체제와 브라우저 제조사가 이미 신뢰 저장소에 넣어 배포했기 때문이다. 사내에서 직접 만든 CA 는 그 목록에 들어 있을 리 없다. 그래서 그 CA 를 신뢰 저장소에 넣어 주는 작업이 필요하다.
즉 인증서를 등록해 경고를 없애는 것은 암호화를 켜는 일이 아니다. 암호화는 이미 되고 있었고, 바뀌는 것은 상대가 진짜인지 판단할 근거다. 근거 없이 경고를 눌러 넘기는 습관은 중간자 공격에 그대로 노출된다.
자체 서명 인증서는 체인이 한 단이라 서버 인증서가 곧 루트다. 이 경우 그 인증서 자체를 신뢰해야 하므로 서버를 바꿀 때마다 다시 배포해야 한다. 사내 CA 를 하나 세우고 그 아래로 발급하면 CA 하나만 배포하면 된다.
윈도우는 certlm.msc 의 신뢰할 수 있는 루트 인증 기관 → 인증서 에 넣는다. 명령으로는 다음과 같다.
Import-Certificate -FilePath C:\temp\corp-root-ca.crt -CertStoreLocation Cert:\LocalMachine\Root
RHEL 계열 리눅스는 다음이다.
sudo cp corp-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract
데비안 계열은 확장자가 .crt 여야 한다.
sudo cp corp-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
애플리케이션이 자기 신뢰 저장소를 따로 쓰는 경우가 많다. 자바는 cacerts, 파이썬 requests 는 certifi, 파이어폭스는 자체 NSS 저장소를 본다. 운영체제에 넣었는데도 특정 도구만 실패한다면 이쪽이다.
keytool -importcert -trustcacerts -alias corp-root -file corp-root-ca.crt \
-keystore "$JAVA_HOME/lib/security/cacerts" -storepass changeit
AD 도메인에 들어 있는 단말이라면 그룹 정책이 가장 확실하다. 도메인 컨트롤러에서 그룹 정책 관리 편집기를 열고 다음 경로에 인증서를 가져오면, 정책이 적용되는 모든 컴퓨터의 루트 저장소에 자동으로 들어간다.
컴퓨터 구성 → 정책 → Windows 설정 → 보안 설정
→ 공개 키 정책 → 신뢰할 수 있는 루트 인증 기관
Active Directory 인증서 서비스(AD CS)로 CA 를 세웠다면 CA 를 디렉터리에 게시하는 것만으로 같은 효과가 난다.
certutil -dspublish -f corp-root-ca.crt RootCA
가상 데스크톱은 두 경우로 나뉜다.
전용(persistent) 데스크톱은 일반 PC 와 같다. 그룹 정책으로 배포하면 그대로 남는다.
비전용(non-persistent) 데스크톱은 세션이 끝나면 원래 이미지로 되돌아간다. 사용자가 로그인한 뒤 넣은 인증서는 다음 로그인에 사라지므로, 골든 이미지에 미리 넣고 이미지를 다시 게시해야 한다. 이미지 갱신 주기가 길면 그룹 정책을 병행해, 새 이미지가 나오기 전까지는 로그인할 때마다 적용되도록 둔다.
프로필 컨테이너(FSLogix 등)를 쓰더라도 컴퓨터 계정의 루트 저장소는 프로필에 담기지 않는다. 사용자 저장소가 아니라 컴퓨터 저장소에 넣는 것이 원칙이다.
리눅스 기반 이미지라면 이미지 빌드 스크립트에 update-ca-trust 단계를 넣는다.
배포가 실제로 먹었는지는 단말에서 직접 본다.
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like '*Corp Root*' }
trust list | grep -A2 'Corp Root'
openssl s_client -connect intra.example.com:443 -servername intra.example.com </dev/null 2>&1 | grep 'Verify return code'
Verify return code: 0 (ok) 가 나와야 한다.
루트 CA 를 신뢰시킨다는 것은 그 CA 가 발급한 모든 인증서를 믿겠다는 선언이다. 개인 PC 나 외부 협력사 단말에 사내 CA 를 넣어 달라고 요구하는 것은 그만한 무게가 있는 일이다.
루트 CA 도 만료된다. 유효기간이 끝나기 한참 전에 새 루트를 배포해 겹치는 기간을 두어야 한다.
개인키는 CA 서버 밖으로 나가지 않는다. 배포하는 파일은 공개 인증서(.crt · .cer)뿐이며, .pfx 를 뿌리는 구성은 잘못된 것이다.