티스토리 뷰

WSL2 + OpenClaw + Tailscale 원격 접속 완전 가이드

Windows 11 Host의 WSL2(ubuntu)에 설치된 OpenClaw를 Tailscale을 통해 외부에서 안전하게 접속하는 방법과, 삽질 끝에 찾아낸 WSL2 특유의 주의사항을 정리합니다.


환경

항목 내용
Host OS Windows 11
WSL2 배포판 Ubuntu 22.04 (mirrored networking mode)
OpenClaw 2026.4.9 (WSL2 내부 설치)
Tailscale WSL2 내부 설치
Node.js v22.22.0 (nvm)

핵심 결론 (TL;DR)

WSL2 환경에서 OpenClaw를 외부에 노출하려면 아래 4가지를 모두 맞춰야 합니다.

  1. Tailscale을 Windows가 아닌 WSL2 안에 설치해야 한다
  2. bind: "loopback" + tailscale.mode: "serve" 조합으로 Tailscale Serve가 HTTPS를 제공하게 한다
  3. trustedProxies: ["127.0.0.1/32"] 를 설정해 Tailscale Serve의 프록시 헤더를 신뢰한다
  4. allowedOrigins에 포트 없이 https://<hostname>.ts.net 형태로 입력한다
  5. 첫 접속 시 기기 pairing을 서버에서 직접 승인해야 한다

1단계: WSL2에 Tailscale 설치

왜 Windows Tailscale을 쓰면 안 되는가

Windows에 Tailscale을 설치하고 WSL2에서 OpenClaw를 실행하면 다음 오류가 발생합니다.

cause: "pairing-required"
reason: "not-paired"

OpenClaw는 외부에서 접속하는 클라이언트의 신원을 tailscale whois <IP>로 검증합니다. 그런데 Tailscale이 Windows에만 설치되어 있으면 WSL2 프로세스(OpenClaw)는 tailscale whois를 실행할 수 없습니다. Windows의 Tailscale 소켓에 WSL2에서 접근하는 경로가 기본적으로 막혀 있기 때문입니다.

결론: Tailscale은 반드시 WSL2 내부에 설치해야 합니다.

Windows에 Tailscale이 설치되어 있다면 제거하거나, WSL2용을 별도로 추가 설치합니다.

WSL2에 Tailscale 설치

curl -fsSL https://tailscale.com/install.sh | sh

설치 후 로그인:

sudo tailscale up

브라우저에서 인증 URL을 열어 로그인하면 이 WSL2 인스턴스가 tailnet에 등록됩니다.

정상 작동 확인

tailscale status

출력 예시:

100.12.98.78   server1      you@    linux    -
100.12.5.19    server2      you@    windows  active; direct ...
100.12.123.5   server3      you@    iOS      offline

sudo 없이 아래 명령이 실행되어야 합니다:

tailscale whois 100.12.98.78

2단계: OpenClaw 설정

~/.openclaw/openclaw.jsongateway 섹션을 아래와 같이 설정합니다.

{
  "gateway": {
    "port": 18789,
    "mode": "local",
    "bind": "loopback",
    "trustedProxies": ["127.0.0.1/32"],
    "auth": {
      "mode": "token",
      "token": "여기에_토큰_입력",
      "allowTailscale": true
    },
    "tailscale": {
      "mode": "serve"
    },
    "controlUi": {
      "allowedOrigins": [
        "http://localhost:18789",
        "http://127.0.0.1:18789",
        "https://<hostname>.ts.net"
      ]
    }
  }
}

설정들의 이유

bind: "loopback"

"loopback"으로 설정하면 OpenClaw가 127.0.0.1에만 바인딩됩니다. Tailscale Serve가 HTTPS를 받아서 내부의 HTTP로 프록시하는 구조이므로, 외부에 HTTP를 직접 노출할 필요가 없습니다.

만약 "lan"으로 설정하면 LAN IP에 HTTP로 노출되는데, 이 경우 브라우저가 secure context가 아님을 감지해 일부 기능(카메라, 클립보드 등)이 차단됩니다.

tailscale.mode: "serve"

OpenClaw가 시작할 때 자동으로 tailscale serve --bg http://127.0.0.1:18789를 실행합니다. 이렇게 하면 https://<hostname>.ts.net으로 들어온 요청이 내부의 HTTP gateway로 프록시됩니다.

수동으로 확인하려면:

tailscale serve status

출력:

https://<hostname>.ts.net (tailnet only)
|-- / proxy http://127.0.0.1:18789

trustedProxies: ["127.0.0.1/32"]

Tailscale Serve는 요청을 127.0.0.1에서 오는 것으로 전달하면서 X-Forwarded-For 헤더에 실제 클라이언트 IP를 담습니다. 이 설정이 없으면 다음 경고가 발생하고 클라이언트 신원 검증이 실패합니다:

Proxy headers detected from untrusted address. Connection will not be treated as local.
Configure gateway.trustedProxies to restore local client detection behind your proxy.

127.0.0.1/32를 신뢰 목록에 추가하면 X-Forwarded-For의 IP를 실제 클라이언트 IP로 인식합니다.

allowedOrigins에서 포트 제거

Tailscale Serve는 HTTPS 443 포트로 서비스합니다. 따라서 allowedOrigins에 포트를 붙이면 안 됩니다.

// 잘못된 예 (origin mismatch 발생)
"https://<hostname>.ts.net:18789"

// 올바른 예
"https://<hostname>.ts.net"

allowTailscale: true

Tailscale 네트워크를 통해 접속하는 기기가 Tailscale 신원으로 인증될 수 있도록 허용합니다.


3단계: Gateway 재시작

설정을 변경했으면 Gateway를 재시작합니다.

openclaw gateway restart

서비스로 설치하지 않은 경우:

openclaw gateway run

4단계: 기기 Pairing 승인

이것이 가장 놓치기 쉬운 단계입니다.

첫 접속 흐름

외부 기기에서 처음 OpenClaw에 접속하면 UI가 pairing 요청을 서버에 보냅니다. 서버가 이 요청을 승인하기 전까지는 접속이 차단됩니다.

접속 URL

https://<hostname>.ts.net/#token=<your-token>

토큰은 URL의 해시 프래그먼트(#)에 붙여야 합니다. Control UI JavaScript가 이것을 읽어서 인증에 사용합니다. 토큰 입력창에 직접 입력하는 방식은 동작하지 않을 수 있습니다.

대기 중인 Pairing 요청 확인

서버(WSL2)에서 아래 명령으로 대기 중인 요청을 확인합니다:

openclaw devices list

Pairing 승인

# requestId를 지정해서 승인
openclaw devices approve <requestId>

# 또는 가장 최근 요청을 바로 승인
openclaw devices approve --latest

승인 후 다시 확인:

openclaw devices list
# Pending (0), Paired (N+1) 으로 바뀌면 성공

이후 해당 기기는 재접속 시 자동으로 인증됩니다.


WSL2 Networking 관련 주의사항

Mirrored Mode vs NAT Mode

WSL2의 네트워킹 모드에 따라 동작이 다를 수 있습니다.

  • Mirrored Mode (Windows 11 22H2+, 권장): WSL2가 Windows와 동일한 네트워크 인터페이스를 공유합니다. Tailscale이 WSL2 내부에 설치되면 tailnet IP가 WSL2에 직접 할당됩니다.
  • NAT Mode (기본값): WSL2는 가상 NAT 뒤에 있습니다. Tailscale이 WSL2 내부에서도 작동하지만, Mirrored Mode보다 설정이 복잡할 수 있습니다.

Mirrored Mode 활성화는 %USERPROFILE%\.wslconfig에서:

[wsl2]
networkingMode=mirrored

변경 후 PowerShell에서:

wsl --shutdown

Tailscale whois 권한

tailscale whoissudo 없이 실행될 수 있어야 합니다. 설치 직후에는 sudo가 필요할 수 있지만, 정상적으로 설치되면 일반 사용자 권한으로도 실행됩니다.

tailscale whois 100.12.5.19  # sudo 없이 실행되어야 함

자주 발생하는 오류와 해결

pairing-required / not-paired

가장 흔한 오류. 두 가지 원인이 있습니다.

원인 1: Tailscale이 WSL2에 없음

# Windows Tailscale이 아닌 WSL2에 설치되어 있는지 확인
which tailscale
tailscale --version

원인 2: 기기 pairing 미승인

openclaw devices list
openclaw devices approve --latest

Proxy headers detected from untrusted address

trustedProxies가 설정되지 않았을 때 발생합니다.

"trustedProxies": ["127.0.0.1/32"]

origin not allowed (CORS 오류)

allowedOrigins에 포트가 붙어 있거나, https:// 대신 http://를 쓴 경우입니다.

// 수정 전 (잘못됨)
"https://<hostname>.ts.net:18789"

// 수정 후 (올바름)
"https://<hostname>.ts.net"

Rate Limit (토큰 실패 반복 시)

토큰 입력 실패가 반복되면 rate limit이 걸립니다.

openclaw gateway restart

502 Bad Gateway

Tailscale Serve는 설정되어 있는데 OpenClaw Gateway가 내려간 경우입니다.

openclaw gateway status
openclaw gateway start

최종 설정 요약

{
  "gateway": {
    "port": 18789,
    "mode": "local",
    "bind": "loopback",
    "trustedProxies": ["127.0.0.1/32"],
    "auth": {
      "mode": "token",
      "token": "<your-token>",
      "allowTailscale": true
    },
    "tailscale": {
      "mode": "serve"
    },
    "controlUi": {
      "allowedOrigins": [
        "http://localhost:18789",
        "http://127.0.0.1:18789",
        "https://<hostname>.ts.net"
      ]
    }
  }
}

접속 URL:

https://<hostname>.ts.net/#token=<your-token>

연결 흐름 정리

[외부 기기 브라우저]
        |
        | HTTPS (Tailscale 암호화 + 443포트)
        v
[Tailscale Serve] ← WSL2 내부에서 실행 중
        |
        | HTTP 프록시 (127.0.0.1:18789)
        | X-Forwarded-For: <외부 기기 tailnet IP>
        v
[OpenClaw Gateway] (bind: loopback)
        |
        | tailscale whois <X-Forwarded-For IP>
        v
[Tailscale daemon] ← WSL2 내부에 설치되어야 함

Tailscale이 WSL2 안에 있어야 하는 이유가 바로 마지막 화살표입니다. OpenClaw가 클라이언트 신원을 검증하기 위해 tailscale whois를 호출하는데, 이 명령은 같은 OS 환경의 Tailscale daemon에만 접근할 수 있습니다.


참고

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함