Cloudflare Sandbox 인증서 패치, SDK만 올리면 끝날까?

인증서 패치를 배포했는데 장애 복구 뒤 컨테이너가 예전 신뢰 설정으로 돌아왔다. 복구 뒤에도 새 인증서를 쓰게 하려면 무엇까지 다시 만들어야 할까?

Cloudflare Sandbox 인증서 패치, SDK만 올리면 끝날까?
세 줄 요약
  • 인증서를 신뢰할지 결정하는 런타임과 컨테이너 이미지를 업데이트해야 한다.
  • 0.x는 패키지와 대응 이미지를 함께 올리고, 1.x는 자체 이미지와 실행 인스턴스를 교체한다.
  • 옛 스냅샷은 옛 이미지로 복원되므로 새 이미지에서 복구용 스냅샷도 다시 만들어야 한다.

npm 패키지 버전은 컨테이너의 인증서 상태가 아니다

Cloudflare Sandbox의 인증서 패치 완료 여부는 실제 코드를 실행하는 이미지에서 확인해야 한다. Cloudflare가 10월 20일 공개한 eMudhra 사고는 중간 인증기관 인증서 8개의 개인키 문제다. 이를 신뢰하는 클라이언트는 위조된 서버 인증서를 받아들일 수 있다.

인증서 검증을 담당하는 주체는 앱마다 다르다. 운영체제 저장소를 쓰기도 하고, 언어 런타임이 자체 목록을 갖거나 별도의 인증서를 지정하기도 한다. 따라서 패키지 관리자의 업데이트 성공과 실제 HTTPS 연결의 신뢰 정책 변경은 같은 결과가 아니다.

0.x는 대응 이미지를, 1.x는 자체 실행 이미지를 바꾼다

10월 22일 대응 공지는 SDK 세대에 따라 조치를 나눈다. 기존 0.x 앱은 @cloudflare/[email protected]와 대응 컨테이너 이미지를 함께 적용하고 재배포한다. 이미지 태그에 -python, -opencode, -musl을 썼다면 그 계열을 유지한다.

FROM docker.io/cloudflare/sandbox:0.12.14

이 예시는 기본 이미지용이다. Dockerfile 문서처럼 자체 베이스 이미지에 Sandbox 바이너리만 복사한 구성이라면, 베이스의 인증서와 런타임도 따로 갱신해야 한다. 새 바이너리를 가져오는 작업만으로 자체 베이스 전체가 바뀌지는 않는다.

0.12.13에 머물러도 충분하다고 판단해서는 안 된다. 후속 0.12.14 릴리스는 자체 인증서 목록을 쓰는 Bun을 1.4.4로 올렸다. 이 수정에는 Bun 명령과 10 MiB 이상 아카이브의 createBackup() 업로드 경로가 포함된다.

1.x는 이번 사고 때문에 SDK 자체를 업데이트할 필요는 없지만 실행 이미지가 신뢰하는 인증서는 갱신해야 한다. 공지는 베이스 이미지를 새로 받고 빌드 캐시를 비운 뒤 배포하도록 안내한다. digest로 이미지를 고정했다면 새 이미지를 빌드·게시하고 참조 digest도 바꿔야 한다.

새 배포와 기존 컨테이너 교체는 따로 확인한다

named image를 사용하는 durable_object 배포 방식에서는 이미지 맵을 갱신해도 이미 실행 중인 컨테이너가 재시작되지 않는다. 새 설정은 이후 시작에 쓸 이미지를 바꾸며, 기존 인스턴스는 시작할 때의 이미지를 계속 쓴다.

이 방식으로 운영하는 1.x 앱은 오래된 인스턴스를 중지하고 갱신된 이미지로 다시 시작해야 한다. destroy()는 즉시 중지하며 진행 중인 작업과 시작 이후의 파일 변경을 잃게 하므로, 보존할 데이터와 미완료 작업을 처리한 뒤 교체해야 한다. 배포 성공 표시만으로 모든 실행 인스턴스가 교체됐다고 판단할 수 없다.

컨테이너 스냅샷도 별도로 갱신해야 한다. 스냅샷은 메모리나 실행 프로세스가 아니라 파일시스템 상태를 보존하며, 생성 당시 이미지 버전에 묶인다. 기존 스냅샷을 새 이미지에 그대로 이식할 수는 없다.

오래된 스냅샷으로 복구하면 옛 이미지의 인증서가 돌아온다. 새 이미지에서 필요한 데이터를 복구한 뒤 새 스냅샷을 만들어, 이후 복구 작업도 갱신된 상태에서 시작하도록 해야 한다.

curl이 막혔어도 Node와 Bun은 따로 확인한다

검증은 앱이 실제로 사용하는 TLS 경로에서 수행해야 한다. 공식 대응 공지는 컨테이너 안에서 사용하는 각 클라이언트로 지정된 테스트 호스트에 연결해, 문제가 된 인증서가 거부되는지 확인하도록 한다.

브라우저나 curl의 결과만으로 별도 인증서 목록을 쓰는 Node·Bun까지 판정할 수 없다. 단순 타임아웃이나 HTTP 오류도 인증서 검증 거부와 같은 결과가 아니다. 로그에서 실패 원인을 확인하고, 검증 오류를 없애려고 인증서 확인을 끄지 않아야 한다.

업데이트의 마지막 확인 대상은 package.json 숫자가 아니라 현재 실행 이미지와 앞으로 복구에 사용할 이미지다. 현재 실행 환경과 복구용 이미지에서 사용하는 TLS 클라이언트가 모두 수정된 인증서 신뢰 설정을 적용하는지 확인해야 한다.