Drop - gVisor를 지원하는 루트 권한 없는 Linux 샌드박스
요약
본 글은 gVisor를 지원하는 루트 권한 없는 Linux 샌드박스 도구인 'Drop'에 대한 기술 분석입니다. 개발자는 기존의 runc, bubblewrap 등 검증된 컨테이너/격리 도구들의 한계를 극복하고, 세밀한 Linux API 호출을 통해 강력한 보안 격리를 구현하는 과정을 설명합니다. 특히 지정 디렉터리 외 파일 접근 제한 등 높은 수준의 권한 제어에 초점을 맞추고 있습니다.
핵심 포인트
- Drop은 gVisor를 지원하며 루트 권한 없는 리눅스 샌드박스를 제공합니다.
- 기존 컨테이너 도구(runc, bubblewrap)보다 세밀한 Linux API 호출을 통해 유연성을 확보했습니다.
- 지정된 디렉터리 외 파일 접근 제한 등 높은 수준의 권한 제어가 가능합니다.
- AI 에이전트 실행 환경에 최적화되어 있으며, Zed 연동 및 메시징 프록시 기능을 갖추고 있습니다.
나도 아주 비슷한 것을 만들고 있는데, 이런 작업을 하는 사람이 꽤 많은 듯함. 그만큼 방향이 타당하다는 뜻으로 받아들여도 되겠음.
README에서 주요 도구와 비교한 부분은 좋지만, 보안상 차별점은 설명이 부족해 보임. nsjail, runc 등과 같은 기본 요소를 사용하면서 일부 기능을 다시 구현한 셈인데, 기존 도구 위에 구축하지 않고 이 접근을 택한 이유가 궁금함.
Drop의 첫 프로토타입은 Docker 런타임인 runc용 config.json을 생성하는 Python 스크립트였고, crun도 시도했음. 하지만 Drop에 필요한 속성을 모두 갖춘 샌드박스를 구성하는 데 걸림돌이 있었음. 기술적으로 해결할 수는 있었지만, 아직 사용자가 없는 신생 프로젝트가 널리 쓰이는 성숙한 도구에 기능 추가를 요청하기는 어려울 수 있음. 특히 runc와 crun은 OCI 호환 컨테이너 런타임이고 Drop은 OCI 호환 컨테이너가 아니므로, 지원 범위 밖이라고 해도 타당함.
bubblewrap도 검토했지만, 결국 세밀한 Linux API를 직접 호출하는 유연성을 택함. Drop 관점에서 runc는 JSON 설정 하나로 샌드박스 전체 구성을 요청하는 큰 단위의 API이고, bubblewrap은 비슷한 역할의 명령줄 API임. 검증된 계층을 재사용하는 이점도 상당해서 어느 쪽이 더 나은지는 명확하지 않았음.
이후 선택 사항으로 gVisor의 runsc를 통합함. 이것도 OCI 호환 런타임이지만, 사용자 공간 커널을 통한 격리 계층을 추가하려는 목적임.
나도 비슷한 도구인 https://gitlab.com/saghm/tartarus를 조금씩 만들고 있어서 무척 흥미로움. 내가 원하는 것은 지정한 디렉터리 밖에는 쓰지 못하되, 대부분의 파일은 읽을 수 있는 샌드박스임. 컨테이너나 VM에 필요한 파일을 일일이 복사하고 싶지 않기 때문임. 원하는 속성을 설정으로 받아 bubblewrap 구성을 만드는 방식으로 접근했고, 나중에는 macOS의 sandbox-exec 등으로 다른 플랫폼도 지원하려 했지만 한동안 작업할 시간이 없었음.
Drop은 Linux에 집중하면서 내가 필요했던 일부 권한 제어보다 더 완전한 샌드박스를 제공하고, 처음 원했던 기능도 대부분 갖춘 듯함. 내 구현에서 가장 공을 들였지만 보안 강화가 가장 부족한 부분은 임의의 GUI 앱 실행이었음. Zed를 통해 샌드박스 안에서 에이전트를 실행하고 싶었기 때문임.
직접 써볼 예정임. 대형 AI 기업들이 아직도 이런 기능을 제대로 해결하지 않고, 실행 도구 내부의 불투명한 규칙이나 허용·차단할 셸 명령 형태를 직접 하드코딩해야 하는 불편한 규칙에 맡긴다는 게 놀라움.
그건 Codex의 기본 동작이기도 하지만 악성 코드 방어에는 좋지 않음. 악성 npm 패키지나 프롬프트 인젝션에 당한 Codex가 SSH 키를 읽어 공격자에게 보낼 수 있음.
나도 같은 것을 만들고 있음! 새로운 격리 방식에는 언젠가 탈출 취약점이 생긴다는 게 지금까지의 교훈이고, LLM이 마음먹고 그런 취약점을 찾아내지 못하리라 믿지 않아서 Docker를 택함.
Zed 연동에 가져다 쓸 수 있는 코드도 있음. 내 구현은 ACP 에이전트처럼 동작하므로 Zed는 호스트에서 실행하되, 내부적으로는 지정한 이미지와 에이전트로 Docker 컨테이너를 만들고 파일을 복사한 뒤 WebSocket으로 ACP 메시지를 중계함. ACP의 내장 파일 읽기·쓰기 및 셸 요청은 기본적으로 프록시가 컨테이너 안에서 실행하며, 설정에 따라 일부나 전부를 호스트로 전달할 수도 있음.
저장소는 https://github.com/SethCurry/abyss이고, 관련 코드는 internal/websockets/wsacp에 있음. 메시지를 protobuf로 감싸며 라우팅 기능도 있어 ACP 이외의 메시지를 프록시 양단 사이에 추가할 수 있음. main에는 프록시의 실험적인 Wasm 플러그인 지원도 있어서, 에이전트 종류와 무관하게 프롬프트나 도구 호출을 차단하거나 모든 에이전트에 공통으로 RAG를 붙일 수 있음.
몇 주 전부터 Drop을 쓰고 있는데 상당히 만족함. 보고했던 몇 가지 오류도 빠르게 수정해 줬음. 편의성과 격리의 균형이 좋아서 모든 개발에 기본으로 쓰는 수준까지 가고 싶음.
아직 해결하지 못한 과제는 docker/podman compose로 서비스를 띄우는 컨테이너 기반 앱 개발과, 게임처럼 하드웨어 가속이 필요한 GUI 앱 개발임. 지금까지 찾아본 다른 도구도 이 부분은 해결하지 못했으며, GUI 쪽은 Flatpak처럼 PipeWire와 Wayland의 보안 컨텍스트를 활용하면 좋을지도 모르겠음.
이전에 조사할 때 https://litterbox.work/도 고려했고 좋은 도구였지만, 환경을 다시 만드는 속도가 느리고 기본 설정이 없는 등 Drop보다 번거로웠음. 지금까지는 Drop을 도입하기가 훨씬 수월함.
GUI 앱 샌드박싱은 로드맵에 있음. 현재 지원하는 Linux 네임스페이스와 gVisor에 더해 VM을 세 번째 런타임으로 추가하는 방안도 고민 중임. 실현 가능한지는 아직 확신이 없지만, VM을 쓰면 컨테이너의 중첩 네임스페이스 문제를 피해서 샌드박스 안에 컨테이너 기반 앱을 띄울 수 있을 듯함.
에이전트 격리에 각자 만든 임시방편이 많이 쓰이는데, Drop은 설계가 잘 된 듯함. 그렇다면 대형 기업은 내부에서 무엇을 쓰는지 궁금함. Anthropic, OpenAI, SpaceXAI, Google, Amazon은 에이전트 실행 환경 격리를 어떻게 해결하고 있을까?
과거 경험으로는 다들 Kubernetes를 쓸 것 같지만 세부 구성이 궁금함. Kubernetes 위에 최소화한 VM을 올리는지, 보안을 강화한 컨테이너를 쓰는지, 우리도 K3s에서 비슷한 환경을 구축할 수 있는지 알고 싶음. 아는 사람이 있다면 공유해 줄 수 있을까?
샌드박스 환경과 내 시스템의 경계를 좀 더 설명해 줄 수 있을까? 단순히 /usr/lib에 읽기 전용 접근을 주는 것인가?
나는 별칭 명령으로 $PWD에서 opencode가 들어 있는 Podman 컨테이너를 실행함. 매핑한 디렉터리 몇 개, 주로 설정 디렉터리를 제외하면 전부 일회성이고, XDG_HOME도 해당 작업 디렉터리 안에 둠. 이미지가 너무 최소한으로 구성됐다는 점만 불편한데, 그건 해결할 수 있음.
호스트의 어떤 디렉터리를 노출하는지는 이 표에서 확인할 수 있음. https://droprun.sh/docs/sandbox-overview/#filesystem-layout.
그 구성과 비교하면 Drop은 호스트의 /usr를 사용하므로 이미 설치한 프로그램을 쓰기 위해 별도 이미지를 관리할 필요가 없음. 사용자 이름, 호스트 이름, 현재 디렉터리와 홈 디렉터리 경로도 유지하며, 환경변수도 쉽게 가져올 수 있음. Podman 컨테이너의 홈 디렉터리는 /root임.
또한 drop ls와 drop rm 으로 환경을 명시적으로 조회하고 삭제하므로, XDG_HOME 파일을 정리할 때 어느 디렉터리에서 Podman을 실행했는지 추적할 필요가 없음. 다만 기존 래퍼에서 이미 해결했거나 필요 없는 부분일 수도 있으니, 현재 구성이 잘 작동한다면 굳이 바꾸지는 않겠음.
에이전트 작업 흐름에 한정하지 않아도 이 아이디어의 구현은 이미 많음. 내가 쓰는 방식의 기능들도 언젠가 정식 소프트웨어 패키지에 반영되면 좋겠음.
우선 임의로 만든 샌드박스는 신뢰하지 않으므로 직접 샌드박스를 구현하지 않고 bwrap 옵션을 생성해 bwrap이나 gVisor에서 사용함. 네트워크는 유닉스 도메인 소켓 기반 자동 HTTP 프록시를 통해 팝업 승인 또는 허용 목록으로 제어하고, 앱 제공에는 리버스 프록시를 사용함. 그 이상의 네트워크 접근은 신뢰하지 않음.
설정은 셔뱅으로 실행 가능한 파일에 저장하며, 조합 가능한 프로필과 명령줄 옵션으로 필요할 때 샌드박스를 구성함. 시스템 디렉터리를 호스트에서 가져올지, 다른 배포판이나 OCI 이미지를 쓸지도 관리하고, 샌드박스의 홈 디렉터리와 작업 디렉터리 공유 방식도 제어함.
Drop도 비슷한 기능이 있어 내 사용 방식에 잘 맞아 보임. 샌드박스가 실제로 어떻게 실행되는지와 보안 모델을 더 자세히 알고 싶음.
커널 보호에 도움이 되는 gVisor 지원이 반가움. 최첨단 모델이 커널 취약점을 찾아낼 수 있다고 예상해야 한다고 봄.
나도 비슷한 취지로 microsandbox(libkrun) 를 사용해 작고 빠른 VM 안에서 실행하는 프로젝트를 만들고 있음. 일부 작업에 필요한 네트워크 허용 목록, 자격 증명 마스킹, GitHub 허용 목록도 갖추고 있음. https://github.com/gregwebs/agent-vm/#agent-vm.
GitHub·네트워크 필터링으로 하려는 일 중 일부는 GitHub의 세분화된 권한 토큰으로 해결할 수 있지 않을까?
유용해 보임. drop run은 자식 프로세스를 실행해 Linux 네임스페이스 안에 넣고, 별도의 신원과 제한된 권한을 부여하므로 호스트에서는 루트가 아니어도 샌드박스 안에서는 루트처럼 동작할 수 있음. 파일시스템도 별도로 보이며, 내부 프로세스는 호스트의 전체 프로세스가 아니라 자체 프로세스 트리만 보게 됨. 네트워크 연결도 마찬가지임.
다만 Linux 전용이라 macOS에서는 작동하지 않는 점이 아쉬움. VPS에서 시험해 봐야겠음.
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기