원문 캡처 · hol.org
원문 캡처 · hol.org

tailnet의 노트북이나 CI 실행기가 침해되면, 공격자는 해당 기기가 Tailscale SSH로 접근할 수 있는 서버에서 루트 권한을 얻을 수 있었다. Tailscale은 SSH 소켓 전달 취약점을 1.104.4에서 수정했으며, 업데이트 전에는 전달 기능을 끄라고 권고한다.

Cyberdione Labs는 수정 사항이 나오기 전인 10월 25일 이 취약점을 공개하고 ‘Tailworm’이라고 불렀다. Tailscale은 10월 27일 1.104.4를 태그했고, 같은 날 오후 9시 5분(미 동부시간)에 TS-2026-014부터 TS-2026-017까지 보안 공지와 함께 GitHub 릴리스를 공개했다.

핵심 취약점인 TS-2026-014는 SSH 전달 과정에서 발생했다. 연구진의 실험실에서는 사용자 조작 없이 서버를 거칠 때마다 1초 이내에 다른 서버로 확산됐다. 실험은 수정되지 않은 1.104.2와 headscale 0.29.5에서 이뤄졌다. Tailscale과 보고서 모두 실제 환경에서 악용됐다는 내용은 언급하지 않았다.

업데이트와 임시 조치

Tailscale SSH 또는 tailscale serve를 실행하는 모든 노드를 1.104.4 이상으로 업데이트해야 한다.

sudo tailscale update # Linux and other installs that support self-update tailscale version # first line must read 1.104.4 or higher

패키지 미러나 이미지에 아직 1.104.4가 없다면, 업데이트할 때까지 Tailscale SSH의 전달 기능을 꺼야 한다. Tailscale이 권고한 임시 조치로, SSH 자체는 계속 작동하며 루트 권한 상승으로 이어지는 전달 경로를 차단한다.

# Debian/Ubuntu/RHEL packages read /etc/default/tailscaled echo 'TS_SSH_DISABLE_FORWARDING=1' | sudo tee -a /etc/default/tailscaled sudo systemctl restart tailscaled

업데이트만으로는 정책이 바뀌지 않으므로 SSH 규칙도 수정해야 한다. ‘모든 구성원에서 모든 태그 서버로’ 허용하는 대신 출발지와 목적지를 구체적인 쌍으로 지정하고, SSH 대상으로 root나 비밀번호 없는 sudo 계정을 허용하지 말아야 한다. 실험실에서는 출발지·목적지 쌍으로 규칙을 제한하는 것만으로 확산을 막았다. Tailscale의 호스팅 제어 평면에서는 SSH 규칙별로 전달을 거부할 수도 있다. headscale 0.29.5에는 이 설정이 없어, 보고서는 그 환경의 모든 SSH 허용 규칙을 대상 서버의 루트 권한과 같은 위험으로 본다.

취약점과 수정 사항

수정 전 Tailscale SSH는 전달되는 유닉스 소켓 경로가 허용 목록에 있는지 이름으로 확인한 뒤, 루트 권한으로 연결하거나 소켓을 만들고 삭제했다. 이로 인해 세 가지 공격 경로가 생겼으며, 모두 TS-2026-014에서 수정됐다.

  • ssh -L로 유닉스 소켓에 연결하면 일반 SSH 세션에서 Docker 소켓이나 tailscaled 로컬 API처럼 루트 전용 소켓에 접근할 수 있었다.
  • ssh -R은 루트 소유 소켓을 삭제하고 공격자의 리스너로 대체할 수 있었다.
  • 경로 확인과 사용 사이에 경쟁 조건이 있어 허용 목록을 우회할 수 있었다. 확인 뒤 커널이 경로를 다시 해석하기 때문이다.

이번 수정은 허용 목록을 고치는 대신 작업에서 루트 권한을 제거했다. v1.104.2와 v1.104.4 사이의 변경 사항은 연결별 모니터를 통해 전달을 처리한다. 모니터는 각 연결·소켓 생성·삭제 작업을 로그인한 세션 사용자 권한으로 실행되는 하위 프로세스에 맡긴다. 이제 경계는 커널의 파일 권한이다. OpenSSH는 원래 같은 방식으로 작동하며, Dropbear도 유사한 취약점인 CVE-2025-14282를 수정한 뒤 같은 방식을 사용한다.

