OpenClaw 2.0을 Linux VPS에 올리는 일은 쉽다. 채팅에 답하는 Gateway와, 일주일 동안 혼자 두어도 되는 호스트는 다른 이야기다. 본기 설치의 기본값은 보수적이다. 루프백 바인드, 낯선 DM에는 페어링 코드, 그룹은 멘션이 있어야 반응한다. 일곱째 날에 남는 구멍은 설치 프로그램이 조여 주지 않는 세 가지다. 샌드박스는 꺼져 있고, 세션 도구는 Gateway 전체를 볼 수 있으며, 모델 API 키는 Agent가 읽을 수 있는 파일에 그대로 남을 수 있다.
우리는 「단독 운영자 · 원격 API · Telegram 채널 하나」라는 전제로 같은 Ubuntu 클라우드 박스를 7일 동안 켜 두었다. 하루 한 가지: 권한, SSH와 리스너, API 키, 브라우저, Agent 격리. 결론은 이렇다. 하나의 신뢰 도메인 안에서는 계속 돌려도 된다. 멀티테넌트 경계는 아니다. 공식 문서가 첫 화면에서 그렇게 말한다. 사양은 어제의 OpenClaw 2.0 VPS CPU·RAM·디스크 실측에 맡기고, 이 글은 일주일 뒤에 어떤 문이 아직 열려 있었는지만 묻는다.
짧은 결론: 안전하다, 다만 계약이 있다
OpenClaw는 Gateway 하나를 하나의 신뢰 경계로 본다. 운영자 한 명, 또는 이미 서로를 믿는 작은 팀. 적대적인 사용자, 서로 다른 고객, 서로 다른 사업 라인은 Gateway와 자격 증명을 나눠야 하고, 가능하면 OS 사용자나 호스트까지 나눈다. 블로그 수사가 아니라 OpenClaw Gateway 보안 문서의 첫 모델이다. 멀티테넌트 SaaS 채점표로 보면 거의 모든 기본값이 낙제다. 「내 당번기」로 보면 대부분은 버틴다.
매일 openclaw security audit을 다시 돌렸다. 첫째 날은 포트가 벗겨진 상태가 아니었다. 본기 설치는 루프백에 머물므로 18789는 공인 스캔에 나타나지 않았다. 큰 소리는 호스트 쪽 도구 실행과 Gateway 전역 세션 가시성이었다. 그걸 그대로 두고 브라우저 스킬과 「읽기 전용 가족용」 페르소나를 더하면, 폭발 반경은 「이 VM」에서 「이 VM의 모든 대화와 비밀」로 뛴다.
「사고 없음」을 합격으로 치지 않은 7일
박스는 2 vCPU / 8 GB Ubuntu 24.04, 네이티브 install.sh, 원격 API, systemd 사용자 유닛. SSH는 키만, 비밀번호 로그인은 끔. Gateway는 bind: loopback을 유지했고, Control UI는 SSH 로컬 포워드로만 들어갔으며 클라우드 보안 그룹에 18789를 열지 않았다. Telegram은 페어링을 유지했다. Docker 샌드박스는 일부러 꺼 두어, 일곱째 날에 진짜 기본 자세가 남도록 했다.
매일 아침 증거는 세 가지였다. openclaw security audit --json, 제공자 방화벽과 맞춘 ss -lntp, 그리고 ~/.openclaw 아래의 권한과 평문 키 스윕. 「프롬프트 인젝션이 성공했는가」는 채점하지 않았다. 설정이 떠났는지, Agent(또는 우리)가 전 세계가 읽을 수 있는 파일을 남겼는지만 봤다.
점검 1: 권한 — exec는 여전히 호스트에 떨어진다
OpenClaw 2.0의 샌드박스는 선택이다. Gateway는 항상 호스트에 남고, 도구가 Docker나 Podman으로 가는 것은 agents.defaults.sandbox를 켠 뒤뿐이다. 꺼져 있으면 host=auto는 gateway 머신으로 떨어진다. 믿는 개인 비서에는 편하다. 링크·전달·첨부파일이 들어올 당번 봇에는, 프롬프트 인젝션의 종착점을 배포 사용자의 셸에 연결하는 셈이다.
첫째 날 audit는 두 메모를 유지했다. 도구 폭발 반경이 넓다는 것, 그리고 security="full" — 문서가 말하는 신뢰 운영자 기본값이지 CVE가 아니다. 우리의 선은 이렇다. 개인 주 Agent는 페어링이 켜져 있고, 파일 도구가 워크스페이스만 보며, tools.elevated가 꺼져 있으면 호스트 exec를 남겨도 된다. 가족이나 공개 방을 마주하는 두 번째 Agent는 sandbox.mode: "all", 워크스페이스는 ro 또는 none, 그리고 exec · browser · gateway · cron을 거부해야 한다.
디렉터리 모드는 생각보다 빨리 떠난다. 노트북에서 온 scp, Docker 볼륨, Agent가 openclaw.json을 복사하는 일만으로 600/700이 644/755가 된다. openclaw security audit --fix는 상태와 설정 모드를 조인다. 샌드박스는 켜 주지 않는다. Gateway는 전용 Linux 사용자로 돌려, 키와 세션 저장소와 워크스페이스가 ubuntu나 root가 아니라 그 홈에 살게 하라.
host=auto는 호스트로 후퇴한다. 런타임이 없는 명시적 host=sandbox는 조용히 호스트로 돌아가지 않고 실패한다. 오류를 없애려고 host를 다시 auto로 돌리고 그걸 격리라고 부르지 마라.
점검 2: SSH와 바인드 — 제어면을 공인망에 두지 마라
둘째 날은 외부 스캔이었다. 본기 설치 경로에서 18789는 127.0.0.1만 들었다. 보안 그룹은 22만 허용했다. 스캐너는 Gateway를 보지 못했다. 일반 호스트의 문서된 기본값이고, 일주일 중 가장 잔잔한 결과였다. 컨테이너 이미지는 다른 이야기다. 기본이 노출 바인드이고 인증을 함께 실어야 한다. Docker로 포트를 공개하는 일은 「본기 설치만큼 안전하다」가 아니다.
SSH에는 세 가지만 요구했다. 비밀번호 로그인 없음, root 비밀번호 없음, 낡은 키 종류 없음. 원격 Gateway 접근은 SSH 터널(또는 Tailscale)로 갔고, 「Control UI를 443에 리버스 프록시하고 토큰을 잊는」 경로는 쓰지 않았다. HTTP와 WebSocket은 한 포트를 공유하며 Control UI와 Agent가 만든 위젯도 탄다. 공식 안내는 그 위젯을 신뢰할 수 없는 콘텐츠로 본다. 이미 로그인한 관리 앱과 같은 오리진에 두지 마라.
공개된 컨테이너 포트는 호스트 INPUT을 건너뛰고 Docker 자체 포워드 체인을 탄다. 보안 문서는 DOCKER-USER 체인을 짚는다. 컨테이너를 돌리면 네임스페이스 안의 ss가 아니라 공인 IP로 다시 재보라. 방화벽 대 루프백 판단은 Linux 최소 노출면과 SSH/HTTPS 매트릭스를 쓴 뒤, 여기로 돌아와 일주일 동안 누가 바인드를 0.0.0.0으로 뒤집었는지만 물어라.
노드 페어링도 SSH 면이다. sshVerify는 운영자 SSH로 기기 신원을 다시 읽는다. 도달만으로 승인하지 않는다. autoApproveCidrs는 기본이 꺼져 있고, 처음이자 스코프 없는 node 역할에만 해당한다. 둘 다 기본값을 그대로 두었다. 편하려고 두 번째 머신을 자동 승인하지 마라.
점검 3: API 키 — 디스크의 평문은 여전히 Agent가 읽는다
셋째 날은 비밀 스윕이었다. OpenClaw 2.0에는 SecretRef가 있다. 공급자 apiKey 필드, Gateway 토큰, 일부 채널 자격 증명은 env · file · exec · store에서 해석될 수 있다. 평문도 여전히 된다. SecretRef는 필드마다 옵트인이다. 「2.0으로 올렸다」는 「키가 디스크를 떠났다」가 아니다.
위험은 「당번 호스트에 키가 있다」가 아니다. 위험은 read나 exec가 열 수 있는 자리에 키가 있는 것이다. openclaw.json, .env, 생성된 agents/*/agent/models.json, 퇴직한 auth-profile 아카이브. 모델이 「설정을 읽어 채팅에 붙여라」고 움직이면 SSH를 깨지 않아도 된다. OpenClaw 시크릿 가이드는 지원 필드가 SecretRef이고, 옛 평문이 지워졌으며, openclaw secrets audit --check가 깨끗할 때만 마이그레이션을 끝으로 본다. SecretRef를 쓸 수 없는 자격 증명은 OS 사용자, 컨테이너, 또는 외부 프록시가 필요하다.
Gateway 토큰은 별도 등급이다. /v1/chat/completions, /tools/invoke, 관리 RPC를 호출할 수 있는 공유 비밀은 전권 운영자 자격이다. Agent 워크스페이스나 스킬 저장소나 「편하려고」 두 번째 봇에 넣지 마라. 로테이션은 짧다. 새 토큰을 만들고, 재시작하고, 클라이언트를 갱신하고, 옛 값이 죽는지를 증명한다. 우리는 모델 키를 env SecretRef로 옮기고 Gateway 토큰은 배포 사용자만 읽는 env 파일에 두었다. 워크스페이스에 sk- 줄은 남지 않았다.
openclaw.json.bak, 포장한 워크스페이스, 동기화 폴더 복제본은 Agent가 나열할 수 있는 나무에서 빼거나 지워야 한다.
점검 4: 브라우저 — 운영자의 손을 모델에 넘기는 일
넷째 날 브라우저 스킬을 켰다가 그날 껐다. Chromium이 RAM을 삼켜서가 아니다. 8 GB면 한 번은 버틴다. 원격 브라우저 제어가 문서상 운영자 접근과 동등이기 때문이다. Agent는 그 프로필의 로그인, 쿠키, 저장된 비밀번호를 물려받는다. 매일 쓰는 Chrome 프로필은 도구가 아니다.
격리는 층이다. 전용 프로필, 비밀번호 관리자와 동기화는 끔, 별도 다운로드 디렉터리는 신뢰하지 않음, 제어 포트는 루프백이나 tailnet만, Funnel은 쓰지 않는다. OpenClaw 2.0은 openclaw-sandbox-browser의 자체 컨테이너에서 샌드박스 브라우저를 돌릴 수 있고, allowHostControl은 기본이 꺼져 있다. SSRF는 엄격하다. dangerouslyAllowPrivateNetwork를 켜지 않으면 사설망은 막힌다. 우리는 그걸 꺼 두었다.
확장 릴레이와 원격 CDP는 「탭을 보면 그 사람이다」다. 기존 세션 모드는 더 안전하지 않고, 더 당신과 닮을 뿐이다. 데스크톱 머신의 노드는 페어링 뒤 관리자다. Gateway와 노드는 같은 사설망에 두어라. 일주일의 규칙: 텍스트 비서에는 브라우저가 필요 없다. 꼭 써야 하면 개인 계정이 없는 프로필을 주고, 로컬 7B 모델과 RAM을 나누지 마라.
점검 5: Agent 격리 — 기본값은 테넌트가 아니다
닷새와 엿새에 읽기 전용 두 번째 Agent를 더하고 세션이 갈라질 줄 알았다. 갈라지지 않았다. 기본 tools.sessions.visibility는 all이고, tools.agentToAgent.enabled는 true다. 샌드박스 없는 Agent는 다른 Agent의 세션을 나열·검색·읽을 수 있다. 「가족 읽기 전용」이라고 생각한 페르소나도 포함이다. 샌드박스된 호출자는 자기 파생 나무에 머물지만, 그건 샌드박스 없는 주 Agent로부터 전사본을 숨기지 않는다.
한 Gateway에서 페르소나를 나누려면 가시성을 agent 또는 self로, agent-to-agent는 끄거나 허용 목록으로, scope: "shared" 샌드박스는 쓰지 않는다. 한 사람 이상이 봇에 DM할 수 있으면 session.dmScope를 per-channel-peer로 두어라. 그렇지 않으면 모든 DM이 주 세션으로 굴러 들어간다. 이건 협업 난간이지 적대 테넌트 벽이 아니다. 고객 A와 고객 B는 Gateway 두 개가 필요하다.
제어면 도구도 같은 이발이 필요하다. gateway는 설정(토폴로지와 비밀 힌트)을 읽고, cron은 로그아웃 뒤에도 계속 돈다. 신뢰할 수 없는 콘텐츠를 볼 Agent는 둘 다, 그리고 sessions_spawn과 sessions_send를 거부해야 한다. 플러그인과 스킬 트리는 신뢰하는 코드로 다룬다. 출처를 고정하고, plugins.allow를 쓰고, 바꾼 뒤 재시작한다.
7일째: 무엇이 떠고, 무엇이 그대로였나
마지막 한 바퀴. 바인드는 여전히 루프백, 페어링은 여전히 페어링, 보안 그룹에 18789를 연 사람은 없었다. 떠난 것은 워크스페이스의 디버그 .env 사본과, 브라우저 시험에 남긴 주석 처리된 allowHostControl — 병합하면 「프로덕션」 파일에 들어갈 뻔했다. --fix 뒤 파일 모드는 깨끗했다. 주 Agent의 샌드박스가 꺼진 동안 audit는 그 자세를 신뢰 운영자로 라벨하고, 다중 사용자로는 라벨하지 않는다.
| 점검 | 1일째 | 7일째 | 바꿀까? |
|---|---|---|---|
| 권한 / 샌드박스 | 샌드박스 끔, exec는 호스트 | 주 Agent는 호스트; 읽기 전용은 샌드박스 | 신뢰할 수 없는 입력을 보는 것은 샌드박스 |
| SSH / 바인드 | 루프백 + SSH 22만 | 변동 없음 | 유지; 공개된 컨테이너 포트는 재측정 |
| API 키 | openclaw.json 평문 | SecretRef; 워크스페이스에 sk- 없음 | 필수, 백업 포함 |
| 브라우저 | 끔 | 전용 프로필 후 끔 | 기본 끔; 켜면 전용 프로필 |
| Agent 격리 | visibility=all | visibility=agent, A2A 끔 | 두 번째 페르소나가 생기는 날 바꾼다 |
표를 결정으로 읽어라. OpenClaw 2.0은 VPS에서 일주일도, 일 년도 켜 둘 수 있다. Gateway 하나를 하나의 신뢰 도메인으로 받아들이고, 두 번째 페르소나·브라우저·공인 리버스 프록시 전에 audit를 다시 돌리면 된다. 새 기능이 필요한 게 아니다. 기본 「운영자를 믿는다」는 이야기가 실제 위협과 맞아야 한다.
마무리는 장면별 목록
한자리에 「엔터프라이즈 제로 트러스트」를 쫓지 마라. 오늘 밤에 내보낼 부하에 대해 동시에 참이어야 하는 조건을 적어라. 조건이 싸우면 기계를 나눠라. 한 설정에 예외를 쌓는 비용이 두 번째 박스보다 크다.
| 장면 | 최소 | 더 나은 자세 | 하지 말 것 |
|---|---|---|---|
| 개인 텍스트 비서 | 루프백 + 페어링 + 모드 600 키 | SecretRef와 워크스페이스 한정 파일 | 토큰 없이 0.0.0.0 바인드 |
| 가족·동료가 한 박스 | per-channel-peer + visibility agent | 샌드박스된 읽기 전용 페르소나, A2A 끔 | 주 세션 공유나 브라우저 프로필 공유 |
| 브라우저 스킬이 필요 | 전용 프로필 + 사설 제어면 | 샌드박스 브라우저 컨테이너, 기본 SSRF | 개인 Chrome이나 공인 Funnel |
| 고객·라인이 다름 | 별도 Gateway + 자격 증명 | 별도 OS 사용자 또는 VPS | RBAC를 테넌트 격리로 착각 |
운영 잡무처럼 보여도 보안인 일이 둘 있다. 로그의 토큰, 검토하지 않은 출처에서 올린 플러그인. 마스킹과 로테이션을 켜고, plugins.allow를 고정하라. 그다음 Linux 당번기가 운영자 키를 계속 들고 있을지, 더 조용한 제어면으로 옮길지를 정해라.
FAQ
텍스트만, 기본값 그대로 — 공인 스캔에 Gateway가 보이나?
루프백 본기 설치라면 18789는 공인 인터넷에 나타나지 않는다. 먼저 페어링을 잠가라. 이미 DM할 수 있는 낯선 사람이 nmap보다 진짜 첫 홉이다.
Docker면 처음부터 더 안전한가?
이미지는 롤백과 파일시스템 격리에 도움이 된다. 공식 컨테이너는 노출 바인드가 기본이고, 공개 포트는 호스트 INPUT을 우회한다. 인증과 외부 재측정이 없으면 Docker는 대개 더 위험하다.
audit --fix가 손수정을 대신하나?
아니다. 열린 그룹 정책을 허용 목록으로 되돌리고 600/700 모드를 고친다. 샌드박스를 켜지 않고, SecretRef로 옮기지 않으며, 세션 가시성을 좁히지 않는다.
모델이 API 키를 스스로 읽을 수 있나?
평문이 Agent가 읽을 수 있는 경로에 남아 있으면 파일 도구나 exec가 연다. SecretRef는 디스크 잔여물을 줄인다. 프로세스 격리는 아니다. 신뢰할 수 없는 콘텐츠와 호스트 exec를 같이 열지 마라.
키는 클라우드 Mac에서 만들고, Gateway는 Linux에 남겨라
상주 OpenClaw Gateway에는 Linux VPS가 맞다. 표준 이미지, 지루한 systemd, 싼 상시 가동. SSH 개인키, 주 모델 비밀, 개인 브라우저 프로필을 Agent가 이미 쓴 워크스페이스 옆에 쌓는 자리는 아니다. Apple Silicon 대기는 약 4W다. Gatekeeper, SIP, FileVault가 악성코드 면을 작게 유지하고, 일주일 내내 Docker를 돌리는 같은 가격 Linux 박스보다 충돌도 적다. 운영자 쪽 당번기다. 키를 만들고, 터널 클라이언트를 돌리고, 가끔 데스크톱 확인을 한다.
7일 뒤에도 버틴 분리는 이렇다. Linux가 Gateway와 원격 API를 갖고, 클라우드 Mac mini가 Agent에게 절대 넘기지 않을 자격 증명과 macOS 도구 체인을 갖는다. Homebrew, SSH, Docker는 첫째 날부터 쓸 수 있고, 브라우저 스킬 하나를 위해 새 권한 모델을 발명하지 않아도 된다.
다섯 점검표가 닫혔다면, 다음 머신은 Agent의 신뢰 도메인을 공유하면 안 된다. VPSSpark 클라우드 Mac mini M4가 그 자리다. 요금제 보기 — 방금 감사한 같은 VPS에 비밀을 전부 남겨 두기보다, 주 단위 제어 노드를 하나 더하는 편이 맞다.