메인 콘텐츠로 건너뛰기 탐색으로 건너뛰기 푸터로 건너뛰기

프록시 & 실행기

클라이언트가 SSH 키나 머신 주소를 전혀 보유하지 않고도 브라우저와 씬 클라이언트의 명령이 실행되는 방식

프록시 & 실행기

일반적으로 rdc는 사용자의 머신에서 사용자의 설정과 SSH 키를 사용해 실행되며, 서버에 직접 연결합니다. 프록시 모델은 이 흐름을 둘로 나눕니다. 어떠한 시크릿도 보유하지 않는 씬 클라이언트와, 시크릿을 보유하고 실제 작업을 수행하는 **실행기(executor)**입니다. 웹 콘솔의 실행 버튼과 CLI의 --proxy 플래그는 모두 씬 클라이언트이며, 동일한 프로토콜을 사용합니다.

명령이 아니라 명령의 의도

씬 클라이언트는 SSH 키, 머신 주소, 복호화된 설정을 전혀 보유하지 않습니다. 무언가를 실행하려 할 때는 명령의 의도만 전송합니다. 즉 명령 식별자(CLI 계약 내 경로, 예를 들어 repo up)와 매개변수뿐입니다. 실행기는 동일한 계약에서 해당 명령을 조회해 서버 측 함수로 해석하고, 복호화된 설정에서 대상 머신을 확인한 뒤 자체 SSH 연결로 명령을 실행합니다. 출력은 클라이언트로 스트리밍되어 돌아옵니다.

실행기는 rdc serve로 서버로서 시작된 CLI 그 자체입니다. 노트북에서 운영자가 실행하는 것과 동일한 바이너리가 이들을 대신해 명령을 실행하는 존재가 됩니다. 배치 방식은 두 가지입니다.

  • --mode daemon: 사용자가 관리하는 호스트에서 실행되며, 일반 CLI와 마찬가지로 헤드리스로 등록됩니다(설정 저장소 참조). 스스로 설정 키를 파생시킬 수 있으므로 세션별 권한 부여가 필요 없습니다. SSH가 사용자 네트워크를 벗어나지 않는 엄격한 등급입니다.
  • --mode container: 사용자를 위해 호스팅되는 조직 전용 컨테이너에서 실행됩니다. 처음에는 키를 전혀 가지지 않으며, 클라이언트가 세션에 키를 부여하기 전까지는 아무 작업도 할 수 없습니다. 편의성을 우선한 등급입니다.

CEK 권한 부여

설정 저장소는 영지식입니다. 서버는 언제나 암호화된 블롭만 저장하며, 콘텐츠 암호화 키(CEK)는 이를 잠금 해제한 클라이언트에서만 평문으로 존재합니다. 따라서 컨테이너 모드 실행기는 키를 부여받아야 하며, 이 부여 과정에서 서버에 키가 노출되어서는 안 됩니다.

흐름은 다음과 같습니다. 잠금이 해제된 브라우저가 실행기와 세션을 열어 세션의 공개 키를 받고, X25519를 이용해 CEK를 해당 세션에 봉인합니다. 봉인된 블롭은 계정 서버를 거쳐 전달되지만, 서버는 이를 열어볼 수 없으므로 영지식 속성은 끝까지 유지됩니다. 실행기는 CEK를 메모리에만 복호화하며, 30분 유휴 만료가 적용되고 디스크에는 절대 기록되지 않습니다. 이후의 명령 요청은 X-Config-Session 헤더를 통해 부여된 세션을 참조합니다.

감사 측면에서 한 가지가 중요합니다. 세 단계(세션 열기, 키 부여, 명령 실행) 모두 동일한 사용자 신원을 사용합니다. 계정 서버는 자신의 자격 증명을 실행기에 전달하지 않습니다. 각 단계마다 실제 사용자에게 귀속된 단기 토큰을 발급하고, 매번 해당 사용자의 소속을 다시 확인합니다. 실행기는 제시된 토큰을 검증한 뒤에만 동작합니다. 한 사용자가 부여한 권한을 다른 사용자가 사용할 수는 없습니다.

설정의 state 부분(호스트 로컬 런타임 데이터)은 애초에 설정 블롭에 담겨 전송되지 않으므로, 이 경로를 통해서도 실행기에 도달하지 않습니다.

프록시로 실행할 수 있는 것

모든 명령이 원격으로 실행하기에 적합한 것은 아닙니다. 계약에 포함된 각 명령은 proxyCapable 플래그를 가지며, 실행기는 어떤 정책 설정과도 무관하게 서버 측에서 이를 강제합니다.

  • 머신 플레인의 비대화형 명령(배포, 백업, 상태 확인, 로그 등)은 프록시 가능합니다.
  • 설정 플레인 명령은 그렇지 않습니다. 이는 설정을 편집하는 작업이며, 이 경로에서는 브라우저의 몫입니다(웹 콘솔은 대신 자체 설정 편집기로 라우팅합니다).
  • 대화형 명령(터미널, VS Code 세션)은 그렇지 않습니다. 이 회선에는 TTY가 없습니다.
  • 클라이언트 측 전송 명령(rdc repo sync)은 그렇지 않습니다. 클라이언트의 파일 시스템과 머신 사이에서 데이터를 이동시키는 작업인데, 실행기는 클라이언트의 파일에 접근할 수 없습니다.

웹 콘솔은 동일한 플래그를 읽어 명령에 실행 버튼을 표시할지 결정하지만, 실행기는 클라이언트가 무엇을 보내든 프록시 불가능한 명령은 거부합니다.

목 실행기

개발 환경에서 실제 실행기가 구성되어 있지 않을 때, 계정 서버는 명령 요청에 목(mock) 스트림과 명확히 가짜임을 알 수 있는 데이터(mock- 접두사가 붙은 리소스 이름)로 직접 응답합니다. 덕분에 머신이나 잠금 해제 없이도 폼, 스트리밍, 결과 렌더링을 포함한 콘솔 전체를 실제로 동작시켜볼 수 있습니다. 실제 실행에는 실제 실행기가 필요합니다.

관련 문서