Windows의 이름 확인 순서 ── hosts·DNS 캐시·LLMNR/mDNS·DoH

· 업데이트: · · Windows, DNS, 이름 확인, 네트워크, 장애 조사, PowerShell, TCP/IP, 정보시스템 담당

「같은 설정인데 이 PC만 사내 서버에 연결되지 않는다」「브라우저에서는 열리는데 업무 앱에서는 이름 확인에 실패한다」「hosts에 썼는데 듣지 않는다」.

이런 문제를 조사할 때 가장 먼저 확인하고 싶은 것은 그 이름에 어떤 구조가 답하고 있는가입니다. Windows에는 캐시, hosts, DNS 서버, LLMNR, NetBIOS, mDNS라는 여러 경로가 있고, 앱에 따라서는 Windows와는 다른 경로를 씁니다.

이 글에서는 먼저 전체상을 잡고, 이름의 형태와 각 경로의 차이를 정리한 뒤 실제 분리 절차로 나아갑니다. 서둘러 조사하고 싶은 분은 다음 표에서 해당 부분으로 이동하십시오.

겪고 있는 문제 먼저 확인할 것 읽을 위치
hosts가 듣지 않는다/일부 PC만 오래된 IP를 돌려준다 캐시의 내용과, 사용한 도구의 경로 캐시와 hosts, 절차 2
app01 같은 짧은 이름에서 일부 PC만 실패한다 접미사에 의한 보완과 LLMNR·NetBT의 유무 이름의 형태, 단일 레이블 이름의 전형
VPN에 연결하면 결과가 달라진다 여러 NIC의 우선순위와 NRPT 여러 NIC, NRPT
몇 초 기다리면 연결된다 무응답인 DNS 서버와 재전송 시간 타임아웃
브라우저와 업무 앱에서 결과가 다르다 내장 확인자, 보안 DNS, 프록시 앱의 입구, 브라우저의 DoH
어디부터 조사할지 모르겠다 이름의 형태부터 차례로, 경로를 한정해 비교한다 분리 절차

이 글의 전제

항목 내용
대상 독자 「이름을 확인할 수 없다」「일부 PC만 연결되지 않는다」를 조사하는 정보시스템 담당자와, 업무 앱의 통신을 설계·유지보수하는 Windows 앱 개발자
전제 지식 IP 주소와 DNS의 기본(A 레코드, FQDN), PowerShell의 cmdlet을 관리자 권한으로 실행할 수 있을 것
전제 환경 Windows 10 / Windows 11. DoH 절은 Windows 11 또는 Windows Server 2022 이상1. 확인 명령은 DnsClient 모듈(Windows 8 / Windows Server 2012 이상)2
다루지 않는 것 DNS 서버 쪽(Windows Server DNS의 영역·전달자·재귀)의 설정과 장애. Zero Trust DNS(ZTDNS)의 배포 절차

패킷 캡처 글이 다루는 것은 선로를 흐르는 패킷, 프록시 글이 다루는 것은 「누구의 프록시 설정을 읽는가」입니다. 이 글은 그 앞 단계인 「목적지의 IP 주소는 어디에서 왔는가」를 Microsoft의 1차 정보를 바탕으로 정리합니다.

1. 먼저 결론

기억해 둘 것은 다음 세 가지입니다.

  • Windows의 이름 확인은 늘 하나의 줄을 차례로 나아가는 것이 아닙니다. 캐시와 hosts가 먼저지만, 단일 레이블 이름에서는 기본적으로 DNS와 LLMNR·NetBT가 병행해 움직입니다.34
  • 같은 이름이라도 PC의 설정과 앱의 경로가 다르면 결과는 달라집니다. 접미사, VPN, NRPT, 브라우저의 내장 확인자를 나누어 생각합니다.567
  • 조사에서는 쓰는 경로를 한정해 결과를 비교합니다. Resolve-DnsName의 스위치로 캐시·DNS·링크 로컬을 나누고, 연결되는 PC와의 설정 차이 및 캡처로 확인합니다.8

우선 다음 그림을 전체의 조감도로 사용하십시오.

이름 확인은 층의 겹침이름 확인 의뢰는 앱의 API에서 DNS 클라이언트 서비스로 넘어가고, 캐시와 hosts가 먼저 보이며, 다음으로 DNS 서버와, 단일 레이블 이름일 때만 LLMNR·NetBIOS(기본적으로는 DNS와 병행)가 시도된다. .local 이름에는 설정된 DNS에 더해 mDNS라는 경로도 더해진다. 브라우저는 이 줄 밖에 자체 확인자를 가진다없으면없으면·단일 레이블 이름(기본은 DNS와 병행).local 이름(추가 경로)자체 확인자·DoH앱(getaddrinfo)DNS 클라이언트 서비스캐시(hosts 포함)DNS 서버에 질의LLMNR / NetBIOSmDNS브라우저다른 경로

캐시를 먼저 보고, 그 앞에서 DNS와, 단일 레이블 이름이면 LLMNR·NetBIOS가 병행해 움직인다. 브라우저는 다른 경로를 가진다.

아래에서는 「어디가 답하는가」를 3~5장, 「어떻게 보내는가」를 6장, 「어떻게 확인하는가」를 7~8장으로 나눕니다. DoH는 DNS 서버로의 전송 경로를 HTTPS로 바꾸는 기능이며, hosts·캐시·NRPT의 순서를 대체하는 것은 아닙니다.9

그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 48건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle

2. 「이름 확인」은 하나의 처리가 아닙니다

앱에 돌아오는 것은 주소 아니면 오류뿐

앱이 www.example.com 같은 이름으로 연결할 때 Winsock의 getaddrinfo(유니코드 판은 GetAddrInfoW)가 호출됩니다. 이 함수는 NS_DNS 네임스페이스에 대해 DNS, 로컬의 hosts 파일, 그 밖의 구조로 이름을 주소로 변환합니다. 여러 네임스페이스 공급자가 응답하면 그것을 집약해 돌려줍니다.10

앱이 결과를 받았다는 것만으로는 어느 층이 답했는지까지는 알 수 없습니다.

.NET의 Dns.GetHostAddresses도 Windows에서는 getaddrinfo를 씁니다. hosts에 적힌 호스트라면 DNS 서버에 묻지 않고 그 주소를 돌려줍니다. HttpClient도 이 Dns 클래스 위에서 동작하므로, 목적지에 직접 연결하는 .NET 앱은 Windows의 이름 확인 순서를 그대로 물려받습니다.11

HTTP 프록시를 경유하면 확인되는 이름이 달라집니다. 로컬에서 확인하는 것은 프록시의 이름이고, 목적지의 이름은 프록시 쪽에서 확인됩니다. 이 경우 로컬의 hosts·캐시·접미사·NRPT는 목적지의 확인에 관여하지 않습니다. 어느 프록시 설정이 쓰이는지는 프록시 글에서 다룹니다.

2.1 DNS 클라이언트 서비스가 순서를 정합니다

getaddrinfo 아래에서 일하는 것이 DNS 클라이언트 서비스(서비스 이름 Dnscache)입니다. Microsoft의 자료는 기본 순서를 다음과 같이 설명합니다.3

  1. 캐시를 확인한다.
  2. hosts 파일을 확인한다.
  3. DNS 서버에 질의한다.

hosts의 내용은 서비스 시작 시 캐시로 읽어들여지므로, 이 글에서는 앞의 두 가지를 묶어 제1층 「캐시와 hosts」로 다룹니다.5

그 앞은 이름과 정책에 따라 갈립니다.

역할 순서를 읽을 때의 주의
제1층: 캐시와 hosts PC 안에 있는 답을 돌려준다 여기서 답이 나오면 DNS 서버에는 묻지 않는다
제2층: DNS 서버 DNS로의 질의로 답을 얻는다 접미사, 여러 NIC, NRPT 등이 관여한다
제3층: LLMNR·NetBT 단일 레이블 이름을 다른 수단으로도 확인한다 기본은 제2층과 병행. DNS 실패 후의 직렬이 되는 것은 최적화를 비활성화했을 때뿐

기본인 「스마트 다중 홈 이름 확인」은 DNS·LLMNR·NetBT의 질의를 모든 네트워크로 병행해 내보냅니다. 어느 응답을 채택할지는 4.3절과 5.2절의 규칙으로 정해집니다.4

따라서 「질의를 내보내는 시점」과 「돌아온 답을 채택하는 우선순위」는 별개의 이야기입니다. 캡처에 LLMNR이나 NetBT가 보인다고 해서 그것만으로 「DNS가 실패했다」고 말할 수는 없습니다. 이 글의 「3층」은 정리를 위한 구분이며, 항상 시간 순서대로 직렬로 움직인다는 뜻은 아닙니다.

2.2 줄 밖에 있는 것들

특히 혼동하기 쉬운 것이 다음 두 가지입니다.

도구·앱 Windows의 경로와의 차이 조사 시의 주의
nslookup OS의 확인자를 쓰지 않고 캐시·hosts·NRPT를 우회해 맨 앞의 DNS 서버에 직접 묻는다123 ping이나 업무 앱과 결과가 달라도 이상하지 않다
Microsoft Edge 기본적으로 내장 DNS 클라이언트를 쓴다. DoH도 항상 내장 확인자로 처리한다7 「브라우저에서는 열린다」는 OS의 이름 확인이 건전하다는 증명이 되지 않는다

Edge의 내장 클라이언트를 쓰는 것 자체는 DNS 서버의 변경을 뜻하지 않습니다. 다른 공급자를 고르는 보안 DNS 설정과는 나누어 6.2절에서 확인합니다.

3. 제1층 ── 캐시와 hosts

이 층에서 알고 싶은 것은 PC 안에 어떤 답이 남아 있는가입니다. 캐시에는 올바른 답뿐 아니라 오래된 답이나 「이름이 없다」는 답도 남습니다.

3.1 hosts는 캐시로 읽어들여집니다

hosts 파일은 C:\Windows\System32\drivers\etc\hosts에 있습니다. DNS 클라이언트 서비스가 시작될 때 이름과 IP 주소의 대응이 확인자 캐시로 읽어들여집니다. DNS 질의로 얻은 레코드도 TTL(수명) 동안 같은 캐시에 보관됩니다.5

ipconfig /displaydns에는 hosts에서 읽어들인 항목과 최근의 DNS 질의로 얻은 항목이 모두 표시됩니다.13 Microsoft의 예에서도 hosts에 contoso.com을 쓰면 Resolve-DnsName contoso.com은 그 주소를 돌려주고 DNS 통신은 흐르지 않습니다.3

DNS 패킷이 없을 때 읽는 법

FQDN을 DoH·DoT 없이 조회했는데 이름 확인은 성공하고 53번 질의가 없다면, 캐시나 hosts가 답하고 있다고 볼 수 있습니다. 다만 먼저 다음의 다른 경로를 배제합니다.

