termal.in

← 블로그

OpenClaw와 SSH: 터널로 대시보드에 닿고, 키 없이 에이전트가 서버에 닿게 하기

· Termalin Team mcpai-agentssshsecuritytutorial

‘OpenClaw SSH’라는 말 뒤에는 서로 다른 두 가지 일이 숨어 있고, 이 둘을 섞는 데서 사람들이 막힙니다. 하나는 OpenClaw 자체에 닿는 것입니다. 대시보드가 localhost에서 돌아가므로 SSH 터널로 엽니다. 다른 하나는 그 반대입니다 — OpenClaw 에이전트가 내 서버에서 명령을 실행하게 하는 것입니다. 이 글은 둘 다 다루고, 두 번째에 대해서는 에이전트가 읽을 수 있는 곳에 SSH 키를 결코 두지 않는 방법을 보여 줍니다.

먼저 한 가지 밝혀 둡니다: 저희는 Termalin을 만듭니다. 2부의 키 없는 선택지가 그것입니다. OpenClaw는 직접 셀프 호스팅하는 오픈소스 에이전트 게이트웨이입니다 — 상자에서 돌며 웹 대시보드를 제공하고, 자체 마켓플레이스인 ClawHub에서 ‘스킬’을 설치합니다. 다른 접근들도 저희 것이 그렇게 설명되기를 바라는 만큼 공정하게 설명합니다.

‘OpenClaw SSH’로 사람들이 뜻하는 두 가지

  • SSH로 OpenClaw에 닿기. 대시보드가 localhost에 묶여 있으므로, 그 포트를 내 머신으로 포워딩합니다. 이게 1부입니다.
  • OpenClaw가 내 서버에 닿게 하기. 에이전트가 다른 상자에서 명령을 실행하길 원합니다. 이게 2부이고, 신중하게 할 가치가 있는 부분입니다.

1부 — SSH 터널로 OpenClaw 대시보드 열기

OpenClaw 게이트웨이는 의도적으로 자기가 돌아가는 호스트의 127.0.0.1:18789에 묶입니다. 대시보드는 공개 웹사이트가 아니라 관리용 컨트롤 플레인입니다. 노트북에서, 이미 쓰고 있는 SSH 로그인 위로 그 포트를 포워딩하세요:

ssh -N -o ServerAliveInterval=30 -L 18789:127.0.0.1:18789 user@vps

그런 다음 브라우저에서 http://127.0.0.1:18789을 여세요. -N은 ‘셸 없이 터널만’을 뜻하고, ServerAliveInterval=30은 연결이 유휴 상태로 끊기지 않게 합니다. 트래픽은 이미 신뢰하는 SSH 세션을 쓰므로, 인터넷에 새로 노출되는 것은 없습니다.

터널을 건너뛰겠다고 게이트웨이를 0.0.0.0에 묶지 마세요. 그러면 에이전트의 컨트롤 플레인이 공개 인터넷에 올라가고, 그 포트를 찾아낸 사람이 곧 에이전트를 쥡니다. OpenClaw 자체 문서도 같은 말을 합니다. SSH 터널을 쓰고, 게이트웨이 포트를 노출하지 마세요. 127.0.0.1에 두고 SSH로 닿으세요.

터널이 연결되지 않을 때

‘Connection refused’, ‘check failed’, 또는 빈 페이지는 보통 다음 중 하나를 뜻합니다:

  • 게이트웨이가 돌지 않거나, 다른 포트에 있습니다. 상자에서 ss -tlnp | grep 18789으로 확인하세요.
  • 로컬 포트 18789이 이미 사용 중입니다. 다른 로컬 포트를 고르세요: -L 28789:127.0.0.1:18789, 그런 다음 http://127.0.0.1:28789을 엽니다.
  • 터널 대신 셸이 떴습니다. -N을 빠뜨린 것입니다.

더 많은 경우는 SSH connection refused와 timed out에 있습니다.

대시보드 터널 유지하기

평범한 ssh -L 터널은 네트워크가 끊기면 멈춥니다. 늘 떠 있는 터널을 원하면 autossh나 작은 systemd 서비스, 또는 알아서 재연결해 주는 터널 매니저를 쓰세요. 로컬·리모트 포워드의 작동 원리는 SSH 포트 포워딩과 터널(영어)에서 다룹니다.

2부 — OpenClaw가 내 다른 서버에서 명령을 실행하게 하기

