테일스케일, 토큰 하나로 초당 보안 터널 여는 '테일캣' 공개
Tailscale이 자사 오픈소스 구성요소를 재조합해 만든 'Tailcat'을 공개했습니다. Tailcat은 Tailscale의 제어 평면 없이 데이터 평면(magicsock)만 활용해 두 대의 머신 사이에 WireGuard로 암호화된 P2P 터널을 몇 초 만에 구축하는 netcat 스타일 도구입니다. 계정이나 루트 권한 없이 사용자 공간(userspace)에서 동작하며, NAT 통과 실패 시 DERP 릴레이를 경유하고, 가능하면 직접 P2P UDP 연결로 업그레이드됩니다.
"Tailscale이 만든, Tailscale 없는 Tailscale"
Tailcat은 Tailscale 오픈소스 구성요소들을 재조합하여 netcat처럼 동작하지만 Tailscale의 제어 평면 없이 데이터 평면 위에서 작동하는 도구입니다.
Tailscale의 데이터 평면(내부적으로 magicsock)은 두 머신 사이에 point-to-point WireGuard® 암호화 터널을 제공하며, DERP가 NAT 홀펀칭 통신용 사이드 채널 및 NAT 통과 실패 시의 최종 릴레이 역할을 합니다.
Tailscale 제어 평면을 사용하는 대신, 모든 tailcat 연결 메타데이터는 원하는 어떤 방식으로든 대역 외(out of band)로 교환됩니다.
tailcat CLI(cmd/tailcat에 위치)는 tailcat Go 라이브러리(github.com/tailscale/tailcat로 임포트 가능) 위에 구축되었습니다. CLI 도구나 라이브러리 어느 쪽으로 사용하든, 한쪽은 tailcat 서버(리스너)를 실행하고 짧은 연결 토큰을 받습니다. 다른 쪽은 그 토큰을 tailcat 클라이언트에 전달해 연결합니다.
양쪽 간의 모든 트래픽은 WireGuard로 종단 간 암호화됩니다. 초기 연결은 Tailscale의 DERP 릴레이 네트워크를 통해 부트스트랩되며, 이후 magicsock이 NAT 통과를 수행해 가능한 경우(보통 가능합니다!) 직접 P2P UDP 연결로 업그레이드합니다.
Tailscale 계정도, 머신의 root/admin 권한도 필요 없습니다(머신의 라우팅 테이블이나 DNS 등을 변경하지 않습니다). 순수한 사용자 공간 라이브러리이자 CLI 도구이며, 모두 오픈소스입니다. 무료 속도 제한 DERP 릴레이(기본 DERP 맵: https://tailcat.dev/derpmap.json)를 사용하거나 직접 운영할 수도 있습니다.
사용법
두 머신 간 stdin/stdout 파이프
서버가 시작되며 임시 주소를 출력합니다:
$ tailcat
선택된 부트스트랩 릴레이 지역 302, 샌프란시스코
🐈 서버가 새 주소로 리스닝 중: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
(대기 중...)
클라이언트는 다음과 같이 실행합니다:
$ echo hello | tailcat tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu $
그러면 서버가 차단 해제되며:
$ tailcat
선택된 부트스트랩 릴레이 지역 302, 샌프란시스코
🐈 서버가 새 주소로 리스닝 중: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
hello $
터널을 통한 로컬 포트 노출
로컬 TCP 포트를 서빙하도록 설정할 수도 있습니다(localhost로 포워딩):
$ tailcat --serve=8080,8443 # 또는 --serve=all
🐈 서버가 새 주소로 리스닝 중: tcXXXXXXXXX
클라이언트:
$ tailcat tcXXXXXXXXX 8080 GET / HTTP/1.1 Host: foo HTTP/1.1 200 OK ....
인증 없는 SSH 서버
Linux와 macOS에서는 인증 없는 SSH 서버도 실행할 수 있습니다. (인증을 원한다면 tailcat --serve=22로 시스템 SSH 서버에 프록시하면 됩니다)
$ tailcat --serve=no-auth-ssh
🐈 서버가 새 주소로 리스닝 중: tcXXXXXXXXX
클라이언트 쪽:
$ tailcat ssh tcXXXXXXXXX $ tailcat ssh tcXXXXXXXXX ls -la
기타 명령
연결 테스트용 ping: 각 pong은 DERP 릴레이 경유인지 직접 경로인지 보고합니다. --until-direct는 직접 경로가 작동할 때까지(--timeout, 기본 10초) 계속 핑을 보내며, 실패 시 0이 아닌 값으로 종료합니다:
$ tailcat ping --until-direct
터널을 경유하는 SOCKS5 프록시를 통해 명령 실행:
$ tailcat socks
토큰은 URL 호스트명으로도 직접 사용할 수 있습니다: SOCKS 프록시가 이를 인식하여 다이얼하므로 토큰 인자는 선택 사항입니다. (토큰은 대소문자를 구분하며, curl과 대부분의 CLI 도구에서 동작하지만 호스트명을 소문자로 바꾸는 브라우저에서는 동작하지 않습니다.)
$ tailcat socks curl http://
클라이언트가 서버의 네트워크에 접근할 수 있도록 exit node로 동작:
$ tailcat --serve=exit-node
연결 토큰을 파싱하여 내용(서버의 WireGuard 공개 키와 DERP 정보)을 아무것에도 연결하지 않고 JSON으로 출력:
$ tailcat parse tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu { "ServerPublic": "nodekey:9c8d2e6728da80a1dd37e275a82595b42d9a838610bc53f74a7670d1610f2e34", "RegionID": 302 }
짧은 토큰(ID로 DERP 지역을 참조하므로 클라이언트가 DERP 맵을 가져와야 함)을 더 긴 자기 완결형 토큰으로 변환하는 것도 가능합니다.