이름·설정 53번 외에 확인할 통신
.local 이름 mDNS(UDP 5353)
단일 레이블 이름 LLMNR(5355), NetBT의 이름 서비스(UDP 137)
DoH가 활성 HTTPS(443)
DoT가 활성 TLS(853)

「53번이 없다」는 것만으로 캐시라고 단정하지 말고, 쓰일 수 있는 경로를 함께 봅니다. 개발용 PC에 남은 검증용 hosts 한 줄이 조사를 헤매게 하기도 합니다.

hosts의 편집에는 관리자 권한이 필요하고, 변경을 보안 제품이 탐지하는 경우도 있습니다. 업무 앱의 운영을 hosts에 의존시키는 설계는 피해야 합니다.

3.2 부정 응답도 캐시됩니다

「찾지 못했다」도 캐시되는 답의 하나입니다. DNS 클라이언트는 긍정 응답뿐 아니라 부정 응답도 보관합니다.5

ipconfig /displaydns에서 대상 이름에 「Name does not exist」가 표시된다면 DNS 서버의 부정 응답이 클라이언트에 남아 있는 것입니다. Microsoft의 절차는 ipconfig /flushdns로 그것을 버리도록 안내합니다.1413

부정 캐시의 보관 시간은 HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\ParametersMaxNegativeCacheTtl로 정해지며 기본은 5초입니다.15 DNS에 레코드를 추가한 직후에도 그 PC가 몇 초 동안은 실패를 돌려주는 것은 이 때문입니다.

3.3 TTL과 「일부 PC만 오래된」 상태

긍정 응답도 TTL 동안 남습니다. 서버의 IP 주소를 바꾸기 전에 이름을 조회한 PC는 오래된 답을 계속 쓰고, 변경 후에 처음 조회한 PC는 새로운 답을 얻습니다. 같은 DNS 서버를 쓰고 있어도 조회한 시각이 다르면 결과는 달라집니다.5

Clear-DnsClientCacheipconfig /flushdns와 같은 동작으로, 부정 응답을 포함한 캐시의 전체 내용을 삭제합니다.16 Get-DnsClientCache라면 캐시를 객체로 꺼내 레코드 종류나 남은 TTL을 확인할 수 있습니다.17

# 특정 이름이 캐시에 있는지, 남은 TTL은 몇 초인지
Get-DnsClientCache -Entry 'app01.corp.example.com' |
    Select-Object Entry, Type, Status, TimeToLive, Data

# hosts와 캐시의 내용을 한꺼번에 확인
ipconfig /displaydns | Select-String -Pattern 'app01' -Context 0,6

# 캐시를 버린다(부정 응답도 포함해)
Clear-DnsClientCache

제1층에서 답이 나오면 이번 검색은 DNS 서버에 닿기 전에 정해집니다. 다만 잘못된 답을 원래 DNS 서버에서 학습했을 가능성은 남습니다. 지우고 끝내지 말고 8장의 절차 3에서 다시 얻은 답도 확인하십시오.

4. 제2층 ── DNS 서버로의 질의

제1층에 답이 없으면 DNS로 나아갑니다. 여기서는 어떤 이름을, 어느 서버로, 어느 시점에 보내는가를 나누어 생각합니다.

4.1 단일 레이블 이름과 접미사

먼저 앱이 넘긴 이름의 형태를 확인합니다.5

이름의 형태 DNS로 보내는 방식
끝에 점이 있는 FQDN(절대 이름) www.contoso.com. 그대로 보낸다
점을 포함하지만 끝에 점이 없는 이름 www.contoso.com 기본적으로는 끝에 점을 붙여 보낸다. 복수 레이블 이름에 대한 접미사 부가를 허용하는 정책이 활성이면 접미사도 시도한다4
점을 포함하지 않는 단일 레이블 이름 www PC의 접미사 설정으로 보완해 보낸다

접미사는 짧은 이름 뒤에 보충하는 도메인 부분입니다. app01corp.example.com을 붙이면 질의하는 이름은 app01.corp.example.com이 됩니다.

검색 목록이 있는 경우

DNS 접미사 검색 목록의 맨 앞부터 차례로 접미사를 붙이고, 끝에 점을 붙인 이름을 보냅니다. 검색 목록을 구성하면 그 목록만 쓰입니다. 기본 접미사, 연결별 접미사, 이름의 잘라내기(devolution)는 쓰이지 않습니다.18

검색 목록이 없는 경우

기본 DNS 접미사를 붙여 보냅니다. 이름의 잘라내기가 활성이면 실패할 때마다 맨 왼쪽 레이블을 떨어뜨려 시도합니다. 예컨대 www.test.contoso.com에서 www.contoso.com으로 나아갑니다. 어댑터에 연결별 DNS 접미사가 있으면 그것도 붙여 보냅니다.5

그래서 그룹 정책으로 검색 목록을 배포하는 환경과 도메인 가입으로 기본 접미사가 붙는 환경에서는, 같은 server01이라도 전개 결과가 다릅니다.

긴 목록은 대기 시간도 늘립니다

올바른 접미사가 목록의 뒤쪽에 있으면 거기에 도달할 때까지의 질의 시간이 쌓입니다. Microsoft도 6개의 접미사를 시도하는 예로 이 지연을 설명합니다. 특정 전개 결과만 시험할 때는 internal.contoso.com.처럼 끝에 점을 붙입니다.3

# 전체 설정: 검색 목록과 잘라내기
Get-DnsClientGlobalSetting

# 인터페이스별: 연결별 접미사와 등록 설정
Get-DnsClient | Select-Object InterfaceAlias, ConnectionSpecificSuffix, UseSuffixWhenRegistering

# 인터페이스별 DNS 서버(IPv4와 IPv6 양쪽)
Get-DnsClientServerAddress | Where-Object ServerAddresses | Select-Object InterfaceAlias, AddressFamily, ServerAddresses

Get-DnsClientGlobalSetting은 검색 목록이나 잘라내기의 유무·단계 수 등의 전체 설정을, Get-DnsClient는 인터페이스별 설정을 돌려줍니다.1920

4.2 여러 DNS 서버의 순서와 타임아웃

「실패하지는 않지만 몇 초 기다려진다」면 무응답인 DNS 서버로의 재전송을 의심합니다. 한 장의 NIC에 설정한 DNS 서버에 대해 기본 재전송 시점을 늘어놓으면 다음과 같습니다.21

시작으로부터 1대 구성 2대 구성 3대 이상 구성
0초 서버에 질의 1대째로 1대째로
1초 재전송 2대째로 2대째로
2초 재전송 2대째로 재전송 3대째로
4초 재전송 전 서버에 동시에 전 서버에 동시에
8초 재전송 전 서버에 동시에 전 서버에 동시에
10초 중단 중단 중단

이는 응답이 없는 경우의 표입니다. 특히 다음 두 가지를 혼동하지 마십시오.

서버의 반응 다음 서버를 시도하는가 읽는 법
무응답 시도한다 재전송과 타임아웃의 문제
「이름이 없다」는 부정 응답 거기서 멈춘다 이름이 없다는 답을 받고 있다

「한쪽을 멈췄는데 전환되지 않는다」고 할 때, 오래된 영역을 가진 서버가 계속 동작하며 부정 응답을 돌려주고 있다면 다음으로 나아가지 않습니다.21

4번째 이후의 서버에는 4초 뒤에야 닿습니다

응답할 수 있는 서버가 목록의 4번째 이후에 있으면 첫 질의부터 최소 4초를 기다립니다. 앱의 기한이 그보다 짧으면 이름 확인 단계에서 실패합니다. 질의를 앞당기려면 앞의 세 자리 중 하나로 옮겨야 하지만, 근본 대책은 닿지 않는 앞선 서버를 고치거나 설정에서 빼는 것입니다. 앱 쪽의 타임아웃도 다시 검토합니다.21

Microsoft의 예에서도 4대 중 1대만 닿는 구성에서는 완료까지 약 4초가 걸립니다. Measure-Command로 소요 시간을 잴 수 있고, 같은 자료는 1초 미만을 허용 범위로 봅니다.3

# 특정 서버에 DNS만으로 직접 묻고, 소요 시간을 밀리초로 얻는다
(Measure-Command {
    Resolve-DnsName -Name 'app01.corp.example.com' -Server 10.0.1.2 -DnsOnly
}).TotalMilliseconds

이 명령은 서버를 고정하므로 그 서버 단독의 응답 시간을 잽니다. 목록의 4번째에 도달할 때까지의 지연은 -Server를 붙이지 않은 질의나 그 캡처로 확인합니다.

참고로 DNS 클라이언트는 응답이 빠른 서버를 위로 올리고, 무응답인 서버를 기억해 주기적으로 재시도합니다. 첫 타임아웃도 과거 실적을 바탕으로 25~1,000밀리초 범위에서 조정됩니다. 위의 표는 기본 골격이며, 실측에 어긋남이 있는 것은 이 때문입니다.5

4.3 여러 NIC와 「스마트 다중 홈 이름 확인」

유선과 Wi-Fi를 가진 PC나 VPN 어댑터가 더해지는 PC에서는, DNS 서버의 목록뿐 아니라 네트워크 간의 질의와 응답의 선택도 확인합니다.

여러 어댑터로의 재전송

Microsoft의 질의 절차에서는 선호 어댑터의 맨 앞 DNS 서버로 보내고 1초 기다립니다. 응답이 없으면 후보에 남은 전 어댑터의 맨 앞 서버로 보내고 2초 기다린 뒤, 그다음에는 전 어댑터의 전 서버로 대기 시간을 2초·4초·8초로 두며 보냅니다. 어떤 어댑터의 서버가 부정 응답을 돌려주면 그 어댑터의 다른 서버는 후보에서 빠집니다.5

병행 질의를 제어하는 정책

그룹 정책 「스마트 다중 홈 이름 확인 끄기」는 다음 동작을 제어합니다.4

정책 동작
기본(미구성) DNS·LLMNR·NetBT를 모든 네트워크로 병행해 질의한다. 긍정 응답이 여럿이면 네트워크의 바인딩 순서로 채택한다
활성 최적화를 멈춘다. 먼저 모든 네트워크에서 DNS를 시도하고, 실패하면 LLMNR, 그것도 실패하면 NetBT라는 직렬이 된다

「끄기」라는 이름의 정책이므로, 정책을 활성화하면 최적화가 비활성화된다는 점에 주의하십시오.

VPN으로 결과가 달라지는 예

사내 이름을 물었을 때 VPN 쪽 DNS는 사내 주소를 돌려주고, 집 라우터 쪽 DNS도 다른 긍정 응답을 돌려주는 경우가 있습니다. 사내와 같은 도메인 이름의 공개 주소나, 존재하지 않는 이름을 대체한 광고 페이지의 주소 같은 것입니다.

