Tailscale serve와 funnel 차이점 및 설정 가이드
Tailscale serve는 tailnet 내부 전용 URL을 제공하며, funnel은 동일한 포트를 공용 인터넷에 개방합니다. 두 기능의 기술적 차이와 funnel 사용 시 반드시 필요한 tailnet 정책 파일의 ACL 설정 및 필수 요구 사항을 상세히 설명합니다.
tailscale serve와 funnel의 차이: URL 접근 권한
tailscale serve와 tailscale funnel의 차이는 오직 접근 가능한 대상뿐입니다. serve은 로컬 포트에 HTTPS(hypertext transfer protocol secure) 프론트엔드를 구성하고 이를 사용자의 tailnet 내부에만 공개합니다. funnel은 동일한 로컬 포트를 Tailscale이 운영하는 릴레이 서버를 거쳐 전 세계 공용 인터넷에 공개합니다. 두 명령어는 동일한 플래그와 대상을 사용합니다. 단어 하나 차이로 비공개 대시보드와 전 세계에서 접근 가능한 서비스가 결정됩니다.
두 방식 모두 브라우저가 이미 신뢰하는 인증서를 ts.net로 끝나는 도메인 이름으로 제공하며, VPS 방화벽에서 인바운드 포트를 열 필요가 없습니다. 사용자의 tailscaled 데몬은 이미 tailnet으로 연결을 유지하고 있으므로, 네트워크 트래픽은 해당 연결을 통해 전달됩니다. 서버를 tailnet에 연결하는 것은 별개의 작업이며, VPS를 Tailscale exit node로 운영하기 또는 사설 네트워크를 위한 서브넷 라우터 광고하기가 이 범주에 해당합니다. 이미 tailnet에 있는 서비스를 외부로 공개하는 것이 바로 이 기능의 역할입니다.
명령어 실행 전 필수 준비 사항
- VPS에 Tailscale 1.38.3 이상 버전이 설치되어 있고 tailnet에 로그인되어 있어야 합니다.
tailscale version및tailscale status명령어로 확인하십시오. - MagicDNS가 활성화되어 있어야 합니다. MagicDNS는 Tailscale의 내장 DNS(도메인 이름 시스템)이며, 기기에
100.x주소뿐만 아니라blog-vps.your-tailnet.ts.net과 같은 이름을 부여합니다. - 관리 콘솔의 DNS 페이지에서 tailnet용 HTTPS 인증서가 활성화되어 있어야 합니다. 이 설정이 없으면 포트 앞에 배치할 인증서를 얻을 수 없습니다.
funnel의 경우에만, tailnet 정책 파일에funnel노드 속성이 필요합니다. 대부분의 초기 시도가 여기서 막히며, 이에 대해서는 아래에서 다룹니다.
여기에 나오는 모든 명령어는 sudo로 시작합니다. CLI가 root만 쓸 수 있는 소켓을 통해 tailscaled과 통신하기 때문입니다. 특정 사용자에게 이 권한을 부여하여 sudo 없이 실행할 수 있도록 설정하십시오:
sudo tailscale set --operator=$USERtailscale serve를 사용하여 tailnet에 게시하기
serve를 로컬 포트로 지정하면 나머지는 자동으로 처리됩니다.
sudo tailscale serve 3000Available within your tailnet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.단순한 3000은 http://127.0.0.1:3000의 단축 명령어입니다. Tailscale은 해당 머신의 tailnet 주소 443번 포트에서 대기하며, ts.net 인증서로 TLS(전송 계층 보안)를 종료하고 일반 HTTP를 로컬 포트로 전달합니다. 애플리케이션은 인증서 존재 여부를 알 필요가 없으며, 이것이 평문 HTTP로 남겨둘 관리자 패널 앞에 이 기능을 사용하는 주된 이유입니다.
이제 마지막 줄을 읽어보십시오: Press Ctrl+C to exit. 이 명령어는 포그라운드에서 실행되며, 매핑은 해당 프로세스 내에서만 유지됩니다. 터미널을 닫으면 디스크에 아무것도 기록되지 않았으므로 URL은 작동을 멈춥니다. --bg를 추가하면 매핑이 노드의 serve 설정에 저장되어 터미널 종료나 재부팅 후에도 유지됩니다.
sudo tailscale serve --bg 3000serve는 포트 번호 이상의 기능을 수행합니다. --set-path는 서비스를 하위 경로에 마운트하므로 여러 앱이 하나의 호스트 이름을 공유할 수 있습니다.
sudo tailscale serve --bg --set-path=/grafana 3000
sudo tailscale serve --bg --set-path=/metrics 9090대상은 정적 파일 디렉터리일 수도 있고, 확인하고 싶지 않은 인증서로 이미 TLS를 사용하는 백엔드일 수도 있습니다.
sudo tailscale serve --bg /srv/reports
sudo tailscale serve --bg https+insecure://localhost:8443HTTP에만 국한되지 않습니다. --tcp=<port>은 원시 TCP(전송 제어 프로토콜) 스트림을 전달하며, --tls-terminated-tcp=<port>은 노드에서 TLS를 종료하고 평문을 전달합니다. 이를 통해 HTTP를 지원하지 않는 서비스 앞단에 신뢰할 수 있는 인증서를 배치할 수 있습니다.
sudo tailscale serve --bg --tls-terminated-tcp=443 tcp://127.0.0.1:9899왜 funnel은 노드 속성이 설정되지 않았다고 출력합니까?
기본적으로 funnel은 전체 tailnet에 대해 비활성화되어 있습니다. 처음 실행하면 다음 메시지를 출력하고 중단됩니다.
Funnel not available; "funnel" node attribute not set. See https://tailscale.com/kb/1223/tailscale-funnel/.명령어는 정확했습니다. tailnet 정책에서 해당 노드에 게시 권한을 부여하지 않았기 때문에, 클라이언트는 릴레이에 연결하기 전에 작업을 거부합니다. 관리자 콘솔의 Access Controls에서 tailnet 정책 파일을 수정하고 다음 속성을 추가하십시오.
"nodeAttrs": [
{
"target": ["autogroup:member"],
"attr": ["funnel"],
},
],autogroup:member은(는) tailnet의 모든 구성원에게 권한을 부여합니다. 특정 장비 하나만 게시하도록 하려면 해당 장비에 태그를 지정하고 그 태그를 대상으로 설정하십시오(예: tag:public). 정책을 저장한 뒤 funnel 명령어를 다시 실행하십시오.
계정이 tailnet 관리자라면 최신 클라이언트에서 제공하는 바로가기 기능을 사용할 수 있습니다. CLI가 login.tailscale.com에 동의 URL을 출력하며, 해당 링크를 따라가면 HTTPS 인증서가 활성화되고 속성이 자동으로 추가됩니다. 관리자가 아니라면 해당 URL은 도움이 되지 않습니다. 정책 접근 권한이 있는 사용자가 직접 수정해야 합니다.
Tailscale Funnel을 사용하여 인터넷에 게시하기
속성이 설정되면, 이미 알고 있는 명령어에서 동사만 바꾸어 사용하면 됩니다.
sudo tailscale funnel --bg 3000Available on the internet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.매번 첫 번째 줄을 주의 깊게 읽으십시오. Available within your tailnet과 Available on the internet는 비공개 서비스와 공개 서비스를 구분하는 유일한 차이점이며, 이를 생성하는 명령어는 단어 하나만 다릅니다.
2026년 8월 기준으로, Funnel은 443, 8443 또는 10000 포트에서만 수신 대기하며 다른 포트는 사용하지 않습니다. 기본값은 443이며, --https=8443 또는 --https=10000가 대안입니다. Funnel 릴레이는 해당 포트에서만 연결을 허용하므로 다른 포트는 거부됩니다. 이것이 Funnel URL이 항상 호스트 이름 그대로이거나, 호스트 이름 끝에 :8443가 붙는 이유입니다.
현재 게시된 항목을 확인하려면 어떻게 해야 합니까?
추측에 의존하면 대시보드가 한 달 동안 공개 상태로 방치될 수 있습니다. 대신 노드에 직접 질의하십시오.
tailscale serve status
tailscale funnel status
tailscale serve status --json두 상태 확인 명령어 모두 동일한 설정을 읽어오므로 어느 쪽을 사용하든 전체 현황을 파악할 수 있습니다. 스크립트나 예약된 점검 작업에는 --json 형식을 사용하십시오. 일반 출력은 사람이 읽기 편하도록 작성되었기 때문입니다. 설정된 항목이 없으면 다음과 같이 한 줄만 출력됩니다.
No serve config작동하던 설정 이후에 이 메시지가 나타난다면, 매핑이 포그라운드에서 생성되었고 현재 프로세스가 종료되었음을 의미합니다. --bg을 사용하여 다시 생성하십시오.
특정 매핑 하나를 제거하려면 해당 매핑을 생성했던 명령어를 다시 입력하고 끝에 off을 추가하십시오. 노드에 있는 모든 serve 및 funnel 매핑을 삭제하려면 reset를 사용하십시오.
sudo tailscale funnel --https=443 3000 off
sudo tailscale serve reset명령어 실행 후에는 의도한 대로 처리되었을 것이라고 가정하지 말고, tailscale serve status을 다시 실행하여 남은 항목을 확인하십시오.
얻는 것과 포기해야 하는 것
이 방식이 주는 이점은 확실하며, 많은 사용자가 리버스 프록시 대신 이 방식을 선택하는 이유이기도 합니다.
- 브라우저가 신뢰하는 인증서가 자동으로 갱신됩니다. 별도의 ACME(automatic certificate management environment) 클라이언트를 설치할 필요가 없으며, 갱신 작업을 잊어버릴 염려도 없습니다.
- VPS 방화벽에 인바운드 포트를 열 필요가 없습니다.
tailscaled은 외부로 연결을 시도하므로, VPS의 기본 거부(default-deny) ufw 방화벽 설정을 그대로 유지할 수 있습니다. - DNS 레코드를 구매하거나, 연결하거나, 전파를 기다릴 필요가 없습니다.
- 포트 포워딩이 필요 없습니다. 이는 공인 IP를 가진 VPS가 아닌 NAT(network address translation) 뒤에 있는 장비에서 특히 중요한 장점입니다.
반면 비용과 제약 사항도 분명하며, 이는 모두 Funnel을 사용함에 따라 발생합니다.
- 도메인 이름을 직접 소유할 수 없습니다. 방문자는
host.your-tailnet.ts.net를 보게 됩니다. Funnel은 사용자 지정 도메인을 지원하지 않으므로, 앞에app.example.com을 붙여 사용할 수 없습니다. - 경로를 직접 제어할 수 없습니다. 트래픽은 먼저 Tailscale 릴레이에 도달하며, 릴레이는 해당 스트림을 tailnet을 통해 노드로 프록시합니다. Tailscale은 Funnel 트래픽에 공개되지 않고 설정할 수도 없는 대역폭 제한이 적용된다고 명시하고 있습니다. 따라서 특정 수치에 의존하기 전에 직접 처리량을 측정해야 합니다.
- 제어 기능이 부족합니다. 직접 운영하는 리버스 프록시는 접근 로그, 속도 제한(rate limit), 요청 크기 제한, 인증 계층 등을 제공하지만, Funnel은 단순히 URL만 제공합니다. 그 외의 모든 기능은 애플리케이션 내부에서 구현해야 합니다.
- 위에서 언급했듯이 포트 목록이 고정되어 있습니다.
두 기능 모두 Tailscale이 운영하는 인프라에 의존합니다. ts.net 이름에 대한 인증서 발급과 Funnel 릴레이 자체가 이에 해당합니다. 자체 호스팅 Headscale 컨트롤 서버를 고려 중이라면, 이 기능들이 그대로 지원된다고 가정해서는 안 됩니다. 사용하려는 Headscale 버전의 릴리스 노트를 확인하십시오.
어떤 것을 사용해야 합니까?
규칙은 간단합니다.
내부용 서비스에는 serve를 사용하십시오. 관리자 인터페이스, 대시보드, 인덱싱을 원치 않는 메트릭 UI, 사이트의 스테이징 복사본 등이 이에 해당합니다. tailnet 멤버십 자체가 강력한 접근 제어 수단이 됩니다. tailnet에 연결되지 않은 장치는 해당 도메인 이름을 해석조차 할 수 없습니다.
데모 링크, 제3자가 POST 요청을 보내야 하는 웹훅 수신기, 개발 중인 OAuth 콜백에는 funnel을 사용하십시오. 공개 HTTPS URL을 얻는 가장 빠른 방법이며, off 명령 한 번으로 즉시 종료할 수 있습니다. 다만 '공개'라는 의미를 명심하십시오. 호스트 이름은 비밀이 아니며, 로그인 기능이 없는 애플리케이션 앞에 funnel을 배치하는 것은 서비스를 외부에 완전히 개방하는 것과 같습니다. 해당 서비스 뒤에 무엇이 있든 노출된 Ollama API 엔드포인트를 다룰 때와 동일한 주의를 기울여 자체적으로 요청을 인증해야 합니다.
운영 환경(production)이라고 부를 만한 서비스에는 실제 리버스 프록시를 사용하십시오. 본인의 도메인, 인증서, 로그, 속도 제한(rate limit)을 직접 관리하며 요청 경로에 제3자가 개입하지 않도록 해야 합니다. 리버스 프록시로서의 nginx, Caddy, Traefik 비교 문서를 참고하여 적절한 도구를 선택하십시오.
실패 유형 및 확인되는 메시지
Funnel이 시작되지 않습니다. Funnel not available; "funnel" node attribute not set.은 명령 문제가 아니라 정책 문제입니다. tailnet 정책 파일에 funnel 속성을 추가하고 저장한 뒤 다시 시도하십시오.
작동하던 것이 이제 tailscale serve status에서 No serve config라고 표시합니다. 매핑이 포그라운드에서 생성되었고 해당 프로세스가 종료된 상태입니다. --bg 플래그를 사용하여 동일한 명령을 다시 실행하십시오.
이름은 해석되지만 응답이 없습니다. Serve는 지정한 대상으로 프록시를 전달하므로, 해당 위치에서 수신 대기 중인 서비스가 없다면 프록시할 대상도 없는 것입니다. tailscaled를 실행하는 동일한 머신에서 ss -ltnp | grep 3000으로 확인하십시오. 흔한 원인은 컨테이너가 포트를 127.0.0.1가 아닌 Docker 브리지 주소로 게시하여, 호스트가 예상한 위치에서 리스너를 찾지 못하는 경우입니다. Docker Compose 네트워킹 작동 방식에서 게시된 포트가 실제로 어디에 할당되는지 확인할 수 있습니다.
ts.net 이름에서 인증서 오류가 발생합니다. HTTPS 인증서가 tailnet에 활성화되지 않았을 가능성이 가장 높습니다. 관리 콘솔에서 인증서를 활성화한 뒤, 인증서 관련 단계만 별도로 실행하여 오류가 serve 출력과 섞이지 않도록 하십시오:
sudo tailscale cert your-host.your-tailnet.ts.net모바일 데이터에서는 Funnel이 로드되지만 노트북과는 다르게 동작합니다. 노트북은 tailnet에 연결되어 있으므로 MagicDNS가 이름을 100.x 주소로 해석하여 릴레이를 거치지 않고 서비스에 직접 도달합니다. 이는 올바른 동작이며, 노트북으로는 공용 도달 가능성을 테스트할 수 없음을 의미합니다. tailnet에 연결되지 않은 머신에서 curl을 사용하십시오.
FAQ
tailscale serve와 tailscale funnel의 차이점은 무엇입니까?
결과에 접근할 수 있는 대상이 다릅니다. tailscale serve는 귀하의 tailnet에 속한 기기만 접근할 수 있는 HTTPS URL로 로컬 포트를 게시합니다. tailscale funnel은 Tailscale이 운영하는 릴레이 서버를 거쳐 인터넷상의 누구나 접근할 수 있는 URL로 동일한 포트를 게시합니다. 두 명령어는 플래그와 대상을 공유합니다. 첫 번째 출력 줄을 보면 Available within your tailnet인지 Available on the internet인지 확인할 수 있습니다.
tailscale funnel 사용 시 노드 속성이 설정되지 않았다는 메시지가 나오는 이유는 무엇입니까?
funnel은 누군가 활성화하기 전까지 tailnet에서 비활성화 상태이기 때문입니다. 해당 메시지는 Funnel not available; "funnel" node attribute not set.이며, 릴레이에 연결하기 전 클라이언트 자체에서 발생합니다. Access Controls의 tailnet 정책 파일에 autogroup:member에 funnel 속성을 부여하는 nodeAttrs 항목을 추가하십시오. 특정 머신만 게시해야 한다면 태그를 사용할 수도 있습니다. tailnet 관리자는 CLI가 출력하는 동의 URL을 따라갈 수도 있습니다.
Tailscale Funnel은 어떤 포트를 사용할 수 있습니까?
443, 8443, 10000 포트만 사용할 수 있습니다. 기본값은 443이며, --https=8443 또는 --https=10000을 사용하여 다른 포트를 선택할 수 있습니다. 이는 서버의 제한이 아니라 funnel 릴레이의 제한이므로, VPS의 방화벽이나 설정을 변경해도 해결되지 않습니다. tailscale serve는 tailnet 외부로 나가지 않으므로 이러한 제한이 없습니다.
serve 또는 funnel URL은 재부팅 후에도 유지됩니까?
--bg을 사용한 경우에만 유지됩니다. 이 옵션이 없으면 명령어가 포그라운드에서 실행되고 Press Ctrl+C to exit.을 출력하며, 프로세스가 종료됨과 동시에 매핑도 사라집니다. --bg를 사용하면 매핑이 노드의 serve 설정에 기록되어 재부팅 후 tailscaled과 함께 복구됩니다. 설정된 내용이 없을 때 No serve config를 출력하는 tailscale serve status 명령어로 상태를 확인하십시오.
funnel을 계속 실행해 두어도 안전합니까?
전송 계층 측면에서는 안전합니다. 연결은 HTTPS이며 방화벽에 포트가 열리지 않기 때문입니다. 하지만 일반적으로 의미하는 보안 측면에서는 안전하지 않습니다. URL이 공개되어 있으므로 그 뒤에 있는 애플리케이션도 공개되기 때문입니다. 자체적으로 인증을 수행하는 서비스 앞에만 funnel을 유지하고, 데모나 웹훅 테스트가 끝나면 생성 시 사용한 명령어 뒤에 off을 붙여 종료하십시오.
위 명령어 동작에 대한 출처: tailscale.com/docs의 Tailscale Serve 및 Funnel 문서와 CLI 참조.