Tailscale이란 무엇이며 어떻게 작동하나요?
Tailscale의 핵심 작동 원리인 WireGuard 기반 피어 투 피어 연결과 조정 서버의 역할을 설명합니다. NAT 통과, DERP 릴레이, 키 관리 및 보안 모델을 포함한 기술적 구조를 상세히 분석하여 VPN 구축 과정을 이해하도록 돕습니다.
Tailscale이란 무엇인가?
Tailscale은 사용자가 운영하는 단일 게이트웨이로 모든 트래픽을 라우팅하는 대신, 기기들을 서로 직접 연결하는 VPN입니다. 모든 노드는 WireGuard를 실행하므로 패킷은 한 서버에서 다른 서버로 암호화되어 이동하며, 경로상의 그 누구도 패킷을 읽을 수 없습니다. 호스팅된 조정 서버(coordination server)가 연결을 중재합니다. 이 서버는 공개 키를 저장 및 배포하고 각 노드에 다른 노드의 위치를 알려줍니다. 또한 사용자가 작성한 접근 규칙을 각 노드에 전달합니다.
이러한 분리 구조가 전체 설계의 핵심입니다. 데이터 평면은 피어 투 피어(peer to peer) 방식이며 노드 간 암호화가 이루어집니다. 제어 평면은 Tailscale이 사용자를 대신해 운영하는 서비스입니다. 신뢰 문제와 같은 불편한 질문을 포함하여 Tailscale에 관한 모든 중요한 의문은 이 두 가지 사실에서 비롯됩니다. 이미 VPS에 수동으로 WireGuard VPN을 구축해 본 경험이 있다면, Tailscale은 키 배포와 방화벽 통과 과정을 자동으로 처리해 주는 동일한 터널이라고 이해하면 됩니다.
Tailscale은 어떻게 작동합니까?
사용자의 노드로 구성된 사설 네트워크를 tailnet이라고 부릅니다. 기기가 tailnet에 참여하면 다음 네 가지 과정이 일어납니다.
tailscaled데몬이 시작되고 WireGuard 키 쌍을 생성하며, 상태를/var/lib/tailscale/tailscaled.state에 저장합니다. 개인 키는 해당 기기 내부에만 남습니다. Tailscale은 "개인 키는 그 어떤 경우에도 노드 밖으로 나가지 않는다"고 명확히 밝히고 있습니다.- 노드가 조정 서버(coordination server)에 로그인하여 자신의 공개 키와 자신이 도달 가능하다고 판단하는 주소들을 업로드합니다. Tailscale은 이 서버를 "공개 키를 위한 공유 드롭박스"라고 설명합니다.
- 조정 서버는 네트워크 맵을 반환합니다. 여기에는 해당 노드가 접근 권한을 가진 모든 노드의 공개 키, tailnet 주소, 기기 이름, 그리고 후보 엔드포인트 정보가 포함됩니다.
- 각 노드 쌍은 서로 직접적인 WireGuard 터널을 구축하려고 시도합니다. 연결에 실패하면 패킷을 릴레이를 통해 전송합니다.
각 노드는 100.64.0.0/10 범위 내에서 고정된 주소를 할당받습니다. 이는 100.64.0.0에서 100.127.255.255까지 이어지는 캐리어급 NAT 대역입니다. Tailscale이 이 대역을 사용하는 이유는 서비스 제공자의 인프라를 위해 예약된 공간이므로, 사용자의 서버가 이미 사용 중인 사설 IP 대역과 충돌할 가능성이 낮기 때문입니다. Linux에서 이 터널은 tailscale0라는 이름의 인터페이스로 나타납니다.
WireGuard 구현은 커널 모듈이 아닌 사용자 공간(userspace)의 tailscaled 내부에서 실행됩니다. 이것이 바로 sudo modprobe wireguard이 Operation not supported 오류로 실패하는 컨테이너 가상화 환경에서도 Tailscale이 시작될 수 있는 이유입니다. 또한 이로 인해 특정 장비에서의 처리량 한계가 커널 기반 WireGuard보다 낮아지는데, 이는 일반 WireGuard와 Tailscale 비교에서 다루는 트레이드오프 중 하나입니다.
현재 상태를 확인하려면 다음 두 가지 명령어를 사용합니다.
tailscale ip -4
tailscale statustailscale status는 노드당 한 줄씩 정보를 출력하며, 마지막 열이 가장 중요합니다.
100.101.102.103 web-1 you@ linux -
100.101.102.104 db-1 you@ linux active; direct 198.51.100.24:41641
100.101.102.105 ci-runner you@ linux active; relay "fra"direct 뒤에 주소와 포트가 표시된다면 두 기기가 서로 경로를 찾았으며 트래픽이 피어 투 피어(peer to peer)로 전달되고 있음을 의미합니다. relay "fra"은 프랑크푸르트에 위치한 Tailscale 릴레이를 거치고 있다는 뜻입니다. -는 현재 해당 노드와 활성화된 세션이 없음을 의미하며, 이는 정상적인 상태입니다.
코디네이션 서버가 볼 수 있는 것과 없는 것
코디네이션 서버는 공개 키와 메타데이터를 보유합니다. 이 서버는 사용자의 머신 이름, 각 노드를 소유한 사용자나 태그, 각 노드의 tailnet 주소, 노드에 접근 가능한 공인 주소, 마지막 접속 시점, 그리고 작성한 정책 파일을 알고 있습니다. 이는 전체 장비 구성에 대한 완전한 지도와 같습니다.
서버는 개인 키를 보유하지 않으므로 두 노드 사이의 트래픽을 복호화할 수 없습니다. 암호화는 WireGuard 피어 간의 종단 간(end-to-end) 방식으로 이루어지며, 코디네이션 서버는 피어에 포함되지 않습니다.
서버가 수행할 수 있는 작업은 키를 전달하는 것입니다. 호스팅 방식이든 직접 운영하는 방식이든, 모든 코디네이션 서버는 어떤 공개 키가 tailnet에 속하는지 노드에 알려주는 역할을 신뢰받습니다. 이는 아래에서 다룰 위협 모델의 핵심이며, 직접 호스팅하는 오픈 소스 코디네이션 서버인 Headscale이 존재하는 이유이기도 합니다.
서로 다른 방화벽 뒤에 있는 두 서버가 직접 통신하는 방법
NAT(network address translation)는 여러 대의 기기가 하나의 공인 IP 주소를 공유할 수 있게 합니다. 일반적으로 VPS는 고유한 공인 IP 주소를 가지고 있지만, 테일넷(tailnet)에 포함하려는 다른 기기들(가정용 서버, 사무실 네트워크의 빌드 러너, 설정을 변경할 수 없는 제공자 방화벽 뒤의 장비 등)은 그렇지 않은 경우가 많습니다.
Tailscale은 STUN(session traversal utilities for NAT) 및 ICE 표준을 기반으로 구축된 기술을 사용하여 경로를 찾습니다. 각 노드는 STUN 서버로 작은 UDP 패킷을 보내고, 라우터가 해당 소켓에 할당한 공인 IP 주소와 포트를 확인합니다. 두 노드는 이러한 후보 정보를 조정 서버(coordination server)에 보고하고, 조정 서버는 이를 상대방에게 전달합니다. 그 후 두 노드는 동시에 서로에게 패킷을 보내기 시작합니다. 각 라우터는 아웃바운드 패킷을 먼저 확인하므로 매핑을 생성하고, 동일한 주소에서 도착하는 응답을 허용합니다. 따라서 양쪽 모두 인바운드 방화벽 규칙을 설정할 필요가 없습니다.
포트는 특정되어 있습니다. 직접적인 WireGuard 터널은 기본적으로 41641번 소스 포트를 사용하는 UDP를 사용합니다. STUN은 Tailscale의 릴레이 서버를 대상으로 UDP 3478번 포트에서 실행됩니다. 제어 연결 및 릴레이된 모든 데이터는 TCP 443번 포트에서 HTTPS를 사용합니다. 대부분의 경우 인바운드 포트를 열 필요는 없지만, NAT 환경이 까다로운 네트워크에서는 UDP 41641번 포트의 인바운드를 허용하면 직접 연결될 확률이 높아집니다.
tailscale netcheck해당 보고서의 두 줄을 읽어 보십시오. UDP: true은 UDP가 해당 기기에서 나갈 수 있음을 의미하며, UDP: false는 이 노드에서 발생하는 모든 연결이 릴레이됨을 의미합니다. MappingVariesByDestIP: true는 라우터가 목적지마다 서로 다른 공인 포트를 할당한다는 의미이므로, 위에서 언급한 주소 예측이 작동하지 않아 해당 노드들은 보통 릴레이 상태로 유지됩니다.
Tailscale이 DERP 릴레이를 사용하는 경우
DERP(designated encrypted relay for packets)는 대체 경로입니다. Tailscale은 여러 지역에서 릴레이를 운영하며, 이들은 TCP 443 포트를 통해 접근할 수 있습니다. 직접적인 경로를 확보하지 못한 노드는 WireGuard 패킷을 이 릴레이 중 하나를 통해 전송합니다.
패킷은 암호화된 상태로 유지됩니다. Tailscale은 이를 명확히 밝히고 있습니다. "DERP 서버가 사용자의 트래픽을 복호화할 방법은 없습니다. 서버는 이미 암호화된 트래픽을 한 노드에서 다른 노드로 단순히 전달할 뿐입니다." 릴레이는 암호문과 어떤 노드가 어떤 노드와 통신하는지만 확인할 수 있습니다.
또한 대부분의 연결에서 초기 패킷은 릴레이를 거칩니다. 직접적인 경로를 찾는 데 시간이 걸리기 때문에, 세션은 대개 릴레이 상태로 시작하며 두 노드가 서로를 식별하면 즉시 직접 연결로 전환됩니다. 이 과정을 직접 확인할 수 있습니다.
tailscale ping db-1첫 번째 응답은 via DERP(fra)으로 돌아오며, 이후 줄에서 via 198.51.100.24:41641과 같은 메시지가 보고됩니다. 이 변화는 직접 터널로의 업그레이드를 의미합니다. 만약 상태가 변하지 않는다면 양쪽 끝에서 tailscale netcheck을 실행해 보십시오. 릴레이 경로로도 연결은 정상적으로 작동합니다. 다만 모든 패킷이 제3의 장비를 거쳐 우회하므로 지연 시간이 발생합니다. 만약 연결이 끊긴 것이 아니라 전송 속도가 느린 것이 문제라면, Tailscale 릴레이 연결이 직접 연결보다 훨씬 느린 이유에서 그 차이를 측정하고 VPS를 직접 경로에 배치하는 방법을 확인할 수 있습니다.
VPS를 tailnet에 연결하기
설치 스크립트는 Ubuntu와 Debian을 지원합니다.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale upsudo tailscale up 명령은 URL을 출력합니다. 해당 URL을 열어 인증하면 관리 콘솔에 노드가 나타납니다. 그 후 재부팅 시 데몬이 정상적으로 다시 시작되는지 확인하십시오. 많은 사용자가 이 단계를 간과합니다.
sudo systemctl is-enabled tailscaled
tailscale statusis-enabled 명령은 enabled을 출력해야 하며, tailscale status 명령은 100.x 주소를 가진 새 노드를 목록에 표시해야 합니다. 스크립트로 빌드된 서버의 경우 대화형 URL을 사용할 수 없습니다. 관리 콘솔에서 인증 키(auth key)를 생성하고, 해당 머신의 유형을 기록하는 태그와 함께 전달하십시오.
sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:server태그가 지정된 노드는 명령을 실행한 개인이 아닌 태그가 소유하므로, 해당 사용자의 계정이 삭제되어도 계속 작동합니다. 태그는 먼저 정책 파일의 tagOwners 항목에 선언되어야 하며, 그렇지 않으면 명령이 거부됩니다. 태그 지정은 머신이 요금제에 계산되는 방식에도 영향을 미칩니다. 태그가 지정된 리소스는 개인 기기와 별도로 요금이 책정되며, 무료 티어의 실제 적용 범위에서 해당 제한 사항을 확인할 수 있습니다.
플릿(fleet) 운영 시 두 가지 설정이 중요합니다. 노드 키는 기본적으로 180일 후에 만료됩니다(2026년 8월 기준). 키가 만료되면 누군가 다시 로그인할 때까지 "해당 엔드포인트로의 연결이 중단"되므로, 무인 서버의 경우 관리 콘솔에서 해당 머신 행을 열어 Disable Key Expiry를 선택하십시오. 2022년 10월 20일 이후 생성된 tailnet에서 기본적으로 활성화되는 MagicDNS는 각 노드에 db-1.yak-bebop.ts.net와 같은 이름을 부여하며, 이는 100.100.100.100의 스텁 리졸버(stub resolver)를 통해 해석됩니다. 재빌드된 노드는 새로운 주소를 할당받지만 이름은 유지되므로, IP 주소 대신 이름을 사용하십시오.
apt 또는 저장소 문제로 설치 자체가 실패하는 경우, Ubuntu에서의 일반적인 Tailscale 설치 오류에서 해결 방법을 확인할 수 있습니다.
localhost에 바인딩된 서비스에 접근하기
이 지점에서 tailnet이 유용하게 사용되지만, 많은 사용자가 여기서 어려움을 겪습니다. tailnet에 가입한다고 해서 loopback 서비스에 바로 접근할 수 있는 것은 아닙니다.
ss -tlnp | grep 3000만약 해당 명령이 127.0.0.1:3000을 출력한다면, 해당 소켓은 목적지가 127.0.0.1인 패킷만 수락한다는 의미입니다. 다른 노드에서 보낸 요청은 이 노드의 100.x 주소로 전달되는데, 커널은 해당 주소에서 수신 대기 중인 프로세스가 없으므로 TCP reset으로 응답합니다. 클라이언트는 Connection refused 오류를 보고합니다. 터널은 정상이며, 리스너 설정이 문제입니다.
두 가지 확실한 해결책이 있습니다. 서비스를 노드의 tailnet 주소에 바인딩하면 프록시 없이도 공용 인터페이스를 거치지 않고 안전하게 유지할 수 있습니다. 설정에서 --bind 100.101.102.104 또는 그에 상응하는 옵션을 전달하십시오. 컨테이너의 경우 포트를 -p 100.101.102.104:3000:3000로 게시하십시오. 아니면 서비스를 loopback에 그대로 두고 그 앞에 Tailscale을 배치할 수도 있습니다.
tailscale serve 3000이 방식은 요청을 http://127.0.0.1:3000으로 프록시하며, tailnet에서 HTTPS 인증서가 활성화되면 ts.net 이름을 통해 tailnet 내부에서 서비스를 제공합니다. 이는 노드 간에 비공개로 유지됩니다. 동일한 개념의 공개 버전은 Funnel이며, Tailscale serve와 funnel 비교에서 필요한 방식을 확인할 수 있습니다.
관련된 두 가지 작업은 별도의 페이지에서 다룹니다. Tailscale이 설치되지 않은 사설 네트워크 전체에 접근하려면 VPS를 이용한 서브넷 라우터 설정이 필요하며, 노드의 아웃바운드 인터넷 트래픽을 다른 노드를 통해 보내려면 exit node 설정이 필요합니다.
더 이상 필요하지 않은 포트 닫기
관리자가 tailnet을 통해 서버에 접속할 수 있게 되면, 공개된 22번 포트는 더 이상 할 일이 없습니다. 이것이 실질적인 이점입니다. 닫힌 포트는 무차별 대입 공격(brute force)을 받을 수 없으며, 로그가 공격 시도로 채워지는 일도 멈춥니다.
순서가 중요합니다. 먼저 tailnet 접근 권한을 추가하고, 두 번째 세션을 통해 접속이 가능한지 확인한 뒤에 공개 규칙을 제거하십시오.
sudo ufw allow in on tailscale0
sudo ufw status verbose그 후, 공개 SSH 규칙을 삭제하고 MagicDNS 이름을 사용하여 다시 연결하십시오. ufw allow in on tailscale0가 실제로 수행하는 작업을 유의하십시오. 이 설정은 터널을 통해 들어오는 모든 트래픽을 신뢰하므로, ufw 대신 Tailscale 정책 파일이 접근 제어의 중심이 됩니다. 이 점을 고려하여 정책을 작성하십시오.
컨테이너를 운영하는 사용자에게 한 가지 주의사항이 있습니다. Docker의 포트 게시(publish) 기능은 자체적인 NAT 규칙을 설치하여 ufw를 우회하므로, ufw deny을 실행해도 해당 포트는 닫히지 않습니다. ufw를 우회하는 Docker 게시 포트에서 이 메커니즘을 설명합니다. 위에서 언급한 것처럼 tailnet 주소로 게시하면 이 문제를 피할 수 있습니다. 애플리케이션이 Docker Compose로 실행 중이라면, Compose 스택 내의 Tailscale 사이드카를 사용하여 게시된 포트를 완전히 제거하고, 컨테이너를 오직 tailnet 이름으로만 접근할 수 있게 구성하는 것이 더 안전합니다.
Tailscale이 보호하는 것과 보호하지 않는 것
마케팅 문구는 이 경계를 모호하게 만들기 때문에 명확히 짚고 넘어갈 필요가 있습니다.
보호 대상: 두 노드 사이의 트래픽은 WireGuard로 종단 간 암호화되며, 중간의 릴레이 서버는 이를 읽을 수 없습니다. 개인 키는 키를 생성한 장비를 절대 떠나지 않습니다. 노드는 인바운드 공개 포트가 필요 없으므로, 인터넷에서 스캔할 수 있는 22번이나 5432번 같은 포트가 존재하지 않습니다. 노드 간 접근 권한은 주소를 아는 사람이 아니라 정책 파일에 의해 결정됩니다.
보호되지 않는 대상: 조정 서버(coordination server)는 사용자의 장치 그래프를 볼 수 있습니다. 장치 이름, 소유자, 주소, 온라인 시간은 인프라 정보를 설명하므로 이 메타데이터 자체로도 민감합니다. 또한 이 서버는 키를 배포하는데, 이것이 더 큰 위험 요소입니다. Tailscale은 이를 직접적으로 명시합니다. "Tailscale이 악의를 품고 네트워크에 몰래 새로운 노드를 삽입한다면, Tailscale은 기존 노드와 평문으로 트래픽을 송수신할 수 있습니다." 단일 로그온(SSO) 제공자 역시 동일한 신뢰 경로에 있습니다. 해당 서비스에서 신원을 생성할 수 있는 사람은 누구든 노드를 추가할 수 있기 때문입니다. 또한 침해당한 노드는 tailnet 내부의 피어(peer)가 되므로, 해당 노드가 접근할 수 있는 범위는 사용자의 정책이 허용하는 곳까지입니다. 이것이 수용 가능한 위험인지는 방어 대상에 따라 다르며, 전체 신뢰 모델에서 도난당한 계정으로 무엇을 할 수 있는지 등 각 사례를 상세히 다룹니다.
키 배포 위험에 대한 해결책은 두 가지입니다. 첫 번째는 tailnet lock입니다. 이는 기존의 신뢰할 수 있는 노드들이 새로운 노드를 암호학적으로 서명해야만 다른 노드들이 이를 수락하도록 하는 방식입니다. 유효한 서명 없이 노드를 추가하려는 제어 평면은 무시됩니다. 관리자 콘솔은 서명 노드에 필요한 정확한 tailscale lock init 라인을 생성하며, 모든 노드는 자신이 보는 내용을 확인할 수 있습니다.
tailscale lock status모든 노드는 동일한 신뢰할 수 있는 서명 키 세트를 보고해야 합니다. 두 번째 해결책은 제어 평면을 직접 운영하는 것입니다. 자체 호스팅 Headscale 조정 서버는 동일한 클라이언트에 동일한 프로토콜을 사용하므로, 장치 그래프와 키 배포를 사용자가 소유한 하드웨어로 옮길 수 있습니다. 이 경우 서버의 가동 시간 역시 사용자가 책임져야 합니다. 만약 자체 호스팅 제어 평면을 비교 중이라면, NetBird는 단일 VPS에서 서버를 완전히 직접 운영할 수 있는 별도의 메시 VPN입니다.
첫날 반드시 수정해야 할 기본 설정이 하나 있습니다. 새로운 tailnet은 기본적으로 허용 정책을 따릅니다. "기본 tailnet 정책 파일은 tailnet 내 모든 장치 간의 통신을 허용합니다." acls 섹션을 추가하는 즉시 모델은 기본 거부(deny by default)로 전환되며, 오직 사용자가 작성한 규칙만 통과하게 됩니다.
{
"tagOwners": {
"tag:server": ["autogroup:admin"]
},
"acls": [
{"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
]
}이 정책은 tailnet 구성원이 태그가 지정된 서버의 SSH에만 접근할 수 있게 하며 다른 것은 허용하지 않습니다. 와일드카드를 그대로 두지 말고 서비스별로 규칙을 추가하십시오. 와일드카드를 사용하면 노트북 키 하나만 탈취되어도 데이터베이스까지 접근이 가능해지기 때문입니다.
실패 유형 및 표시되는 문자열
tailscale status은 항상 relay을 출력합니다. 두 노드가 직접 경로를 생성하지 못했습니다. 양쪽 끝에서 tailscale netcheck을 실행하십시오. UDP: false는 UDP 아웃바운드 트래픽이 차단되었음을 의미하며, 이 경우 릴레이만 사용할 수 있습니다. MappingVariesByDestIP: true은 엄격한 NAT가 가로막고 있음을 의미합니다. 제어 가능한 측에서 UDP 41641 포트의 인바운드 트래픽을 허용하면 문제가 해결되는 경우가 많습니다.
수개월간 정상 작동하던 노드가 사라졌습니다. 노드 키가 기본값인 180일 만료 기간을 넘겼습니다. 관리 콘솔에서 해당 머신이 만료된 것으로 표시되며, 해당 장비에서 sudo tailscale up을 실행하면 다시 복구됩니다. 이런 일이 반복되지 않도록 서버의 키 만료 설정을 비활성화하십시오.
피어는 목록에 나타나지만 연결 시 타임아웃이 발생합니다. 연결성은 정상이나 정책이 트래픽을 거부하고 있습니다. 해당 소스, 대상, 포트를 포함하는 규칙이 있는지 acls 섹션을 확인하십시오. 거부된 패킷은 응답 대신 폐기되므로, Connection refused 대신 타임아웃이 발생합니다.
MagicDNS 이름이 해석되지 않습니다. ping db-1는 실패하지만 ping 100.101.102.104는 정상 작동합니다. 무언가가 /etc/resolv.conf을 대체하여 쿼리가 100.100.100.100의 스텁 리졸버에 도달하지 못하고 있습니다. cat /etc/resolv.conf에서 100.100.100.100를 확인하고, 해당 파일을 수정하는 다른 프로세스가 있는지 살펴보십시오. 이는 WireGuard 터널 내부의 DNS 문제와 동일한 유형의 문제입니다.
tailscale up이 태그를 거부합니다. 정책 파일의 tagOwners 항목 아래에 해당 태그가 선언되지 않았습니다. 해당 위치에 태그를 추가한 뒤 명령을 다시 실행하십시오.
FAQ
Tailscale은 VPN입니까, 아니면 메시 네트워크입니까?
두 용어 모두 정확하며, 서로 다른 계층을 설명합니다. 터널은 WireGuard를 사용하므로 VPN이 맞습니다. 토폴로지는 메시 구조인데, 이는 모든 패킷을 중앙 서버로 보내는 대신 각 노드가 통신하는 상대 노드와 직접 터널을 구축하기 때문입니다. 조정 서버(coordination server)는 제어 경로에만 관여하고 데이터 경로에는 관여하지 않으므로, 서버에 접근할 수 없게 되어도 기존 터널은 트래픽을 계속 전달합니다. 서버 장애 시 영향을 받는 것은 새로운 노드의 참여나 키 및 정책 변경 사항의 적용뿐입니다.
Tailscale이 제 트래픽을 읽을 수 있습니까?
내용은 읽을 수 없습니다. 트래픽은 WireGuard를 통해 노드 간 종단 간 암호화되며, 개인 키는 노드 밖으로 나가지 않습니다. DERP 릴레이는 복호화할 방법이 없는 패킷을 전달할 뿐입니다. Tailscale은 머신 이름, 소유자, 공개 키, 엔드포인트 주소, 각 노드의 온라인 상태와 같은 메타데이터는 확인할 수 있습니다. 또한 키를 배포하므로, 조정 서버가 침해되면 귀하의 네트워크가 신뢰하게 될 노드를 삽입하려 시도할 수 있습니다. Tailnet lock은 귀하가 신뢰하는 노드의 서명을 요구하여 이를 차단하며, Headscale을 사용하면 호스팅된 제어 평면을 완전히 배제할 수 있습니다.
Tailscale을 위해 방화벽 포트를 열어야 합니까?
인바운드 포트는 거의 열 필요가 없습니다. Tailscale의 자체 가이드라인에서도 "대부분의 경우 방화벽 포트를 열 필요가 없다"고 명시합니다. 아웃바운드 측면에서는 조정 서버 및 릴레이와의 통신을 위해 TCP 443 포트가 필요하며, STUN을 위해 UDP 3478 포트가 필요합니다. 직접 터널은 기본적으로 소스 포트 41641을 사용하는 UDP를 사용합니다. UDP 41641 인바운드를 허용하는 것은 선택 사항이며, 이는 까다로운 네트워크 환경에서 직접 연결 성공률을 높이는 데만 도움을 줍니다.
왜 다른 노드에서 제 서비스의 3000번 포트에 접근할 수 없습니까?
먼저 ss -tlnp를 사용하여 바인딩 주소를 확인하십시오. 127.0.0.1:3000에서 대기 중인 리스너는 노드의 100.x tailnet 주소로 들어오는 연결을 거부합니다. 해당 소켓은 루프백 대상만 허용하기 때문이며, 클라이언트는 Connection refused 오류를 보게 됩니다. 서비스를 tailnet 주소에 바인딩하거나, tailscale serve 3000를 실행하여 프록시로 사용하십시오. 만약 리스너가 이미 0.0.0.0에 설정되어 있는데도 연결이 거부되지 않고 시간 초과가 발생한다면, 원인은 바인딩 주소가 아니라 정책 규칙이나 호스트 방화벽 설정일 가능성이 높습니다.
Tailscale의 조정 서버 대신 Headscale을 실행해야 합니까?
장치 그래프나 키 배포를 직접 제어하는 인프라 내에 유지해야 하거나, 외부 서비스에 대한 의존성 없이 tailnet을 운영해야 한다면 Headscale을 실행하십시오. 클라이언트와 프로토콜은 동일합니다. 다만 조정 서버를 직접 운영해야 하는 비용이 발생하며, 서버 장애 시 새로운 노드 참여나 정책 변경 적용이 중단됩니다. 소규모 네트워크라면 Tailnet lock을 활성화한 상태로 호스팅된 제어 평면을 사용하는 것이 일반적으로 더 나은 선택입니다.