긍정 응답이 둘이면 채택은 바인딩 순서로 정해집니다. 현재의 Windows에서는 이 우선순위가 인터페이스 메트릭으로 정해지며, Get-NetIPInterfaceInterfaceMetric이 작을수록 우선됩니다. PC마다의 순서 차이가 결과의 차이가 됩니다.22

한편 집 쪽이 부정 응답을 돌려준 경우에는 그 어댑터가 후보에서 빠지고 VPN 쪽의 답이 쓰입니다.5 VPN 제품이 NRPT나 「스마트 다중 홈 이름 확인 끄기」를 배포하는 것은 이런 차이를 제어하기 위해서입니다.

4.4 NRPT ── 네임스페이스별로 질의 대상을 바꾼다

NRPT(Name Resolution Policy Table, 이름 확인 정책 테이블)는 .corp.contoso.com 같은 네임스페이스별로 사용할 DNS 서버나 DirectAccess·DNSSEC 설정을 지정하는 표입니다. DirectAccess나 Always On VPN의 프로필이 규칙을 써 넣어 「사내 이름만 사내 DNS로 향하게 한다」 같은 동작을 만듭니다.236

Get-DnsClientNrptPolicy -Effective로 실제로 듣고 있는 규칙을 확인할 수 있습니다.

# 실제로 듣고 있는 NRPT 규칙
Get-DnsClientNrptPolicy -Effective

# 특정 네임스페이스의 규칙만 표시한다. -Namespace는 Namespace 속성으로 좁힐 뿐 이름과의 일치 판정은 하지 않는다.
# 'app01.corp.example.com'을 넘겨도 '.corp.example.com'의 접미사 규칙은 돌아오지 않는다.
# 어떤 이름에 어느 규칙이 듣는지는 8장의 절차 4처럼 규칙을 열거해 스스로 대조한다
Get-DnsClientNrptPolicy -Effective -Namespace '.corp.example.com'

NRPT가 듣는 것은 Windows DNS API를 쓰는 앱뿐입니다. 자체 DNS 구현을 가진 앱은 그 경로를 우회합니다. VPNv2 CSP의 자료는 nslookup을 예로 들며, NRPT의 확인에는 Resolve-DnsName을 쓰도록 요구합니다. 브라우저의 내장 확인자나 DoH도 Windows DNS API의 바깥입니다.6

5. 제3층 ── 단일 레이블 이름의 우회로: LLMNR·NetBIOS, 그리고 mDNS

5.1 세 프로토콜의 차이

LLMNR과 NetBIOS over TCP/IP(NetBT)는 app01 같은 단일 레이블 이름을 확인하는 다른 수단입니다. 기본적으로 DNS와 병행해 움직이며, DNS가 긍정 응답을 돌려주어도 링크 로컬의 응답이 채택되는 경우가 있습니다. DNS 실패 후의 직렬이 되는 것은 스마트 다중 홈 이름 확인을 비활성화했을 때뿐입니다.4

mDNS는 이와 달리 .local 이름에 더해지는 경로입니다. 단일 레이블 이름의 DNS 확인이 실패한 뒤의 받침대가 아닙니다.24

프로토콜 포트 닿는 범위 위치
LLMNR UDP 5355의 멀티캐스트. TCP 5355는 유니캐스트 재전송용2526 동일 서브넷 내의 링크 DNS를 구성하지 않고도 쓸 수 있는 2차적인 이름 확인4
mDNS UDP 5353의 멀티캐스트24 멀티캐스트가 닿는 로컬 네트워크 .local 이름의 확인. Microsoft가 앞으로의 축으로 고른 방식27
NetBT UDP 137의 이름 서비스28 브로드캐스트, 또는 WINS 서버로의 질의29 레거시. WINS에서 DNS로의 이전이 권장된다30

.local이라도 DNS의 확인을 건너뛰지 않습니다

.local이 mDNS 전용이 되는 것은 아닙니다. Active Directory 도메인이 corp.local 등인 경우, 그 이름은 계속 설정된 DNS 서버나 NRPT에서도 확인됩니다. RFC 6762도 유니캐스트 DNS와의 병용을 인정합니다. .local 이름의 조사에서도 DNS와 VPN의 정책을 확인하십시오.24

NetBT는 WINS의 유무와 노드 유형에 따라 달라집니다

노드 유형 이름 확인의 방법
B-node 브로드캐스트만
P-node WINS로의 질의만
M-node 브로드캐스트 뒤에 WINS
H-node WINS 뒤에 브로드캐스트

WINS 미구성이면 B-node, 한 대라도 구성되어 있으면 H-node가 기본입니다.29 LLMNR과 NetBT의 브로드캐스트는 서브넷을 넘지 못하지만, WINS로의 질의는 유니캐스트라서 넘을 수 있습니다.

nbtstat -c로 NetBIOS 이름 캐시를 표시하고, nbtstat -R로 캐시의 삭제와 LMHOSTS의 재읽기를 할 수 있습니다.31

5.2 어느 것이 우선되는가

병행해 질의한 뒤 어느 응답을 우선할지도 정책에 따라 달라집니다.4

조건 단일 레이블 이름의 응답 우선순위
기본·도메인에 속하지 않는 네트워크 LLMNR이나 NetBT의 링크 로컬 응답을 DNS보다 우선한다
도메인의 네트워크 DNS 응답을 우선한다
「스마트 프로토콜 재정렬 끄기」를 활성화 모든 네트워크에서 DNS→LLMNR→NetBT의 순으로 우선한다

집이나 외부의 네트워크에서는 같은 이름을 가진 가까운 장비의 답이 DNS보다 우선되는 경우가 있습니다. 여기서도 응답의 우선순위와, 질의가 직렬인지 병행인지를 나누어 읽는 것이 중요합니다.

5.3 Microsoft의 방침: mDNS로 정렬한다

Microsoft는 2022년 4월, mDNS로 정렬하고 NetBIOS 이름 확인과 LLMNR을 단계적으로 축소하는 방침을 공표했습니다.27 Computer Browser 같은 오래되고 안전하지 않은 장비 탐색 프로토콜도 더 이상 사용되지 않습니다.32 단일 레이블 이름을 멀티캐스트나 브로드캐스트로 보완하는 설계는 축소되어 가는 방향입니다.

LLMNR의 취약점에 관한 Microsoft의 정보는 회피책으로 TCP/UDP 5355의 차단이나 그룹 정책 「멀티캐스트 이름 확인 끄기」의 활성화를 듭니다. 그 영향으로 컴퓨터가 다른 컴퓨터에서 보이지 않게 되는 경우가 있다는 점도 명기하고 있습니다.25 이 정책을 활성화하면 DNS 클라이언트의 모든 어댑터에서 LLMNR이 비활성화됩니다.4

비활성화하는 방향 자체는 옳은 판단이지만, 사라지는 경로의 대체를 DNS에 마련해야 합니다. DNS에 등록되지 않은 장비는 A 레코드를 등록하거나 DHCP에 의한 동적 등록을 활성화하고, 목적지를 FQDN으로 바꿉니다. mDNS를 지원하는 장비라면 .local 이름을 쓸 수 있지만, 닿는 범위는 멀티캐스트가 통하는 범위로 한정됩니다.

5.4 「일부 PC만 연결되지 않는다」의 전형: 단일 레이블 이름

설정 파일이나 바로 가기에 \\fileserver01이나 http://app01/이라고 적혀 있으면, 같은 이름이라도 다음과 같은 차이가 나옵니다.

PC의 환경 일어날 수 있는 일
도메인에 가입한 데스크톱 접미사로 app01.corp.example.com으로 보완되어 사내 DNS로 확인할 수 있다
VPN 경유의 노트북 보완 여부는 VPN 프로필에 달렸다. 보완되지 않고 동일 서브넷에도 대상이 없으면 LLMNR이나 NetBT는 헛돈다
다른 서브넷의 사무실 DNS 등록이 없으면 LLMNR과 NetBT의 브로드캐스트는 닿지 않는다. 다만 WINS에 등록이 있으면 확인할 수 있는 경우가 있다2930
LLMNR과 NetBT를 모두 비활성화한 PC DNS에 없는 이름은 확인할 수 없다. LLMNR만 비활성화했다면 NetBT나 WINS로 확인할 여지가 남는다

Resolve-DnsName app01 -LlmnrOnly로 알 수 있는 것은 「LLMNR로 확인할 수 있는가」입니다. 평소의 질의에서 채택된 답의 출처까지는 알 수 없습니다. 스위치 없는 결과와의 비교나 캡처는 8장의 절차 5에서 합니다.8

근본 대책은 FQDN화와 DNS 등록

단일 레이블 이름에 의존하는 목적지를 FQDN으로 바꾸고, 이름 확인을 DNS로 모읍니다.

SMB2 이상은 TCP 445로 직접 연결하며 NetBIOS의 세션을 쓰지 않습니다.33 그러나 그것은 전송 경로의 이야기입니다. \\fileserver01\share라는 목적지의 이름을 확인하는 단계에서는 LLMNR이나 NetBT가 쓰이는 경우가 있습니다. \\fileserver01.corp.example.com\share처럼 FQDN으로 지정해 단일 레이블 이름 경로에 대한 의존을 없앱니다.

다만 FQDN에도 다음 주의가 남습니다. 끝에 점이 없는 FQDN은, 복수 레이블 이름에 대한 접미사 부가 정책이 활성이면 보완도 시도됩니다. .local로 끝나는 이름은 mDNS를 병용할 수 있습니다. 무조건 고정하기 위한 절대 이름은 끝에 점을 붙인 형태입니다. 실무에서 「FQDN이면 DNS에 고정된다」고 다루는 전제는, 위 정책이 비활성이고 사내 도메인 이름에 .local을 쓰지 않는다는 것입니다.

6. DNS 서버로의 전송 경로 ── DoH는 순서를 바꾸지 않는다

6.1 Windows 11 / Windows Server 2022의 DoH

Windows의 DoH는 DNS 서버로의 질의를 HTTPS로 보내는 기능입니다. 기존의 hosts·캐시·NRPT나 어댑터·프로필별 확인자 지정과 통합되며, 3~4장의 순서를 대체하지 않습니다.9

Windows 11의 DNS 클라이언트는 DoH를 지원하고, 새로운 버전에서는 DoT(DNS over TLS)도 지원합니다. 다만 Microsoft의 해설은 DoT의 지원 버전을 명시하지 않으므로, 이 글의 전제 환경 전부에서 쓸 수 있다고는 할 수 없습니다. 아래에서는 DoH를 다룹니다.9

먼저 알려진 DoH 서버 목록을 확인합니다

DDR을 활성화하지 않은 경우, 쓸 수 있는 것은 알려진 DoH 서버 목록에 실린 서버입니다. 기본 목록에는 Cloudflare·Google·Quad9이 있으며, Get-DnsClientDohServerAddress로 확인할 수 있습니다. 사내 DNS 등은 DoH 템플릿과 폴백·자동 승격 설정을 등록합니다.134