1.104.4에는 다음 보안 수정도 포함됐다.

  • TS-2026-015: 인증된 SSH 세션에서 창 크기 변경 메시지와 환경 변수 추가를 반복해 tailscaled 메모리를 제한 없이 늘릴 수 있었다. 메모리 부족 종료 장치가 데몬을 종료하면 해당 노드의 모든 Tailscale 연결도 영향을 받았다.
  • TS-2026-016: tailscale serve --tcp가 유닉스 소켓에 루트 권한으로 연결해 tailscaled 로컬 API에 접근할 수 있었다. 이는 노드 전체를 장악하는 경로다. HTTP 백엔드의 심볼릭 링크 방어는 설정을 다시 불러올 때만 작동해 이후 경로를 바꿀 수 있었다. 이제 Serve는 데몬 소켓 연결을 거부하고 연결할 때마다 다시 확인한다.
  • TS-2026-017: TLS를 통한 Serve에서 한 연결의 HTTP/2 스트림이 같은 컨텍스트를 공유해, 한 마운트용 Tailscale-App-Capabilities 값이 다른 마운트 요청으로 넘어갈 수 있었다. 앱이 이 헤더를 권한 확인에 사용하고, 한 노드에 서로 다른 기능 규칙을 적용한 마운트가 둘 이상 있을 때만 해당한다.

노드와 정책 확인

재시작을 예약하기 전에 노드 상태를 확인할 수 있다.

tailscale version # below 1.104.4 = unpatched tailscale debug prefs | grep -i runssh # "RunSSH": true means Tailscale SSH is on tailscale serve status # look for TCP forwards to unix: paths systemctl show tailscaled -p Environment # confirms TS_SSH_DISABLE_FORWARDING=1 took

그다음 tailnet 정책 파일의 ssh 항목을 확인한다. src가 그룹이나 autogroup:member이고 dst가 여러 서버를 포함하는 태그인 규칙은 한 기기의 침해가 서버 전체로 번질 수 있게 한다.

확인 모드(check mode)도 이 문제를 막아주지 않는다. "action": "check"인 Tailscale SSH 규칙은 세션을 시작하기 전에 다시 로그인하도록 하지만, 전달 취약점은 이미 승인된 세션 안에서 작동했다. 호스팅 제어 평면에서는 기본 12시간인 확인 기간 동안 한 번 승인하면 확인 모드가 적용된 모든 목적지에 접근할 수 있다. 따라서 확인 모드 서버도 노출된 것으로 봐야 한다.

영향 범위와 제외 대상

영향을 받는 대상은 Tailscale SSH를 사용하거나 유닉스 소켓 백엔드와 함께 tailscale serve를 실행하는 노드다. 노드 사이의 일반 WireGuard 메시 트래픽은 해당하지 않는다. tailnet을 통해 일반 OpenSSH로 접속하는 서버도 영향 범위가 아니다. OpenSSH는 전달 전에 권한을 세션 사용자로 낮춘다.

Tailnet Lock을 켠 tailnet에서는 실험실에서 공격자가 등록 비밀을 탈취하더라도 악성 노드를 등록하는 단계까지 완료하지 못했다. 다만 대상 서버에서 루트 권한을 얻는 데는 성공했다.

자체 호스팅 제어 서버는 별도로 패치해야 한다. headscale의 메모리 고갈 문제와 실험 단계인 앱 커넥터의 송신 트래픽 취약점은 1.104.4로 해결되지 않았다. 앱 커넥터 문제는 일부만 수정됐고 관련 PR이 열려 있다. 보고서는 headscale 0.29.6 이하에도 임시 지침을 적용하라고 권고한다.

이번 취약점은 인터넷에서 인증 없이 원격 침입하는 문제가 아니다. 공격자는 먼저 tailnet에 있는 기기를 장악하고, SSH 규칙을 통해 대상 서버에 접근할 수 있어야 한다. Tailscale 엔지니어링 부사장 마이크 셰이버(Mike Shaver)는 SecurityWeek에 “인증되지 않은 공격자가 임의의 기기에 연결할 수 있는 상황과는 다르다”고 말했다.

보고서는 취약한 웹 앱, 변조된 패키지, 피싱된 로그인 정보를 최초 침투 경로로 들었다. README의 지시에 따라 무엇이든 설치하는 AI 코딩 에이전트를 실행하는 개발자 노트북도 예로 제시했다. 그런 기기가 SSH 권한을 가진 상태로 tailnet에 연결되면, 기존 신뢰 모델에서는 그 기기가 접근할 수 있는 모든 대상을 장악할 수 있었다.

보고서 작성 당시에는 취약점에 대한 CVE 식별자가 공개되지 않았다. 추적할 식별자는 Tailscale 보안 공지 번호다.

참고 자료: