Windows で  "nslookup 使うな おじさん" 爆誕

この記事は  [Microsoft Azure Tech Advent Calendar 2024](https://qiita.com/advent-calendar/2024/microsoft-azure-tech) の **8 日目の記事** です。
かつ、
こちらの記事は､[Azure PoC部 Advent Calendar 2024](https://adventar.org/calendars/10622)の**11日目の記事**でもあります。

---
こんにちは、アーキテクトのやまぱんです。  

補足コメントや質問、<font color="red">**いいね、拡散**</font>、是非お願いします🥺！  
間違ってたら<font color="red">**優しく**</font>教えてください！

---
突然ですが、私は nslookup 使うなおじさんになりました。
結論からいうと、「`nslookup` の代わりに、PowerShell の `Resolve-DnsName` をつかいましょう！」です。
もちろん、この記事の内容を理解した上で ```nslookup``` を使うのはよいですが、実務では ```Resolve-DnsName``` の方がいいことの方がいいじゃないかと思います。

## 「Windows で nslookup 使うの、もうやめませんか？」

DNS の名前解決をテストしたりトラブルシューティングするときに、`nslookup` を使う人が多いかと思います。
でも、Windows ユーザーには**強く言いたい、「nslookup 使うな」** と。  

**今どき Windows で nslookup を使うのは非推奨！PowerShell の Resolve-DnsName に切り替えよう！**  

ちなみに検索してみると以下のように X でも嘆いている人がいました。

> LAN内の名称解決がクライアント側できちんとしてるかのチェックにnslookup使うとmDNS無視するのでPowerShellでResolve-DNSNameを使おう！
結構アホな齟齬あるからな！
[https://x.com/ayutimali/status/1748124909824541141](https://x.com/ayutimali/status/1748124909824541141)



この記事では、`nslookup` がなぜ Windows では推奨されないのか、そして `Resolve-DnsName` について簡単に解説します。

本件に関連して、ここに記載している内容以外にもあるかと思いますが、それはきっと公式のサポートブログなどから記事が出ることでしょう…。

+ `nslookup` と `Resolve-DnsName` の実行例
![nslookup と Resolve-DnsName の実行例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/fd688597-3ec1-9393-daf3-dfd6785422aa.png)


---

## DNS リゾルバサービスとは
今回のお話をする前に前提としてお話ししたい、WindowsのDNSリゾルバサービスです。
Windows には「DNS リゾルバサービス」という仕組みが備わっています。  
これは、DNS クエリを効率よく処理し、キャッシュやサフィックスリストを活用して名前解決を行うサービスです。ほとんどの Windows アプリケーション（ブラウザ、メールクライアントなど）は、この DNS リゾルバサービスを使用して名前解決を行います。

+ Microsoft-Windows-DNS-Client - MS Learn

https://learn.microsoft.com/ja-jp/windows-hardware/customize/desktop/unattend/microsoft-windows-dns-client?utm_source=chatgpt.com


+ DNS リゾルバー - MS Learn

https://learn.microsoft.com/ja-jp/windows/win32/dns/dns-resolvers?utm_source=chatgpt.com

### **リゾルバサービスの主な特徴**
1. **キャッシュの活用**
   - 過去に解決した名前をキャッシュとして保存し、再利用することでクエリの速度を向上
2. **サフィックスの自動補完**
   - ホスト名に DNS サフィックスを追加して、完全修飾ドメイン名（FQDN）に変換
3. **複数 DNS サーバーの自動フォールバック**
   - プライマリ DNS が応答しない場合、セカンダリ DNS に切り替え

+ 参考 ```ipconfig /flushdns``` によるキャッシュのクリア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/c54a1dd5-9454-b0b8-1924-f81d33f47d31.png)


### **Windows アプリケーションの挙動**
- Windows アプリケーションは DNS リゾルバサービスを利用するため、**`Resolve-DnsName` の挙動に近い**結果を得る (代替 DNS にフォールバック参照すること、Hostsファイルを参照する等が可能)
- 一方、`nslookup` は **DNS リゾルバサービスを使用しないため、アプリケーションの挙動と異なる**場合がある

---

## Resolve-DnsName のここがすごい！
+ Resolve-DnsName - MS Learn

https://learn.microsoft.com/ja-jp/powershell/module/dnsclient/resolve-dnsname?view=windowsserver2022-ps

> The Resolve-DnsName cmdlet performs a DNS query for the specified name. This cmdlet is functionally similar to the nslookup tool which allows users to query for names.
<抄訳>
Resolve-DnsName コマンドレットは、指定された名前の DNS クエリを実行します。このコマンドレットは、ユーザーが名前を問い合わせることができる nslookup ツールに機能的に似ています。

`Resolve-DnsName` は、PowerShell で DNS クエリを行うためのコマンドで、現代的な機能を備えています。`Resolve-DnsName` は、Windows の DNS クライアント (リゾルバサービス) を直接利用し、ローカルキャッシュやmDNSを含む**すべての名前解決プロセス**を利用します。

### **Windows アプリケーションに近い挙動**
- `Resolve-DnsName` は DNS リゾルバサービスを使用するため、Windows アプリケーションの名前解決結果とほぼ同じ挙動を再現する

### **モダンな設計**
- **オブジェクト形式で結果を返す**ため、スクリプト処理が容易

### **DNSSEC や EDNS に対応**
- DNSSEC を有効にしたクエリが可能。
> Resolve-DnsName -Name example.com -DnsSecOk

### **複数 DNS サーバーの順次利用**
- 複数の DNS サーバーを設定している場合、自動でフォールバックを試行
これが結構大きいポイントかなと個人的に思います。

### mDNS の対応
```Resolve-DnsName``` は、ローカルネットワーク内のmDNS（通常、.local ドメイン）を解決できます。例えば、プリンターや IoT デバイスなどの mDNS 対応デバイスの名前を確認する場合に有効です。

一方、 ```nslookup``` は、名前解決を行う際に、通常の ユニキャスト DNS（外部の DNS サーバーを使った名前解決）を使います。そのため、***mDNS（Multicast DNS）に基づく名前解決には対応しておらず***、```.local``` ドメインの名前解決を行った場合でも失敗することがある

:::note info
+ mDNS とその名前解決
mDNS（Multicast DNS）は、ローカルネットワーク内で名前解決を行うためのプロトコルですが、一般的なDNSクエリツール（例: nslookup）では mDNS の名前解決をサポートしていません。そのため、ローカルネットワーク内のmDNSを使った名前解決を正しく確認するには、mDNS に対応したツールやコマンドを使用する必要があります。
:::

### **キャッシュ無視や特定サーバーへの問い合わせ**
- クライアントキャッシュを無視して最新情報を取得 (**nslookupでは不可能**)
> Resolve-DnsName -Name example.com -NoCache

- もちろん、特定の DNS サーバーにクエリを送ることも可能 (nslookupでも可能)
> Resolve-DnsName -Name example.com -Server 8.8.8.8

- hosts ファイルの参照
Resolve-DnsName では hosts ファイルも参照して名前解決を行う。(**nslookupでは不可能**)

---

## 複数 DNS サーバー指定時の挙動
複数の DNS サーバーを指定している場合の挙動も異なります。

### **nslookup の場合**
- **最初の DNS サーバーしか使わない**
  - プライマリ サーバーが応答しないと、そのまま失敗します
  - hosts ファイルを参照しない

### **Resolve-DnsName の場合**
- **自動フォールバック**
  - 複数の DNS サーバーが設定されている場合、プライマリが失敗するとセカンダリに切り替え
  - hosts ファイルを参照する

## nslookup と Resolve-DnsName の動作の差異を実際に検証

実際に nslookup と Resolve-DnsName の動作の差異を検証してみます✨

:::note info
+ hosts ファイルの設定は以下
　www.yahoo.co.jp に www.nii.ac.jp の IP アドレスを設定
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/8d86763d-7dd0-87e4-b333-6728732baa04.png)

+ ブラウザの挙動では hosts ファイルの情報参照するので www.yahoo.co.jp にアクセスしても www.nii.ac.jp を確認する動作となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/3626801f-2fd4-b975-ea97-cbe566e613bc.png)

+ Resolve-DnsName と nslookup による名前解決の比較
 Resolve-DnsName ではブラウザと同じ挙動をしていることがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/6ecf309a-b6ac-9153-b47e-3e7a6b664ce5.png)
:::

---

## **Resolve-DnsName を推奨する理由**

### **1. Outdated なツールとしての nslookup**
- `nslookup` は古い設計のツールであり、DNS クエリの機能が限定的
- 現代的なプロトコル（例: **DNSSEC** や **EDNS**、 **mDNS**）には対応していないため、最新のセキュリティや拡張機能を必要とするシナリオでは十分ではない

### **2. 実際のアプリケーション挙動を再現できない**
- `nslookup` は **DNS リゾルバ サービス**を使用せず、直接 DNS サーバーにクエリを送信します
  - そのため、Windows アプリケーションの名前解決挙動とは異なる
  - 例: プライマリ DNS が応答しない場合、セカンダリ DNS にフォールバックする動作を再現できない
- Windows 環境のネットワーク診断やアプリケーション挙動の再現には不向き

### **3. 固定的な結果形式**
- `nslookup` の結果はテキスト形式に固定されており、スクリプト処理や詳細なトラブルシューティングには不便
  - エラー情報も簡略化されており、詳細な解析や自動化に制約があり
- これに対し、`Resolve-DnsName` はオブジェクト形式で結果を返すため、PowerShell スクリプト内での柔軟な処理が可能

### **4. Resolve-DnsName の優位性**
- **最新プロトコル対応**: DNSSEC や EDNS などの現代的な DNS プロトコルをサポート
- **Windows リゾルバ サービスを使用**: Windows アプリケーションの名前解決に近い挙動を再現可能
- **オブジェクト形式の出力**: スクリプト処理や詳細解析に適した形式で結果を返すため、診断や自動化が容易

### **結論**
`nslookup` は依然として利用可能ですが、最新のプロトコル対応、Windows アプリケーションの挙動再現、スクリプト処理の柔軟性を求める場合には、`Resolve-DnsName` の使用が推奨されます。

---

## エイリアス について　- ```Set-Alias``` コマンドの紹介　
残念ながら、```Resolve-DnsName``` は ```Test-NetConnection``` における ```tnc``` のような便利な短いエイリアスはないです⚡
しかし！以下のようにして自分なりのエイリアス、オレオレエイリアスを設定することができます。
以下の例では ```rdn``` という エイリアスを設定しています。
めっちゃ短くなって便利ですね(#^.^#)❣

```powershell:
Set-Alias -Name rdn -Value Resolve-DnsName
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/cd261d01-e4f9-31d6-236a-99b6aafd9247.png)

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/set-alias?view=powershell-7.4


:::note info
**セッションを超えてエイリアスを永続保持する方法**
エイリアスを永続的に保持するには、PowerShellのプロファイルファイルに設定を保存する必要があります。
しかし、PowerShellのセッションを終了するとエイリアスは消えてしまうのがデフォルトの動作です。これは、Set-Alias が一時的なエイリアスをセッション中にのみ設定するためです。

+ 手順 1: プロファイルファイルを確認
次のコマンドで、現在使用されているプロファイルファイルのパスを確認します： 
```PowerShell:PowerShell
$PROFILE
```
出力例
> C:\Users\ユーザー名\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

+ 手順 2: プロファイルファイルにエイリアスを追記
次のコマンドで、現在使用されているプロファイルファイルのパスを確認します

プロファイルファイルを編集するために以下を実行します
```PowerShell:PowerShell
notepad $PROFILE ##ファイルが存在しない場合は新規作成します。
```

次のエイリアス設定をファイルに追記します
```PowerShell:PowerShell
Set-Alias -Name rdn -Value Resolve-DnsName
```
ファイルを保存して閉じます。

+ 手順 3: プロファイルを適用
PowerShellを再起動するか、次のコマンドで設定を適用します。
```PowerShell:PowerShell
. $PROFILE
```

+ 確認
PowerShellを再起動し、次のコマンドでエイリアスが適用されているか確認します。

```PowerShell:PowerShell
Get-Alias rdn
```

出力例:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/14672f51-d9a3-19d4-1368-3b4fac680dd9.png)


:::

## まとめ

**Windows で nslookup を使うのはもう古い！**  
`Resolve-DnsName` は、DNSSEC や EDNS の対応、詳細な結果の提供、自動フォールバックなど、現代的な運用に必須の機能を備えています。さらに、DNS リゾルバサービスを使用しているため、**Windows アプリケーションの挙動に近い結果(代替 DNS へのフォールバックなど)を得ることができます**。

ぜひこの記事を参考に、`Resolve-DnsName` を使いこなしてみてください！  

----
もしよければ、<font color="red">コメントや質問、拡散</font>よろしくお願いします！🙏