# 알려진 DoH 서버 목록
Get-DnsClientDohServerAddress

# 사내 DNS를 DoH 서버로 등록(평문 폴백 없음·자동 승격 있음)
Add-DnsClientDohServerAddress -ServerAddress '10.0.1.2' `
    -DohTemplate 'https://dns.corp.example.com/dns-query' `
    -AllowFallbackToUdp $false -AutoUpgrade $true

netsh dnsclient add encryption으로도 등록할 수 있습니다. 전체의 netsh dnsclient set global doh=yes|no|auto는 서버별 autoupgrade와는 다른 설정입니다.35

전체 설정 의미
doh=no DoH를 금지한다
doh=yes 서버나 어댑터의 설정에 따라 DoH를 허용한다
doh=auto 알려진 DoH 서버로의 질의를 자동으로 DoH로 강제한다

auto만으로는 평문으로의 복귀를 금지하지 않습니다. 실패 시 UDP로 되돌릴지는 서버별 udpfallback, PowerShell에서는 -AllowFallbackToUdp가 따로 정합니다. 암호화만으로 한정하려면 폴백도 비활성화합니다.35

DDR이 활성이면 동적인 발견 경로도 있습니다

DDR(Discovery of Designated Resolvers)을 지원하는 버전에서는 평문으로 설정한 확인자가 암호화 DNS의 엔드포인트를 통지할 수 있습니다. 정적인 목록에 등록하지 않아도 암호화로 승격될 수 있으므로 「목록에 없으니 DoH가 아니다」라고 단정할 수 없습니다.35

DDR이 작동하려면 전체의 netsh dnsclient set global ddr=yes와 어댑터별 set interface <이름> ddr=yes양쪽이 필요합니다. DDR로 얻은 암호화 확인이 실패했을 때의 평문 복귀는 ddrfallback으로 정해지며 기본은 비활성입니다.

조사에서는 알려진 목록에 더해 netsh dnsclient show globalnetsh dnsclient show state, DNS 서버를 가진 어댑터에 set interface로 설정한 값을 확인합니다. 자료에 정의된 showencryption·global·state이며, 어댑터 전용의 표시 하위 명령은 없습니다.35

「허용」「요구」와 평문으로의 복귀를 나눕니다

설정 앱에서는 DNS 설정을 수동으로 하고, 기본 설정 DNS 서버가 알려진 목록에 있을 때만 「기본 설정 DNS 암호화」를 고를 수 있습니다. 선택지는 다음 세 가지입니다.1

설정 앱의 선택지 동작
암호화만(DNS over HTTPS) 암호화만 쓴다
암호화를 우선하고 암호화되지 않은 통신도 허용 DoH 실패 시 통지 없이 평문으로 되돌아간다
암호화되지 않은 통신만 평문으로 보낸다

그룹 정책 「DNS over HTTPS(DoH) 이름 확인 구성」에는 허용·금지·요구가 있습니다. 허용인 경우에는 알려진 목록에의 등록에 더해 자동 승격·어댑터의 암호화 설정·전체의 doh=auto 등의 조건으로 DoH를 씁니다. 「요구」에서는 DoH 미지원 서버에 의한 이름 확인 자체가 실패합니다.135

도메인에 가입한 PC에 「DoH를 요구」를 적용해서는 안 됩니다. Microsoft가 분명히 주의하고 있습니다. Active Directory Domain Services는 DNS에 강하게 의존하고, Windows Server 표준의 DNS 서버 서비스가 DoH 질의를 지원하지 않기 때문입니다.1

캡처에서는 설정과 실제 통신을 나누어 읽습니다

실제로 DoH로 보낸 질의는 UDP 53이 아니라 443번의 TLS에 들어갑니다. 다만 「DoH를 허용」하고 있어도, 알려진 목록에 없는 서버로의 질의나 암호화 실패 후의 폴백은 평문으로 흐릅니다. DoH의 설정이 있다고 해서 53번의 통신이 사라지는 것은 아닙니다.

DNS 질의가 보이지 않으면 hosts·캐시에 더해 DoH와 DoT(853번)도 확인합니다. 채취 방법은 패킷 캡처 글을 참조하십시오.

6.2 브라우저의 DoH는 OS와 별개입니다

Edge의 내장 DNS 클라이언트와, 보안 DNS에 의한 질의 대상의 변경은 두 단계로 나누면 이해하기 쉬워집니다.

설정 질의하는 주체·상대
기본의 내장 DNS 클라이언트 OS의 DNS 클라이언트가 아니라 Edge가 질의한다. 쓰는 DNS 서버 자체는 바뀌지 않는다
보안 DNS로 현재의 공급자를 사용 현재의 공급자에 암호화해 질의한다. 실패하면 평문으로 재시도한다
보안 DNS로 다른 공급자를 선택 고른 DoH 확인자에 질의한다. 실패해도 평문으로 되돌아가지 않는다

내장 클라이언트는 BuiltInDnsClientEnabled로 제어하며, DoH의 질의는 항상 내장 확인자가 수행합니다.7 보안 DNS는 조직 관리하의 PC에서는 기본적으로 비활성이며, DnsOverHttpsMode(off / automatic / secure)와 DnsOverHttpsTemplates로 구성합니다.3637

다른 공급자를 고른 Edge는 사외 사이트는 조회할 수 있어도 사내 DNS만 아는 이름은 조회하지 못할 수 있습니다. 반대로 OS의 DNS가 불안정해도 Edge만은 열리는 경우가 있습니다. 현재의 공급자 그대로라면 질의 대상이 바뀌는 것은 아닙니다.

결론은 브라우저의 성공과 업무 앱의 성공을 같은 경로의 증거로 다루지 않는 것입니다. OS의 경로는 Resolve-DnsName이나 ping으로 확인합니다.

7. 앱은 어느 경로를 지나는가

조사에 쓸 도구를 고르기 전에, 보고 있는 경로를 맞춥니다.

호출 지나는 경로 hosts 캐시 NRPT LLMNR/NetBT
getaddrinfo / Dns.GetHostAddresses / HttpClient(직접 연결 시)1011 OS의 DNS 클라이언트 서비스. 프록시 경유의 HttpClient는 프록시 이름만 로컬에서 확인하고 목적지는 프록시가 확인한다 본다 본다 듣는다 단일 레이블 이름에서 쓴다(기본은 DNS와 병행. 실패 후의 직렬은 최적화 비활성 시에만)
ping OS의 DNS 클라이언트 서비스 본다 본다 듣는다 단일 레이블 이름에서 쓴다(기본은 DNS와 병행. 실패 후의 직렬은 최적화 비활성 시에만)
Resolve-DnsName8 OS의 DNS 클라이언트 서비스(스위치로 층을 고를 수 있다) -NoHostsFile로 뺄 수 있다 -CacheOnly로 한정 듣는다 -DnsOnly로 뺄 수 있다
nslookup123 맨 앞의 DNS 서버로 직접 보지 않는다 보지 않는다 듣지 않는다 쓰지 않는다
Microsoft Edge(기본)76 내장 DNS 클라이언트(OS의 DNS 클라이언트를 거치지 않는다) OS의 경로와는 별개 OS의 캐시와는 별개 듣지 않는다(Windows DNS API의 바깥) OS의 경로와는 별개

Resolve-DnsName의 주요 스위치를 조사 목적별로 정리하면 다음과 같습니다.8

확인하고 싶은 것 스위치
로컬 캐시만으로 답이 나오는가 -CacheOnly
hosts를 빼고 시험하고 싶다 -NoHostsFile
DNS 프로토콜만 쓰고 LLMNR·NetBIOS를 내보내고 싶지 않다 -DnsOnly
특정 DNS 서버에 묻고 싶다 -Server
LLMNR만 시험하고 싶다 -LlmnrOnly
LLMNR 또는 NetBIOS만 시험하고 싶다 -LlmnrNetbiosOnly
DNS 실패 시 NetBIOS로 내려가는 것을 허용하고 싶다 -NetbiosFallback
레코드 종류를 고르고 싶다 -Type. 기본은 A와 AAAA 양쪽을 묻는 A_AAAA

7.1 A와 AAAA, IPv6가 먼저 돌아온다

이름 확인이 성공해도 그 뒤의 주소 선택에서 연결이 느려지는 경우가 있습니다.

DNS 클라이언트는 A(IPv4)와 AAAA(IPv6) 양쪽을 질의합니다. 캡처에서도 양쪽의 질의가 짝으로 보입니다.3 답을 돌려준 뒤 getaddrinfo와 연결 쪽 스택이 쓸 주소를 고릅니다. Windows Vista 이후는 RFC 3484의 접두사 테이블을 쓰며, 기본적으로 IPv6의 글로벌 유니캐스트를 IPv4보다 우선합니다.38

다만 AAAA가 돌아왔다고 해서 반드시 IPv6 연결을 시도하는 것은 아닙니다. 대상 선택에서는 IPv6의 원본 주소나 경로가 없는 등 쓸 수 없는 대상을 먼저 빼고 나서 후보를 늘어놓습니다.39

문제가 되는 것은 IPv6의 원본 주소와 경로가 언뜻 있는 것 같지만 실제로는 통하지 않는 환경입니다. 이름 확인은 성공해도 연결에서 시간을 잃습니다. IPv6가 정말로 시도되었는지는 DNS 응답만이 아니라 연결 로그나 캡처로 확인합니다.

Microsoft는 대처로 IPv6를 비활성화하는 것을 권장하지 않습니다. Windows의 일부 구성 요소가 동작하지 않게 되기 때문입니다. 대신 DisabledComponents0x20으로 해서 접두사 정책에서 IPv4를 우선하는 방법을 안내합니다.38 localhost::1로 확인되어 127.0.0.1을 가정한 조사와 어긋나는 예는 패킷 캡처 글에서도 다룹니다.

8. 분리 절차 ── 층을 위에서부터 차례로 벗긴다

연결되지 않는 PC에서 다음 순서로 실행합니다. 각 명령은 경로를 한정하기 위한 것이며, 성공했다는 것만으로 평소의 확인 경로까지 증명할 수는 없습니다. 결과의 비교와 마지막 캡처를 조합합니다.

절차 확인할 것
1 앱이 넘긴 이름의 형태
2 캐시와 hosts의 답
3 hosts·LLMNR·NetBIOS를 뺀 DNS의 결과
4 실제 확인 경로에 있는 DNS 서버별 결과
5 단일 레이블 이름의 LLMNR·NetBT에 의한 확인
6 연결되는 PC와 연결되지 않는 PC의 설정 차이
7 패킷이 나갔는지, 무엇이 돌아왔는지

절차 1: 이름의 형태를 확인한다

로그나 설정 파일에서 앱이 실제로 넘기고 있는 이름을 확인합니다. 단일 레이블 이름인지, .local로 끝나는지, 끝에 점이 있는지에 따라 경로가 달라집니다. http://app01/ 같은 짧은 이름이라면 4.1절의 보완과 5.4절의 PC별 차이부터 조사합니다.