대부분의 사람이 원하는 부분이 이것입니다. OpenClaw가 서비스가 죽은 것을 보고 실제 상자에서 고칩니다. 흔한 방법은 에이전트에게 SSH 키를 주는 것입니다 — 게이트웨이 호스트의 ~/.ssh에 있는 키, 또는 ClawHub의 SSH 스킬입니다. 됩니다. 그리고 가장 큰 위험을 안고 있는 구성이기도 하므로, 손을 뻗기 전에 이해해 둘 가치가 있습니다.

위험한 부분: 게이트웨이 위의 키

스킬 마켓플레이스는 내가 쓰지 않은 코드가 내 키 옆에서 돌아가는 것입니다. 2026년 초 Koi Security의 ‘ClawHavoc’ 연구는 ClawHub 스킬 2,857개를 감사해 341개를 악성으로 표시했습니다. 여럿이 SSH 키와 자격 증명을 훔치도록 설계됐고, 대부분은 가짜 ‘사전 요구 사항’을 통해 AMOS 스틸러를 설치했으며, 일부는 에이전트 자신의 .env 파일을 빼냈습니다.

여기에 모든 에이전트가 가진 실패 양식 — 에이전트가 읽는 웹 페이지나 이메일로부터의 프롬프트 인젝션 — 을 더하면 결과는 뻔합니다. 게이트웨이 위의 SSH 키 하나는 그 키를 신뢰하는 모든 호스트에 대한 완전한 셸이고, 에이전트를 조종할 수 있는 무엇이든 거기에 닿습니다. 그 키를 해지하려면 그 모든 호스트에서 키를 교체해야 합니다.

그래서 2부의 목표는, 에이전트 — 또는 악성 스킬 — 가 빼낼 수 있는 키 없이 OpenClaw가 내가 원하는 명령을 실행하게 하는 것입니다.

키 없는 경로: Connector, 그다음 원격 MCP 서버로서의 Termalin

두 조각입니다.

먼저, OpenClaw가 닿기를 원하는 서버마다 Termalin Connector를 설치하세요. 한 줄 설치이고 아웃바운드 전용입니다. 포트에서 절대 수신 대기하지 않으므로 NAT나 CGNAT 뒤에서도 되고, 방화벽에 아무것도 열 필요가 없습니다. 등록하면 서버의 sshd가 Termalin의 SSH 인증 기관을 신뢰하도록 설정되고, 이후 모든 로그인은 내 계정용으로 발급된 단기 인증서를 씁니다. 장기 키가 상자에 놓이지 않고, 에이전트에게 건네지는 것도 전혀 없습니다.

둘째, Termalin을 원격 MCP 서버로 OpenClaw에 추가하세요. MCP(영어)는 OpenClaw가 자체 제공하지 않는 도구와 대화하는 방식입니다. Termalin의 호스팅 엔드포인트는 Connector로 등록한 서버들을 도구로 노출합니다. hosts_list, ssh_exec, ssh_exec_many, SFTP 읽기·쓰기, server_metrics, alerts_list 등입니다.

OpenClaw는 ~/.openclaw/openclaw.json에서 JSON5 설정을 읽고 자동으로 다시 로드합니다. 먼저 함정 하나. transport를 빼면 현재 OpenClaw(2026.10.x)는 기본값으로 SSE를 씁니다. Termalin은 Streamable HTTP로 말하므로, "transport": "streamable-http"를 설정해야 하고, 그러지 않으면 연결이 실패합니다.

인증 방법은 두 가지입니다.

API 키 — VPS에서 돌아가는 게이트웨이에 좋습니다. Termalin 웹 캐비닛에서 키를 만들고, 이 에이전트가 손대야 할 서버로 범위를 좁히고, 그 값을 환경 변수 TERMALIN_API_KEY로 넣으세요. 그런 다음 명령 하나로 서버를 추가하세요:

openclaw mcp set termalin '{"url":"https://termal.in/api/v1/mcp","transport":"streamable-http","headers":{"Authorization":"Bearer ${TERMALIN_API_KEY}"}}'

또는 같은 내용을 ~/.openclaw/openclaw.json에 적으세요:

{
  "mcp": {
    "servers": {
      "termalin": {
        "url": "https://termal.in/api/v1/mcp",
        "transport": "streamable-http",
        "headers": {
          "Authorization": "Bearer ${TERMALIN_API_KEY}"
        }
      }
    }
  }
}

리터럴 키가 아니라 ${TERMALIN_API_KEY} 참조를 쓰세요. openclaw mcp doctor는 토큰이 headers에 그대로 적혀 있으면 경고하고, 로그에서는 헤더 값을 가립니다.

OAuth — 사람이 직접 로그인할 때 좋습니다. 서버가 https://termal.in/mcp를 가리키게 하고, auth를 oauth로 설정한 다음 로그인하세요:

openclaw mcp set termalin '{"url":"https://termal.in/mcp","transport":"streamable-http","auth":"oauth"}'
openclaw mcp login termalin
openclaw mcp doctor termalin --probe

openclaw mcp login은 인증 URL을 출력하고 루프백 콜백(http://127.0.0.1:<port>/callback)을 기다립니다. Termalin의 OAuth는 그런 루프백 리디렉션 URI를 받아들이므로, 브라우저에서 로그인을 승인하면 토큰이 저장됩니다 — 붙여 넣을 키가 없습니다. OpenClaw가 헤드리스 VPS에서 돌고 브라우저가 노트북에 있다면, openclaw mcp login termalin --code <code>로 직접 마무리하세요. auth: "oauth"가 설정되면 OpenClaw는 그 서버에 대한 정적 Authorization 헤더를 모두 무시하므로, 방법은 하나만 고르세요.

어느 쪽이든, openclaw mcp doctor termalin --probe가 서버에 닿는지 확인하고 도구 목록을 보여 주며, 그러면 Termalin 도구들이 에이전트에 나타납니다. (Control UI에서도 서버를 추가할 수 있습니다: 채팅 → + → Connectors → Add MCP server…, 관리자 전용.)

먼저 무엇을 할 수 있는지 정하고, 전부 기록하기

상시 돌아가는 에이전트는 작게 시작해야 합니다. Termalin의 AI 앱 카드에서 이 연결에 명령 정책을 주세요. 읽기 전용, 정확한 명령의 허용 목록, 또는 전체 액세스입니다. 읽기 전용으로 시작하세요 — ‘내 서버들 어때’, 디스크, 실패한 서비스, 로그의 마지막 몇 줄을 server_metrics와 alerts_list로요. 그런 다음 좁은 허용 목록으로, 다시 쓰기로, 한 번에 한 단계씩 넓히세요. 촘촘한 호스트별 명령 허용 목록(영어) 뒤에 있는 논리가 여기에 그대로 적용됩니다.

에이전트가 실행하는 모든 것이 기록에 남습니다. 각 명령은 세션 녹화, 실시간 워치 그리드, 그리고 감사 로그(영어)에 에이전트의 것으로 표시되어 남습니다. 비밀이 여러 호스트에 흩어진 SSH 키가 아니라 Termalin 자격 증명이므로, 에이전트를 끄는 것은 토글 하나이지 키 교체가 아닙니다. 여러 사람이 하나의 OpenClaw를 공유한다면, OpenClaw는 발신자마다 별도의 신원(oauth.identity: "per-requester")을 줄 수 있어 감사 추적이 사람별로 유지됩니다.

MCP 서버가 연결되지 않을 때

  • 연결은 되는데 도구가 안 보이거나, 핸드셰이크에서 실패합니다. transport를 빼서 OpenClaw가 SSE로 돌아간 것입니다. "transport": "streamable-http"를 설정하세요.
  • 401 Unauthorized. API 키가 없거나 범위를 벗어났거나, openclaw mcp login을 돌리지 않은 채 OAuth URL(/mcp)에 있는 것입니다. 키 엔드포인트는 /api/v1/mcp, OAuth 엔드포인트는 /mcp입니다.
  • ${TERMALIN_API_KEY}가 비어서 도착합니다. OpenClaw가 돌아가는 환경에 그 변수가 설정돼 있지 않은 것입니다. 게이트웨이가 시작되는 곳에서 export 하세요.
  • 있어야 할 서버가 hosts_list에 없습니다. 아직 Connector가 없거나, 키의 범위 밖입니다.

openclaw mcp status --verbose와 openclaw mcp doctor termalin --probe를 돌려 어느 단계에서 실패하는지 보세요.

공정한 대안들

키 없는 경로가 유일한 길은 아닙니다. 필요에 따라 다른 두 가지도 합리적입니다.

에이전트에게 키를 직접 주기. 게이트웨이 호스트의 ~/.ssh에 SSH 키를 두거나, 키·비밀번호·볼트 항목을 읽는 ClawHub SSH 스킬(ssh-executor, ssh-full, sshx 등)을 설치합니다. 설정이 가장 빠르고 호스팅되는 것에 의존하지 않습니다. 맞교환은 바로 위에서 설명한 위험입니다. 키는 에이전트가 실행하는 무엇에게나 읽히고, 그 범위는 그 키를 신뢰하는 모든 호스트이며, 해지하려면 그 전부에서 키를 교체해야 합니다. 이렇게 한다면, 전용 저권한 키를 쓰고, authorized_keys의 command=으로 강하게 제한하고, 개인 키는 절대 재사용하지 마세요.

키를 쥐는 독립형 SSH-MCP 서버 돌리기. ssh_exec 도구를 갖춘 작은 셀프 호스팅 MCP 서버는 키를 모델의 컨텍스트 밖, 자기 설정 안에 둡니다. 이건 진짜 개선입니다 — 새어 나간 대화 기록에 더는 자격 증명이 들어 있지 않습니다. 하지만 이런 서버는 대부분 명령 정책도, 라이브 뷰도, 감사 추적도 없이 출시되므로, 어떤 도구 호출이든 설정된 어느 호스트에서나 무엇이든 실행할 수 있고, 무슨 일이 있었는지에 대한 기록은 에이전트가 보고하는 것이 전부입니다. 저희는 이것들과 그 밖의 모든 구성을, 침해가 치르는 비용으로 AI 에이전트에게 SSH 액세스 주기, 폭발 반경으로 보기(영어)에서 순위 매겼습니다.

자주 묻는 질문

OpenClaw는 MCP를 지원하나요? 네. 현재 OpenClaw(2026.10.x)는 원격 MCP 서버에 HTTP로 연결합니다. openclaw mcp set이나 openclaw mcp add로, 또는 Control UI에서(채팅 → + → Connectors → Add MCP server…, 관리자 전용) 추가하세요. Termalin 같은 서버에는 "transport": "streamable-http"를 설정하세요. 그러지 않으면 기본값이 SSE이기 때문입니다.

OpenClaw가 내 서버에 SSH로 들어올 수 있나요? 두 가지로 가능합니다. 직접, exec 도구나 ClawHub SSH 스킬로 키를 준다면요. 또는 키 없이, 대신 액세스를 쥐어 주는 MCP 서버에 연결해서요 — 위의 Connector + MCP 구성으로, 키가 에이전트에 결코 닿지 않습니다.

OpenClaw에게 내 SSH 키를 줘도 안전한가요? 고위험으로 다루세요. 게이트웨이 위의 키는 에이전트가 따르는 어떤 스킬이나 주입된 지시로도 읽힐 수 있고, ClawHub는 바로 그것을 훔치도록 만들어진 스킬을 출시한 적이 있습니다(Koi Security가 2026년 초 341개의 악성 스킬을 표시했습니다). 꼭 해야 한다면, command= 제한을 건 일회용 저권한 키를 쓰세요 — 개인 키는 절대 안 됩니다.

‘openclaw ssh connection refused’는 어떻게 고치나요? 대시보드 터널이라면, 게이트웨이가 돌고 있고 127.0.0.1:18789에 묶여 있는지(상자에서 ss -tlnp | grep 18789) 확인하고, 로컬 포트가 비어 있는지 확인하고, ssh -L 명령에 -N을 유지하세요. 더 많은 경우는 SSH connection refused와 timed out에 있습니다.

포트를 열어야 하나요? 아니요. 대시보드 터널은 이미 있는 SSH 연결을 쓰고, Termalin Connector는 아웃바운드 전용입니다 — 포트에서 절대 수신 대기하지 않으므로, 방화벽에 아무것도 열지 않고 NAT와 CGNAT 뒤에서 됩니다.


Termalin은 호스팅 MCP 서버, 키 커스터디언(사용자 대신 키를 보관하고 서명하는 구성 요소), 호스트별 에이전트 정책을 갖춘 크로스 플랫폼 SSH 클라이언트입니다. 호스팅 엔드포인트와 Connector 기반 액세스는 Pro(월 $10, 연간 결제 시 월 $8)와 Team에서 제공되며, 14일 Pro 체험은 카드가 필요 없습니다 — MCP, Connector, 또는 AI 에이전트를 위한 SSH를 보세요.

호스트 한 대에서 먼저 써 보세요.

Termalin은 여러분과 여러분의 에이전트를 위한 빠른 SSH 클라이언트입니다.

무료 요금제 · Pro 14일 무료 체험 · 요금