이름 해석 성공은 LAN route 성공을 뜻하지 않는다
MagicDNS는 tailnet device에 사람이 읽을 수 있는 이름을 붙이는 기능입니다. 이름이 Tailscale IP로 해석되고 해당 node가 응답한다고 해서 그 node 뒤의 private LAN까지 route가 설치됐다는 뜻은 아닙니다. 반대로 subnet route가 정상이어도 private DNS server에 도달하지 못하면 LAN host name만 실패할 수 있습니다.
이 문제는 DNS와 route를 동시에 바꾸지 않는 것이 핵심입니다. 먼저 이름이 어떤 주소로 해석되는지, 그 주소가 Tailscale node인지 LAN host인지 기록합니다. 그 다음 route injection의 조건과 packet 허용 조건을 별도로 확인합니다.
증상을 주소 종류로 나누는 표
| 대상 | 성공 조건 | 실패 시 조사 계층 |
|---|---|---|
| MagicDNS device 이름 | tailnet node 이름이 Tailscale IP로 해석 | MagicDNS와 client DNS 수락 |
| Tailscale IP | 해당 node에 직접 도달 | node online 상태와 grant |
| LAN IP | subnet route가 client에 설치되고 허용됨 | 광고, 승인, 수락, access control |
| private DNS 이름 | nameserver에 route로 도달하고 질의 허용 | split DNS와 DNS server route |
tailscale status
tailscale status --json > tailscale-status.json
tailscale ip -4
getent hosts <MAGICDNS_NAME>
tailscale ping <SUBNET_ROUTER>
ip route get <LAN_IP>
Linux가 아닌 client에서는 마지막 명령을 운영체제의 route 조회 명령으로 바꿉니다. tailscale-status.json에는 device와 tailnet 정보가 포함되므로 공개 첨부 전에 식별자를 제거합니다.
변경 전에 원래 값을 읽고 기록한다
아래는 Linux 클라이언트의 읽기 전용 조회입니다. RouteAll은 route 수락, CorpDNS는 DNS 수락 값입니다. 둘 중 하나라도 unknown이거나 명령이 실패하면 변경을 중단합니다. 실제 출력의 true/false를 ORIGINAL_ACCEPT_ROUTES와 ORIGINAL_ACCEPT_DNS 셸 변수에 각각 기록한 뒤, 같은 셸에서 필요한 시험 하나만 수행합니다. 다른 관리 연결을 먼저 확보하고 DNS와 route를 동시에 바꾸지 않습니다.
tailscale version
tailscale debug prefs | python3 -c 'import json,sys; p=json.load(sys.stdin); keys=("RouteAll","CorpDNS"); ok=all(type(p.get(k)) is bool for k in keys); print(json.dumps({k:p.get(k,"unknown") for k in keys})); sys.exit(0 if ok else 1)'
route injection의 조건을 순서대로 확인한다
Tailscale 공식 문서는 subnet route가 client에 들어오려면 router가 route를 광고하고, admin이 승인하고, control plane이 배포하고, client가 수락해야 한다고 설명합니다. Windows, macOS, Android, iOS, tvOS는 route를 기본 수락하지만 Linux는 명시적으로 켜야 합니다.
sudo tailscale set --accept-routes=true
tailscale status --json > tailscale-status-after.json
ip route get <LAN_IP>
route가 보인다는 사실과 연결 허용은 별개입니다. grants 또는 ACLs는 packet을 허용하지만 route를 만들어 내지 않습니다. 반대로 route가 설치돼도 access control이 destination과 port를 허용하지 않으면 packet은 통과하지 않습니다.
MagicDNS와 private DNS를 혼동하지 않는다
MagicDNS는 tailnet device 이름을 자동 등록하지만 arbitrary LAN record를 추가하는 기능은 아닙니다. NAS나 printer처럼 Tailscale client가 없는 장비의 이름을 쓰려면 해당 record를 가진 private nameserver와 split DNS를 구성해야 합니다. private nameserver 주소가 LAN에 있다면 그 주소까지 가는 subnet route도 필요합니다.
client가 Tailscale DNS를 받는지 확인한 뒤 필요한 경우에만 수락 설정을 바꿉니다. DNS 수락을 끄는 시험은 route를 고치는 작업이 아니라 이름 해석 계층을 분리하는 시험입니다.
sudo tailscale set --accept-dns=false
getent hosts <MAGICDNS_NAME>
# Restore the recorded values using the guarded rollback below.
결과를 해석하는 방법
- MagicDNS 이름과 Tailscale IP는 성공, LAN IP는 실패: DNS가 아니라 subnet route와 access control을 봅니다.
- LAN IP는 성공, private 이름만 실패: route는 동작합니다. split DNS nameserver, search domain, client DNS 수락을 확인합니다.
- router의 Tailscale IP부터 실패: LAN route를 보기 전에 router node의 online 상태와 기본 tailnet 권한을 복구합니다.
- Linux에서만 LAN IP 실패: route 수락 설정과 실제 route table을 먼저 비교합니다. 모든 OS에 같은 기본값을 가정하지 않습니다.
- route는 있으나 특정 port만 실패: grant, destination service listen address, LAN firewall을 분리합니다.
롤백과 검증
복원값을 false/true로 고정하지 않습니다. 변경 전에 기록한 두 값으로 되돌린 뒤 다시 조회합니다. 아래 코드는 Bash 스크립트에서 실행하며, 원래 값을 기록하지 않았다면 종료합니다. router의 광고 route 변경은 다른 client에도 영향을 주므로 이 client 시험과 섞지 않습니다.
# Set these to the booleans recorded BEFORE the test in this shell.
# Empty/unknown values stop the command; do not guess defaults.
case "${ORIGINAL_ACCEPT_ROUTES-}:${ORIGINAL_ACCEPT_DNS-}" in
true:true|true:false|false:true|false:false) ;;
*) printf '%s\n' 'STOP: original preferences are required' >&2; exit 1 ;;
esac
sudo tailscale set --accept-routes="$ORIGINAL_ACCEPT_ROUTES" --accept-dns="$ORIGINAL_ACCEPT_DNS"
tailscale version
tailscale debug prefs | python3 -c 'import json,sys; p=json.load(sys.stdin); keys=("RouteAll","CorpDNS"); ok=all(type(p.get(k)) is bool for k in keys); print(json.dumps({k:p.get(k,"unknown") for k in keys})); sys.exit(0 if ok else 1)'
최종 검증은 이름 해석, route 선택, 실제 service port의 세 결과를 함께 남깁니다. ping만 성공하는 상태를 애플리케이션 복구로 기록하지 않습니다.
같이 확인할 글
공식 문서 및 확인 기준
- Tailscale MagicDNS – tailnet device 이름과 client DNS 수락 범위
- DNS in Tailscale – global, split DNS, private nameserver와 exit node 동작
- Tailscale subnet routers – route 광고, 승인과 Linux client 수락
- Tailscale route injection – route와 access control의 독립 조건
- Tailscale client preferences – accept-dns와 accept-routes 설정
이 글에 남아 있던 이전 검증 기록
검증 수준: 공식 문서 대조
MagicDNS, split DNS, subnet route와 access control의 경계를 Tailscale 공식 문서로 확인했습니다. 특정 LAN의 route 또는 firewall은 재현하지 않았으므로 실제 packet 차단 위치는 운영 환경에서 검증해야 합니다.