절차 2: 캐시와 hosts만으로 확인할 수 있는가

Resolve-DnsName -Name 'app01.corp.example.com' -CacheOnly
Get-DnsClientCache -Entry 'app01.corp.example.com'
Get-Content "$env:SystemRoot\System32\drivers\etc\hosts" | Select-String -Pattern 'app01'
결과 읽는 법과 다음 확인
올바른 답이 나온다 이번에는 DNS 서버에 닿기 전에 답이 정해져 있다
오래된·잘못된 답이 나온다 hosts라면 그 줄을 수정한다. 캐시라면 지운 뒤 절차 3에서 다시 얻은 답을 확인한다
「Name does not exist」 부정 캐시. Clear-DnsClientCache 뒤에 절차 3으로 나아간다
답이 없다 통상의 캐시 미스일 가능성이 있다. 절차 3으로 나아간다

-CacheOnly는 이번 검색을 로컬 캐시로 한정할 뿐입니다. 잘못된 답을 DNS 서버에서 학습했다면 지워도 같은 값이 돌아옵니다. 캐시에 있었다는 것은 DNS 서버가 무관하다는 증명이 되지 않습니다.8

절차 3: DNS만으로 확인할 수 있는가

# hosts를 빼고 LLMNR/NetBIOS도 내보내지 않으며, 설정된 DNS 서버만으로 조회한다
Resolve-DnsName -Name 'app01.corp.example.com' -NoHostsFile -DnsOnly

절차 2에서 답이 없고 여기서 성공했을 뿐이라면 대개는 통상의 캐시 미스입니다. 캐시나 hosts의 문제라고 말할 수 있는 것은 절차 2에 오래된 답, 잘못된 답, 부정 캐시가 있었던 경우입니다.

여기서도 실패한다면 DNS 서버로의 경로, 서버 쪽, 클라이언트 쪽의 정책을 조사합니다. 절차 4로 나아가기 전에 다음을 확인하십시오.

  • Get-DnsClientNrptPolicy -Effective: 다른 DNS 서버로 향하게 하는 규칙이 없는지.
  • Get-DnsClientDohServerAddress와 DoH의 그룹 정책: 미지원 서버에 「DoH를 요구」하고 있지 않은지.

NRPT가 있으면 절차 4의 대상 서버가 달라집니다. 「DoH를 요구」가 원인이라면 경로도 서버도 건전한 채로 이름 확인만 실패합니다. 4.4절·6.1절의 확인을 먼저 끝냅니다.

절차 4: 서버별로 직접 묻는다

연결 중인 어댑터의 DNS 서버를 모으고, 대상 이름에 NRPT가 듣는 경우에는 그 규칙의 서버로 바꿉니다. IPv6로만 설정된 DNS 서버도 대상으로 삼습니다.

$name = 'app01.corp.example.com'
# 연결 중인 인터페이스의 DNS 서버를 IPv4·IPv6 양쪽에서 모은다.
# 끊긴 VPN이나 가상 스위치에 남은 설정의 서버는 지금의 확인 경로와 관계없으므로 제외한다(IPv6로만 설정된 서버는 놓치지 않는다)
$connected = @((Get-NetIPInterface -ConnectionState Connected).ifIndex | Select-Object -Unique)
$servers = @((Get-DnsClientServerAddress |
    Where-Object { $_.ServerAddresses -and ($connected -contains $_.InterfaceIndex) }).ServerAddresses)
# 이 이름에 듣고 있는 NRPT 규칙의 서버(Always On VPN이나 DirectAccess가 써 넣는 것)는 어댑터의 설정에 나타나지 않으므로 실효 정책에서 고른다.
# Get-DnsClientNrptPolicy의 -Namespace는 규칙의 Namespace 속성으로 좁힐 뿐 이름과의 일치 판정은 하지 않는다.
# 그래서 Any 규칙(.)·접미사 규칙(맨 앞이 점. 네임스페이스 자체와 자식 도메인에 듣는다)·FQDN 규칙·접두사 규칙(호스트 이름 부분. web* 같은 와일드카드도 가능)을 스스로 대조하고,
# 더 구체적인(긴) 규칙을 채택한다. Any 규칙은 가장 짧으므로 다른 일치 규칙이 없을 때만 선택된다
# Namespace는 문자열의 집합(Namespace : {.corp.example.com}처럼 표시된다)이므로, 규칙마다 요소를 펼쳐 대조하고 일치한 네임스페이스의 길이로 정렬한다
# 끝에 점을 붙인 절대 이름(app01.corp.example.com.)은 대조할 때만 점을 뗀다. Resolve-DnsName에는 원래의 $name을 넘긴다
$matchName = $name.TrimEnd('.')
$label = $matchName.Split('.')[0]
$matched = foreach ($policy in @(Get-DnsClientNrptPolicy -Effective)) {
    foreach ($ns in @($policy.Namespace)) {
        if (-not $ns) { continue }
        $hit = if ($ns -eq '.') { $true }
               elseif ($ns.StartsWith('.')) { $matchName.Equals($ns.TrimStart('.'), [System.StringComparison]::OrdinalIgnoreCase) -or $matchName.EndsWith($ns, [System.StringComparison]::OrdinalIgnoreCase) }
               elseif ($ns.Contains('.')) { $matchName.Equals($ns, [System.StringComparison]::OrdinalIgnoreCase) }
               else { $label -like $ns }
        if ($hit) { [pscustomobject]@{ Namespace = $ns; Policy = $policy } }
    }
}
$rule = $matched | Sort-Object { $_.Namespace.Length } -Descending | Select-Object -First 1
$policyServers = @()
if ($rule) { $policyServers = @(@($rule.Policy.NameServers) + @($rule.Policy.DirectAccessDnsServers) | Where-Object { $_ }) }
if ($policyServers.Count -gt 0) {
    # NRPT가 이 네임스페이스의 서버를 지정하고 있다면 절차 3의 질의는 그 서버로 향한다. 어댑터의 서버는 경로 밖이므로 바꾼다
    $servers = $policyServers
}
$servers = $servers | Where-Object { $_ } | Select-Object -Unique
foreach ($server in $servers) {
    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    try {
        $r = Resolve-DnsName -Name $name -Server $server -DnsOnly -ErrorAction Stop
        $status = 'OK'
        # 여러 레코드는 응답마다 배열이 달라질 수 있으므로 정렬한 뒤 비교한다
        $answer = ($r.IPAddress | Sort-Object) -join ','
    } catch {
        # 부정 응답(이름이 없다)·SERVFAIL·타임아웃은 여기로 온다. 이유를 버리지 말고 남긴다
        $status = $_.Exception.Message
        $answer = ''
    }
    [pscustomobject]@{ Server = $server; Status = $status; Answer = $answer; Milliseconds = [int]$sw.ElapsedMilliseconds }
}

먼저, 비교할 서버를 맞춥니다

NRPT의 NameServersDirectAccessDnsServers는 어댑터의 DNS 설정에 나타나지 않는 경우가 있습니다. 절차 3에서 NRPT의 서버에 묻고 있는데 절차 4에서 어댑터의 서버만 조사하면, 다른 경로를 비교하게 됩니다.

NRPT에는 접미사, FQDN, 접두사, Any(.) 등의 규칙이 있고 더 구체적인 규칙이 우선됩니다.40 -Namespace는 규칙의 속성으로 좁힐 뿐 호스트 이름과의 일치 판정은 하지 않습니다. 그래서 위의 코드는 규칙의 네임스페이스를 펼쳐 대상 이름과 대조합니다.23

분할 DNS의 VPN에서는 집 쪽의 확인자가 사내 이름에 부정 응답을 돌려주고 NRPT 쪽만 긍정 응답을 돌려주는 것이 정상입니다. 경로 밖의 서버도 비교하는 경우에는 「대조」로 따로 기록하고, 영역의 불일치 판정에는 섞지 않습니다. 끊긴 어댑터에 남은 서버로의 타임아웃도 현재 확인 경로의 지연과는 별개입니다.

다음으로, 결과를 가려 읽습니다

결과 조사할 것
특정 서버만 타임아웃한다 그 서버가 무응답이 된 이유
「이름이 존재하지 않는다」 등의 부정 응답 타임아웃과 구별하고, 이름과 영역의 내용을 확인한다
응답의 IP 주소가 다르다 같은 역할의 서버끼리인지 확인하고, 레코드 집합으로 비교한다
레코드의 순서만 다르다 라운드 로빈일 가능성. 정렬한 집합이 같다면 순서만으로 영역 불일치로 보지 않는다

집합으로도 다르면 영역의 내용이나 일련번호를 확인합니다. 또한 여기는 -Server로 대상을 고정한 측정입니다. 4.2절의 「4번째 이후에 닿기까지 4초」라는 목록 위치에 따른 지연은 절차 3이나 그 캡처로 확인합니다.

절차 5: 링크 로컬의 층을 확인한다

Resolve-DnsName -Name 'app01' -LlmnrOnly          # LLMNR만
Resolve-DnsName -Name 'app01' -LlmnrNetbiosOnly   # LLMNR이나 NetBIOS만(DNS는 쓰지 않는다)
nbtstat -c                                        # NetBIOS 이름 캐시

이 확인은 단일 레이블 이름이 대상입니다. -NetbiosFallback은 DNS 실패 시에만 NetBIOS로 내려가므로, DNS로 조회되는 이름에서는 NetBIOS의 확인이 되지 않습니다.8

결과는 다음과 같이 읽습니다.

결과 알 수 있는 것/아직 알 수 없는 것
-LlmnrOnly로 성공 LLMNR로 확인할 수 있다. 다만 평소에도 그 답을 채택했다고는 할 수 없다
-LlmnrOnly는 실패하고 -LlmnrNetbiosOnly로 성공 NetBIOS가 답했다고 단정할 수 없다. 누락이나 상대의 시작 시점에 따라 뒤의 시도에서 LLMNR이 답했을 가능성도 있다
연결되는 PC에서는 이 층만 성공하고, 연결되지 않는 PC에서는 실패 단일 레이블 이름 경로에 대한 의존을 의심한다. 근본 대책은 FQDN화와 DNS 등록

어느 프로토콜이 답했는지는 캡처에서 UDP 5355(LLMNR)와 UDP 137(NetBT)로 가려냅니다. 평소의 확인 경로를 확인하려면 스위치 없는 Resolve-DnsName이 돌려주는 주소와도 비교하고, 어긋나는 경우에는 캡처로 채택된 응답을 확인합니다. 기본적으로는 DNS도 병행해 질의되기 때문입니다.

절차 6: 설정 덤프의 차이를 본다

「일부 PC만」의 조사에서는 연결되는 PC와 연결되지 않는 PC에서 같은 스크립트를 실행해 비교합니다.

# name-resolution-dump.ps1 -- 관리자 권한으로 실행하고, 출력 파일을 두 대분 나란히 비교한다
$out = "$env:COMPUTERNAME-name-resolution.txt"
$sections = [ordered]@{
    'Get-DnsClientServerAddress' = { Get-DnsClientServerAddress | Format-Table -AutoSize | Out-String -Width 200 }
    'Get-DnsClientGlobalSetting' = { Get-DnsClientGlobalSetting | Format-List | Out-String }
    'Get-DnsClient'              = { Get-DnsClient | Format-Table InterfaceAlias, ConnectionSpecificSuffix, UseSuffixWhenRegistering -AutoSize | Out-String -Width 200 }
    'Get-DnsClientNrptPolicy'    = { Get-DnsClientNrptPolicy -Effective | Format-List | Out-String }
    'Get-DnsClientDohServerAddress' = { Get-DnsClientDohServerAddress | Format-Table -AutoSize | Out-String -Width 200 }
    'netsh dnsclient show state' = { netsh dnsclient show state 2>&1 | Out-String }
    'Get-NetIPInterface'         = { Get-NetIPInterface | Sort-Object AddressFamily, InterfaceMetric | Format-Table InterfaceAlias, AddressFamily, InterfaceMetric, ConnectionState, Dhcp -AutoSize | Out-String -Width 200 }
    'DNSClient policy registry'  = { Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient' -ErrorAction SilentlyContinue | Format-List | Out-String }
    'ipconfig /all'              = { ipconfig /all | Out-String }
}
$sections.GetEnumerator() | ForEach-Object {
    "===== $($_.Key) ====="
    try { & $_.Value } catch { "ERROR: $($_.Exception.Message)" }  # 없는 항목(Windows 10의 DoH 등)은 오류로 남긴다
} | Set-Content -Path $out -Encoding UTF8
Write-Host "wrote $out"

비교하는 것은 DNS 서버의 배열, 검색 목록, 연결별 접미사, NRPT, DoH, 인터페이스 메트릭, 정책 값입니다.

HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient에는 「멀티캐스트 이름 확인 끄기」의 EnableMulticast, 「스마트 다중 홈 이름 확인 끄기」의 DisableSmartNameResolution, 검색 목록이나 기본 접미사 등이 들어갑니다.4 차이를 여기까지 정리한 각 층의 작용과 대조해 봅니다.

절차 7: 패킷 캡처로 뒷받침한다

Microsoft의 데이터 수집 절차는 클라이언트와 서버 양쪽에서 netsh trace start capture=yes를 시작하고, ipconfig /flushdns로 캐시를 버린 뒤 재현하고, netsh trace stop으로 멈추는 흐름입니다.41

Wireshark에서는 dns.qry.name == "app01.corp.example.com"이나 dns.qry.name contains "app01"로 좁혀, 어느 서버에 무엇을 묻고 무엇이 돌아왔는지 확인합니다.

캡처에서 보인 것 조사할 곳
질의가 나가지 않는다 캐시·hosts, DoH·DoT나 링크 로컬 등 다른 경로에 더해, 송신 측 방화벽에 의한 UDP 53의 차단을 확인한다
질의는 나가지만 응답이 없다 DNS 서버로의 경로, 방화벽, 서버의 무응답
부정 응답이 돌아온다 질의한 이름과 서버 쪽의 레코드
긍정 응답이 돌아온다 이름 확인 후의 연결 쪽. 쓰인 주소나 IPv6도 확인한다

송신 측 방화벽에서 UDP 53을 차단하고 있는 경우, Resolve-DnsName은 타임아웃하고 캡처에도 DNS 질의가 나타나지 않습니다. 이름 확인이 성공하고 통신이 나가지 않는 경우뿐 아니라, 실패해서 통신이 나가지 않는 경우도 분리합니다.3

DNS 외에도 LLMNR은 5355, mDNS는 UDP 5353, NetBT의 이름 서비스는 UDP 137을 확인합니다. DoH는 443, DoT는 853입니다. 캡처의 채취와 읽는 법은 패킷 캡처 글에 정리했습니다.

9. 업무 앱 쪽의 설계 ── 이름 확인에 강하게 만든다

조사를 가볍게 하려면 앱 쪽이 「어떤 이름을, 무엇으로 확인했고, 어디서 실패했는지」를 남길 수 있는 것이 중요합니다. 앱의 로그와 정보시스템 담당이 채취하는 설정 덤프·캡처를 맞춰 보면, 8장의 어디부터 조사할지 정하기 쉬워집니다.

목적지는 FQDN으로 가지고, hosts에 의존하지 않는다

설정 파일의 기본값, 바로 가기, UNC 경로는 FQDN으로 합니다. 단일 레이블 이름의 접미사 보완이나 LLMNR·NetBT에 대한 의존을 없애기 위해서입니다. 다만 .local 이름의 mDNS 병용과, 끝에 점이 없는 이름에 대한 접미사 부가 정책이라는 5.4절의 주의는 남습니다.

hosts는 개발 중의 일시적인 덮어쓰기에는 편리하지만, 관리자 권한과 수작업이 필요합니다. 배포나 변경 이력을 관리하기 어렵고, 확인자에 따라서는 참조하지도 않습니다(nslookup은 참조하지 않습니다12). 목적지의 전환은 설정 파일에서 합니다.

이름 확인의 결과·시간·실패 이유를 기록한다

시작 시 등에 주요 목적지의 IPv4·IPv6 주소와 소요 시간을 기록합니다. Dns.GetHostAddressesgetaddrinfo와 같은 결과를 돌려주므로, 「어느 PC에서, 언제부터, 무엇으로 확인되고 있었는지」를 좇을 수 있습니다.11

// 시작 시 주요 목적지의 이름 확인 결과를 기록한다(.NET 6 이상)
static async Task LogNameResolutionAsync(ILogger logger, string host)
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    try
    {
        var addresses = await System.Net.Dns.GetHostAddressesAsync(host);
        logger.LogInformation("이름 확인 {Host} -> {Addresses} ({Elapsed} ms)",
            host, string.Join(",", addresses.Select(a => a.ToString())), sw.ElapsedMilliseconds);
    }
    catch (System.Net.Sockets.SocketException ex)
    {
        logger.LogError(ex, "이름 확인 실패 {Host} 오류 {Code} ({Elapsed} ms)",
            host, ex.SocketErrorCode, sw.ElapsedMilliseconds);
        throw;
    }
}

실패는 로그에 남기고 다시 던집니다. 다른 이름이나 고정 IP로 말없이 바꾸면 조사할 때 실제 경로를 알 수 없게 되기 때문입니다. 오류 코드와 소요 시간이 있으면 정보시스템 담당은 절차 2~4의 어디부터 시작할지 판단할 수 있습니다.

타임아웃과 IPv6의 답을 감안한다

DNS 클라이언트는 무응답인 서버에 대해 질의하는 후보 하나당 최대 10초를 씁니다.21 접미사 검색으로 후보가 여럿이 되면 전체로는 10초를 넘을 수도 있습니다.

연결 타임아웃을 2~3초로 줄이면, 답할 수 있는 서버가 4번째 이후에 있는 구성 등에서는 기한까지 이름 확인이 끝나지 않습니다. 다만 2대째에는 1초 뒤, 3대째에는 2초 뒤에 질의하므로 한 대가 죽었다고 해서 반드시 실패하는 것은 아닙니다. 4.2절의 재전송 시간을 감안해 설계합니다.

또한 AAAA가 돌아오고 IPv6의 원본 주소와 경로가 있으면 Windows는 기본적으로 IPv6를 우선합니다.38 IPv4만 상정한 연결 코드에서는 이름 확인에 성공했는데 연결에 실패하는 경우가 있습니다. 이름 확인의 성공과 연결의 성공을 나누고, 양쪽 주소를 다룰 수 있게 합니다.

10. 정리

Windows의 이름 확인에서 가장 먼저 나눌 것은 이름의 형태, 답을 돌려주는 층, 앱이 지나는 경로입니다.

캐시와 hosts가 먼저 답하고, 단일 레이블 이름에서는 기본적으로 DNS와 LLMNR·NetBT가 병행해 움직입니다. .local에는 mDNS도 더해집니다. DNS로 나아간 뒤에는 접미사, 재전송 시간, 여러 NIC, NRPT가 결과를 바꿉니다. DoH는 그 전송 경로를 바꾸는 기능이며, 브라우저의 내장 확인자와는 나누어 생각합니다.

조사는 -CacheOnly-NoHostsFile -DnsOnly-Server-LlmnrOnly의 순으로 경로를 한정하고, 설정 덤프의 차이와 캡처로 확인합니다. 부정 캐시, 무응답과 부정 응답의 차이, 클라이언트 쪽의 정책을 놓치지 않는 것이 중요합니다.

「이 PC만 연결되지 않는다」고 할 때는 먼저 다음 두 가지를 확인하십시오.

그 이름은 어떤 형태로 넘겨지고 있습니까. 그 PC에서는 어느 경로가 답하고 있습니까.

이 두 가지를 맞추면 조사할 곳을 좁힐 수 있습니다.

관련 글

관련된 상담 영역

합동회사 코무라소프트에서는 「일부 PC에서만 업무 앱이 사내 서버에 연결되지 않는다」「브라우저에서는 열리는데 앱에서는 이름 확인에 실패한다」 같은 이름 확인에서 비롯된 통신 문제의 원인 조사, LLMNR 비활성화·DoH·VPN 같은 환경 변경을 업무 앱이 견딜 수 있는지에 대한 설계 리뷰, 이름 확인의 결과와 타임아웃을 기록하는 통신 계층의 구현을 다룹니다. 연결되는 PC와 연결되지 않는 PC의 설정 덤프를 첨부해 상담해 주시면 조사의 입구가 빨리 정해집니다.

