HTTPS 보안 모델은 “클라이언트 ↔ 서버 직통” 구조예요.
rubygems.org 서버가 공인된 CA(인증기관) 에서 인증서를 발급받고,
클라이언트(브라우저, Ruby, curl 등)는 Root CA 목록을 통해 이 서버가 “진짜”임을 검증합니다.
즉, 중간에 아무도 못 끼어들어야 정상이에요.
기업 보안 장비(웹필터, 방화벽, IDS/IPS)는 “암호화된 HTTPS 트래픽을 들여다볼 수 없음”이 문제예요. → 그래서 SSL 가로채기(SSL Inspection) 를 합니다.
사용자가 rubygems.org 요청 → 보안 장비가 가로챔.
장비가 진짜 rubygems.org 와 통신 → 받은 응답을 분석/필터링.
장비는 사용자에게 자기 서명 CA 로 새 인증서를 만들어 줌.
사용자 입장에서는 “rubygems.org”라고 되어 있지만, 사실은 프록시가 대신 서명한 것.
결과적으로, 모든 HTTPS 트래픽이 회사 장비를 경유하면서 감시/필터링됨.
브라우저는 Windows OS의 루트 인증서 저장소를 보기에, 회사 CA를 넣어주면 정상 동작.
Ruby, Python, Git 등은 OS 저장소 대신 자체 번들(cert.pem) 을 사용.
회사 CA가 거기에 없으니 “이건 신뢰할 수 없는 인증서다 → SSL 에러” 가 발생하는 거예요.
TLS 설계는 “아무도 중간에서 인증서를 바꿀 수 없다” 라는 신뢰 모델을 강제합니다.
그런데 회사 보안 장비는 합법적으로 “중간자 공격”을 수행하는 셈이라, 이를 클라이언트가 허용하려면 “우리 회사 CA도 신뢰해” 라고 수동으로 추가해야 합니다.
그렇지 않으면 클라이언트는 계속 “자기 서명 인증서라서 못 믿어” 라고 거부하죠.
TLS 기본 철학 = 최소한의 신뢰(공인 CA만).
회사 정책 = 전 구간 감시(내부 CA 필요).
이 두 가지가 충돌하니까, 우리는 매번 Ruby, Python, Git 같은 툴마다 사설 CA를 수동 등록해야 하는 겁니다.
불편한 이유 = 보안 구조가 원래 중간자(MITM)를 막기 위해 설계되었기 때문.
기업 SSL 필터링 = 의도적인 MITM.
그래서 회사 CA를 신뢰 목록에 추가하는 번거로운 작업이 필요.
브라우저는 OS 저장소만 보면 되니 한 번이면 끝나지만, 개발 툴들은 각각 자기 cert bundle을 쓰니 매번 따로 설정해야 함.