참고 링크

  1. Microsoft Learn, Secure DNS Client over HTTPS (DoH). DoH를 구성할 수 있는 것은 기본 설정/대체 DNS 서버가 알려진 DoH 서버 목록에 있는 경우뿐이라는 점, 설정 앱의 세 가지 암호화 선택지와 「암호화를 우선」이 통지 없이 평문으로 되돌아간다는 점, 그룹 정책 「DNS over HTTPS(DoH) 이름 확인 구성」의 Allow/Prohibit/Require, 도메인에 가입한 PC에서 Require를 활성화해서는 안 되는 이유, 알려진 서버 목록(Cloudflare·Google·Quad9)과 Get-DnsClientDohServerAddress, Add-DnsClientDohServerAddress에 의한 추가, NRPT와의 병용에 대해.  2 3 4 5

  2. Microsoft Learn, MSFT_DNSClientGlobalSetting class. DnsClient cmdlet의 기반이 되는 WMI 클래스의 최소 지원 OS가 Windows 8 / Windows Server 2012라는 점에 대해. 

  3. Microsoft Learn, Troubleshoot DNS client name resolution issues. DNS 클라이언트가 캐시→hosts 파일→DNS 서버의 순으로 확인한다는 점, hosts에 해당이 있으면 DNS 통신이 흐르지 않는다는 점, UDP 53을 막으면 Resolve-DnsName이 타임아웃한다는 점, 여러 서버 중 닿는 것이 적으면 약 4초가 걸린다는 점, nslookup이 맨 앞의 DNS 서버에만 질의한다는 점, 긴 접미사 검색 목록에 의한 지연, 끝의 점에 의한 특정 질의, Measure-Command에 의한 소요 시간 측정에 대해.  2 3 4 5 6 7 8 9

  4. Microsoft Learn, Policy CSP - ADMX_DnsClient. 「스마트 다중 홈 이름 확인 끄기」(기본으로 모든 네트워크에 DNS·LLMNR·NetBT를 병행해 질의하고 여러 긍정 응답은 바인딩 순서로 채택. 활성화하면 DNS→LLMNR→NetBT의 직렬), 「스마트 프로토콜 재정렬 끄기」(기본으로 비도메인 네트워크의 단일 레이블 이름은 링크 로컬 응답을 우선), 「멀티캐스트 이름 확인 끄기」(LLMNR이 2차적 프로토콜이라는 점과 모든 어댑터에서 비활성화된다는 점, 레지스트리 값 EnableMulticast), DNS 접미사 검색 목록과 잘라내기, 「복수 레이블의 정규화되지 않은 이름 질의에 DNS 접미사 부가를 허용」(점을 포함하지만 끝에 점이 없는 이름에도 접미사를 붙여 질의하는 정책), 기본 DNS 접미사, 연결별 접미사, 레지스트리 키 Software\Policies\Microsoft\Windows NT\DNSClient에 대해.  2 3 4 5 6 7 8 9

  5. Microsoft Learn, DNS queries and lookups. hosts의 내용이 DNS 클라이언트 서비스 시작 시 캐시로 읽어들여지고 DNS 응답도 TTL 동안 캐시에 보관된다는 점, FQDN·복수 레이블 이름·단일 레이블 이름에서 질의를 만드는 방식이 달라지고 접미사 검색 목록·기본 접미사·잘라내기·연결별 접미사가 차례로 쓰인다는 점, 긍정이든 부정이든 응답이 캐시된다는 점, 여러 어댑터에서의 질의 순서와 부정 응답에 의한 어댑터 제외, 적응형 타임아웃과 무응답 서버의 캐시에 대해.  2 3 4 5 6 7 8 9 10

  6. Microsoft Learn, VPNv2 CSP. VPN 프로필의 DomainNameInformationList가 NRPT의 규칙이라는 점, Windows DNS API를 쓰는 앱만 NRPT를 이용할 수 있고 자체 DNS 구현을 가진 앱은 우회한다는 점, 그 예가 nslookup이며 NRPT의 확인에는 반드시 Resolve-DnsName을 써야 한다는 점에 대해.  2 3 4

  7. Microsoft Learn, Microsoft Edge policy: BuiltInDnsClientEnabled. Edge가 기본적으로 내장 DNS 클라이언트를 쓴다는 점, 이 정책이 어느 DNS 서버를 쓸지에는 영향을 주지 않는다는 점, DoH의 질의는 항상 내장 확인자가 수행한다는 점에 대해.  2 3 4

  8. Microsoft Learn, Resolve-DnsName. -CacheOnly(로컬 캐시만), -DnsOnly(DNS 프로토콜만으로 LLMNR·NetBIOS를 내보내지 않음), -NoHostsFile(hosts를 건너뜀), -LlmnrOnly, -LlmnrNetbiosOnly, -LlmnrFallback, -NetbiosFallback, -Server, -Type(기본은 A_AAAA), -QuickTimeout, -TcpOnly 각 매개 변수에 대해.  2 3 4 5 6

  9. Microsoft Learn, Windows security book: Network security. Windows 11의 DNS 클라이언트가 DoH와 DoT를 지원한다는 점, 그룹 정책과 프로그램에서 DoH를 구성할 수 있다는 점, 암호화 DNS의 지원이 NRPT·시스템의 hosts 파일·어댑터나 프로필별 확인자 지정 같은 기존 DNS 구성과 통합된다는 점에 대해.  2 3

  10. Microsoft Learn, getaddrinfo function (ws2tcpip.h). NS_DNS 네임스페이스에 대해 DNS·로컬의 hosts 파일·그 밖의 구조로 이름을 주소로 변환하고 여러 네임스페이스 공급자의 응답을 집약한다는 점, 유니코드 판이 GetAddrInfoW라는 점에 대해.  2

  11. Microsoft Learn, Dns.GetHostAddresses Method. 기반이 되는 OS의 이름 확인 API(Windows에서는 getaddrinfo)로 구현되어 있다는 점, hosts 파일에 적힌 호스트는 DNS 서버에 묻지 않고 그 주소가 돌아온다는 점에 대해.  2 3

  12. Microsoft Learn, Troubleshoot Azure DNS. nslookup이 OS의 로컬 DNS 확인자 라이브러리를 쓰지 않고 로컬 DNS 캐시·hosts 파일·NRPT를 우회한다는 점, 그 층들이 관계되는 경우에는 Resolve-DnsName을 써야 한다는 점에 대해.  2 3

  13. Microsoft Learn, ipconfig. /displaydns가 hosts에서 읽어들인 항목과 최근 확인한 레코드를 모두 포함하는 DNS 클라이언트 확인자 캐시를 표시한다는 점, /flushdns가 부정 캐시 항목을 포함한 캐시를 버린다는 점, /registerdns에 의한 동적 등록에 대해.  2

  14. Microsoft Learn, Troubleshooting DNS clients. ipconfig /displaydns에서 실패하는 이름에 「Name does not exist」가 나오면 DNS 서버의 부정 응답이 클라이언트에 캐시되어 있다는 점, ipconfig /flushdns로 해소된다는 점, nslookup이 클라이언트의 DNS 캐시를 쓰지 않는다는 점에 대해. 

  15. Microsoft Learn, Windows Firewall profile doesn’t always switch to Domain when you use a third-party VPN client. Dnscache\Parameters의 MaxNegativeCacheTtl 기본값이 5초라는 점, 0으로 부정 캐시를 비활성화할 수 있다는 점에 대해. 

  16. Microsoft Learn, Clear-DnsClientCache. DNS 클라이언트 캐시의 전체 내용을 삭제하며 ipconfig /flushdns와 동등하다는 점에 대해. 

  17. Microsoft Learn, Get-DnsClientCache. 로컬 DNS 클라이언트 캐시의 내용을 가져오고 Name·Type·TimeToLive·Section 등으로 좁힐 수 있다는 점에 대해. 

  18. Microsoft Learn, How to configure a domain suffix search list on the Domain Name System clients. 도메인 접미사 검색 목록이 구성되면 그 목록만 쓰이고 기본 DNS 접미사도 연결별 접미사도 잘라내기도 쓰이지 않는다는 점에 대해. 

  19. Microsoft Learn, Get-DnsClientGlobalSetting. 인터페이스에 묶이지 않는 DNS 클라이언트의 전체 설정(UseSuffixSearchList·SuffixSearchList·UseDevolution·DevolutionLevel)을 가져오는 것에 대해. 

  20. Microsoft Learn, Get-DnsClient. 인터페이스별 ConnectionSpecificSuffix·RegisterThisConnectionsAddress·UseSuffixWhenRegistering을 가져오는 것에 대해. 

  21. Microsoft Learn, DNS client resolution timeouts. DNS 서버가 1대·2대·3대 이상일 때의 재전송 시점(시작으로부터 1·2·4·8초에 재전송하고 10초에 중단), 부정 응답으로 처리가 멈추고 무응답일 때만 다음 서버를 시도한다는 점, 4번째 이후의 서버에는 최소 4초 뒤에야 닿는다는 점에 대해.  2 3 4

  22. Microsoft Learn, Automatic interface metric. 현재의 Windows에서는 인터페이스의 우선순위가 인터페이스 메트릭으로 정해지고, Get-NetIPInterface로 메트릭을 확인·변경할 수 있다는 점에 대해. 

  23. Microsoft Learn, Get-DnsClientNrptPolicy. NRPT에 구성된 네임스페이스별 설정(DNS 클라이언트의 이름 서버, DirectAccess, DNSSEC 등)을 가져오고, -Effective로 실효 정책을, -Namespace로 특정 네임스페이스의 몫을 표시하는 것에 대해.  2

  24. IETF, RFC 6762: Multicast DNS. mDNS가 UDP 포트 5353의 멀티캐스트로 .local 이름을 동일 링크 안에서 확인하는 프로토콜이라는 점에 대해.  2 3

  25. Microsoft Learn, Microsoft Security Bulletin MS11-030. LLMNR이 TCP/UDP 5355를 쓴다는 점, 회피책으로서의 방화벽에서의 5355 차단과 그룹 정책 「멀티캐스트 이름 확인 끄기」, 그 영향으로 컴퓨터가 다른 컴퓨터에서 보이지 않게 될 수 있다는 점에 대해.  2

  26. IETF, RFC 4795: Link-Local Multicast Name Resolution (LLMNR). LLMNR의 질의가 UDP 멀티캐스트(포트 5355)로 보내지고, TCP는 잘린 응답 등의 유니캐스트 주고받기에 쓰인다는 점에 대해. 

  27. Microsoft Tech Community, Networking Blog, Aligning on mDNS: ramping down NetBIOS name resolution and LLMNR. 2022년 4월에 Microsoft가 공표한, mDNS로 정렬해 NetBIOS 이름 확인과 LLMNR을 단계적으로 축소하는 방침에 대해.  2

  28. Microsoft Learn, How to configure TCP/IP networking while NetBIOS is turned off. NetBIOS 이름 서비스가 UDP 137, 데이터그램 서비스가 UDP 138, 세션 서비스가 TCP 139를 쓴다는 점, NetBT를 비활성화하면 그것들을 수신 대기하지 않게 된다는 점에 대해. 

  29. Microsoft Learn, Windows security baseline (Azure Policy guest configuration). NetBT의 노드 유형(B-node는 브로드캐스트만, P-node는 WINS만, M-node는 브로드캐스트 뒤 WINS, H-node는 WINS 뒤 브로드캐스트), WINS가 미구성이면 B-node·구성되어 있으면 H-node가 기본이라는 점, 권장이 P-node라는 점에 대해.  2 3

  30. Microsoft Learn, Windows Internet Name Service (WINS). WINS가 NetBIOS 이름을 IP 주소에 대응시키는 레거시 서비스이며, 새로 배포하지 말고 DNS를 쓰고 이미 배포했다면 DNS로 이전해 폐지하는 것이 권장된다는 점에 대해.  2

  31. Microsoft Learn, nbtstat. /c로 NetBIOS 이름 캐시를 표시하고, /R로 캐시를 지우고 Lmhosts의 사전 태그 항목을 다시 읽어들이며, /RR로 WINS로의 등록을 해제·재등록하는 것에 대해. 

  32. Microsoft Learn, Features removed or no longer developed in Windows Server. Computer Browser 서비스가 시대에 뒤떨어지고 안전하지 않은 장비 탐색 프로토콜로서 더 이상 사용되지 않게 되었다는 점, WINS 등 레거시 이름 확인 관련 기능의 취급에 대해. 

  33. Microsoft Learn, Direct host SMB over TCP/IP. Windows Vista / Windows Server 2008 이후의 SMB 2.0.2가 TCP 445를 필요로 하고 NetBIOS 세션 전송을 쓰지 않는다는 점. 같은 자료는 그 이점으로 이름 확인을 DNS로 표준화할 수 있다는 점을 들지만, 이는 SMB의 전송 경로 이야기이며 클라이언트의 DNS 클라이언트가 단일 레이블 이름을 LLMNR이나 NetBT로 확인하는 동작을 멈추는 것은 아니다(본문 5.4절). 

  34. Microsoft Learn, Add-DnsClientDohServerAddress. DoH 서버 구성을 알려진 서버 목록에 추가하고, -DohTemplate·-AllowFallbackToUdp·-AutoUpgrade로 암호화 실패 시의 폴백과 자동 승격을 지정하는 것에 대해. 

  35. Microsoft Learn, netsh dnsclient. add/set encryption에 의한 DoH·DoT 서버의 등록(dohtemplate·dothost·autoupgrade·udpfallback), set global에 의한 doh/dot/ddr의 전체 설정, show encryption·show global·show state에 대해.  2 3 4 5

  36. Microsoft Learn, User data and privacy in Microsoft Edge: Secure DNS. 보안 DNS가 기본적으로 현재의 공급자를 쓰고 암호화 연결에 실패하면 평문으로 재시도한다는 점, 특정 공급자를 고르면 평문으로 되돌아가지 않는다는 점, 조직 관리하의 PC에서는 기본적으로 비활성이라는 점에 대해. 

  37. Microsoft Learn, Microsoft Edge policy: DnsOverHttpsMode. off·automatic·secure의 3가지 모드와, 관리 대상 장치에서 미구성이면 DoH 질의를 보내지 않는다는 점에 대해. 

  38. Microsoft Learn, Guidance for configuring IPv6 in Windows for advanced users. Windows Vista 이후가 RFC 3484의 접두사 테이블로 쓸 주소를 정하고 기본적으로 IPv6 글로벌 유니캐스트를 IPv4보다 우선한다는 점, IPv6의 비활성화를 권장하지 않고 DisabledComponents의 0x20으로 「IPv4를 우선」을 써야 한다는 점에 대해.  2 3

  39. IETF, RFC 3484: Default Address Selection for Internet Protocol version 6 (IPv6). 대상 주소의 선택 규칙의 제1칙이 「쓸 수 없는 대상을 피한다」이며, 원본 주소나 경로가 없는 대상을 먼저 빼고 나서 접두사 정책의 우선도로 후보를 늘어놓는 것에 대해. 

  40. Microsoft Learn, Configure DNSSEC rules using the Name Resolution Policy Table. NRPT의 네임스페이스 종류(접미사·접두사·FQDN·서브넷·Any)와 접미사가 자식 도메인을 포함하는 끝 일치라는 점, 더 구체적인 규칙이 일반적인 규칙보다 우선된다는 점에 대해. 

  41. Microsoft Learn, Troubleshooting Domain Name System (DNS) issues: Data collection. 클라이언트와 서버에서 netsh trace start capture=yes를 시작하고 ipconfig /flushdns로 캐시를 버린 뒤 재현하고 netsh trace stop으로 멈추는 데이터 수집 절차에 대해. 

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.

Windows 앱 개발

목적지의 지정 방법·타임아웃·이름 확인 결과의 로그를 갖춘, 이름 확인 문제에 강한 업무 앱의 구현은 Windows 앱 개발의 범위이기 때문입니다.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

hosts 파일을 고쳤는데도 반영되지 않습니다. 왜 그렇습니까?
Windows의 hosts 파일 내용은 DNS 클라이언트 서비스가 시작될 때 캐시로 읽어들여지고, 이름 확인은 캐시→hosts→DNS 서버의 순서로 진행됩니다. 반영되지 않을 때는 먼저 ipconfig /displaydns로 그 이름의 항목을 확인하고, 오래된 응답이 남아 있으면 ipconfig /flushdns로 버리십시오. 다음으로, 조사에 쓰는 도구가 Windows의 확인자를 거치는지 의심합니다. nslookup은 OS의 확인자를 쓰지 않고 캐시도 hosts도 NRPT도 그냥 지나쳐 DNS 서버에 직접 질의하므로 hosts의 내용은 전혀 반영되지 않습니다. hosts를 포함한 실제 확인 결과를 보려면 Resolve-DnsName이나 ping을 쓰십시오. 그래도 반영되지 않는다면 브라우저처럼 자체 확인자나 DoH를 가진 앱인지 확인합니다.
브라우저에서는 사이트가 열리는데 업무 앱만 이름 확인에 실패합니다.
브라우저와 앱이 서로 다른 경로로 이름을 조회하고 있을 가능성이 높은 상태입니다. Microsoft Edge는 기본적으로 OS의 DNS 클라이언트가 아니라 내장 DNS 클라이언트로 DNS 서버와 통신하며, 보안 DNS(DoH)에서 다른 공급자를 고르면 외부 확인자에 질의합니다. 한편 .NET의 Dns.GetHostAddresses나 목적지에 직접 연결하는 HttpClient는 OS의 getaddrinfo를 거치므로 hosts·DNS 캐시·NRPT·접미사 검색 목록의 영향을 모두 받습니다(HTTP 프록시를 경유하는 요청에서는 목적지의 이름이 프록시 쪽에서 확인됩니다). 양쪽이 다른 답을 돌려준다면, 어느 경로가 어느 DNS 서버에 무엇을 물었는지를 Resolve-DnsName과 패킷 캡처로 맞춰 보는 것이 가장 빠릅니다.
설정은 같을 텐데 일부 PC만 사내 서버에 연결되지 않습니다. 무엇을 비교하면 됩니까?
이름의 형태와, 그 PC가 어느 층에서 답을 얻고 있는지를 비교합니다. 단일 레이블 이름(server01처럼 점을 포함하지 않는 이름)은 PC의 DNS 접미사 검색 목록이나 연결별 접미사로 보완되어 DNS로 보내지고, 기본적으로는 그와 병행해 LLMNR이나 NetBIOS 브로드캐스트 같은 동일 서브넷 한정 수단에도 질의됩니다(DNS 실패 후에 차례로 시도되는 것은 최적화를 비활성화했을 때뿐입니다. WINS가 구성되어 있으면 NetBIOS는 유니캐스트로 서브넷을 넘을 수 있습니다). 도메인에 가입한 PC는 접미사로 FQDN이 보완되어 확인할 수 있어도, VPN 경유나 다른 서브넷의 PC, LLMNR과 NetBIOS를 비활성화한 PC에서는 같은 이름을 확인할 수 없습니다. 연결되는 PC와 연결되지 않는 PC 양쪽에서 Get-DnsClientServerAddress·Get-DnsClientGlobalSetting·Get-DnsClient·Get-DnsClientNrptPolicy -Effective의 출력을 채취해 차이를 보는 것이 확실합니다. 근본 대책은 설정 파일이나 바로 가기의 목적지를 FQDN으로 만드는 것입니다.
이름 확인이 실패하는 것이 아니라, 몇 초 기다린 뒤에야 겨우 연결됩니다. 원인은 무엇입니까?
DNS 클라이언트의 타임아웃과 재시도 구조가 겉으로 드러난 상태입니다. Windows는 응답이 없는 DNS 서버에 대해 시작 시점부터 1초·2초·4초·8초에 재전송하고 10초에 중단합니다. 여러 DNS 서버를 설정해 두어도, 응답하는 서버가 목록의 4번째 이후에 있으면 최소 4초를 기다린 뒤에야 그 서버에 질의합니다. 또한 긴 DNS 접미사 검색 목록은 단일 레이블 이름을 확인할 때 접미사를 차례로 시도하는 만큼 지연을 쌓아 올립니다. Measure-Command로 Resolve-DnsName의 소요 시간을 재고, Wireshark에서 dns.qry.name 필터를 걸어 어느 서버로의 질의가 무응답인지 보십시오.
보안 대책으로 LLMNR과 NetBIOS를 비활성화했더니 일부 장비에 이름으로 연결되지 않게 되었습니다.
예상되는 부작용입니다. LLMNR과 NetBIOS over TCP/IP는 DNS에 등록되어 있지 않은 장비의 단일 레이블 이름을 동일 서브넷 안에서 확인하는 2차적인 수단이며, 비활성화하면 그 경로가 사라집니다. Microsoft 자신도 2022년에 mDNS로 정렬해 NetBIOS 이름 확인과 LLMNR을 단계적으로 축소하는 방침을 밝혔으므로, 비활성화하는 방향 자체는 옳은 판단입니다. 대책은 이름 확인을 DNS로 모으는 것으로, 장비의 A 레코드를 사내 DNS에 등록하거나 DHCP에 의한 동적 등록을 활성화하고, 앱과 공유의 목적지를 FQDN으로 고쳐 씁니다. mDNS를 지원하는 장비라면 .local 이름으로 확인할 수 있지만, 이쪽도 멀티캐스트가 닿는 범위로 한정됩니다.
Windows 11의 DoH(DNS over HTTPS)를 활성화하면 사내의 이름 확인은 어떻게 됩니까?
DoH는 DNS 클라이언트가 설정된 DNS 서버로 질의할 때의 전송 경로를 HTTPS로 바꾸는 기능이며, hosts·캐시·NRPT 같은 기존 순서는 그대로 살아 있습니다. DoH를 쓸 수 있는 것은, DDR(Discovery of Designated Resolvers)을 활성화하지 않았다면 그 서버가 알려진 DoH 서버 목록에 실려 있는 경우뿐이며, 사내 DNS를 쓰려면 관리자가 Add-DnsClientDohServerAddress로 등록해야 합니다. 그룹 정책 「DNS over HTTPS(DoH) 이름 확인 구성」에서 「DoH를 요구」로 하면 DoH를 지원하지 않는 서버에서는 이름 확인 자체가 실패합니다. Microsoft는 도메인에 가입한 PC에서 이 설정을 활성화하지 말라고 명기하고 있습니다. Active Directory가 의존하는 Windows Server 표준 DNS 서버 서비스가 DoH 질의를 지원하지 않기 때문입니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기