C Sharpとネットワーク - DNS
概要
DNSレコードの確認
DnsClient.NETライブラリとは
DnsClient.NETライブラリは、.NET環境で使用できる高機能なDNS (Domain Name System) クライアントライブラリである。
DnsClient.NETライブラリの特徴および用途を以下に示す。
- 主な機能
- DNSクエリの実行 (A、AAAA、CNAME、MX、NS、PTR、SOA、SRV、TXTレコード等)
- 例: DNSレコードの存在を確認する場合
- 非同期DNSルックアップ
- DNSキャッシュのサポート
- DNSSEC (DNS Security Extensions) のサポート
- IPv4およびIPv6のサポート
- DNSクエリの実行 (A、AAAA、CNAME、MX、NS、PTR、SOA、SRV、TXTレコード等)
- 使用目的
- ドメイン名の解決
- メールサーバーの検索 (MXレコード)
- サービスディスカバリ (SRVレコード)
- リバースDNSルックアップ
- カスタムDNSサーバの使用
- メリット
- パフォーマンスの最適化
- システムのDNSリゾルバよりも高速な場合がある。
- 細かな制御
- タイムアウト、リトライ、DNSサーバの選択などを詳細に設定できる。
- クロスプラットフォーム
- Windows、Linux、MacOSで動作可能。
- 豊富な機能
- 標準的なDNS操作に加えて、高度な機能も提供している。
- パフォーマンスの最適化
- 一般的な使用シナリオ
- マイクロサービスアーキテクチャでのサービスディスカバリ
- ネットワーク診断ツール
- メールシステムの実装
- カスタムネットワークアプリケーション
DnsClient.NETライブラリのインストール
Riderからインストールする場合
Riderを起動して、対象のプロジェクトを開く。
[ツール]メニューバー - [NuGet] - [パッケージマネージャーの管理]を選択して、NuGetパッケージマネージャーを開く。
または、ソリューションエクスプローラでプロジェクトを右クリックして、[NuGetパッケージの管理]を選択して、NuGetパッケージマネージャーを開く。
次に、DnsClient.NETライブラリを検索する。
検索バーにて、DnsClient.NETと入力する。
DnsClient.NETライブラリのインストールする。
検索結果からDnsClient.NETライブラリを選択して、[インストール]ボタンを押下する。
インストールが完了した後、[閉じる]ボタンを押下してNuGetパッケージマネージャーを閉じる。
.NET CLIからインストールする場合
プロジェクトのディレクトリに移動して、dotnetコマンドを実行する。
# 最新の安定版のDnsClient.NETライブラリをインストールする場合 dotnet add package DnsClient.NET # 特定のバージョンを指定する場合 # 例: DnsClient.NET 1.7.0ライブラリをインストール dotnet add package DnsClient.NET --version 1.7.0
ライブラリを追加した後、依存関係を復元する。
dotnet restore
DNSレコードタイプの確認
以下の例では、duckduckgo.comから複数のDNSレコードタイプを取得および表示している。
- LookupClientクラスのインスタンスを生成する。
- 取得するレコードタイプの配列を定義する。
- 各レコードタイプに対して、DNSクエリを送信する。
- 結果を取得して、レコードタイプに応じて表示する。
※注意
PTRレコードの逆引きはIPアドレスに対して行うものであることに注意する。
IPアドレスを逆にした形式 (例: 4.4.8.8.in-addr.arpa) を使用する。
SRVレコードは特定のサービスに対して使用されるため、適切なサービス名とプロトコルを指定する必要がある。
using System;
using System.Threading.Tasks;
using DnsClient;
class Program
{
public static async Task Main(string[] args)
{
var lookup = new LookupClient();
var domain = "duckduckgo.com";
var recordTypes = new[] {
QueryType.A, QueryType.AAAA, QueryType.CNAME,
QueryType.MX, QueryType.NS, QueryType.PTR,
QueryType.SOA, QueryType.SRV, QueryType.TXT
};
foreach (var recordType in recordTypes) {
Console.WriteLine($"--- {recordType} Records for {domain} ---");
var result = await lookup.QueryAsync(domain, recordType);
if (result.Answers.Count == 0) {
Console.WriteLine($"No {recordType} records found.");
continue;
}
foreach (var record in result.Answers) {
switch (record)
{
case ARecord a:
Console.WriteLine($"A Record: {a.Address}");
break;
case AaaaRecord aaaa:
Console.WriteLine($"AAAA Record: {aaaa.Address}");
break;
case CNameRecord cname:
Console.WriteLine($"CNAME Record: {cname.CanonicalName}");
break;
case MxRecord mx:
Console.WriteLine($"MX Record: {mx.Exchange} (Preference: {mx.Preference})");
break;
case NsRecord ns:
Console.WriteLine($"NS Record: {ns.NSDName}");
break;
case PtrRecord ptr:
Console.WriteLine($"PTR Record: {ptr.PtrDomainName}");
break;
case SoaRecord soa:
Console.WriteLine($"SOA Record: Primary NS: {soa.MName}, Responsible: {soa.RName}");
break;
case SrvRecord srv:
Console.WriteLine($"SRV Record: Target: {srv.Target}, Port: {srv.Port}, Priority: {srv.Priority}, Weight: {srv.Weight}");
break;
case TxtRecord txt:
Console.WriteLine($"TXT Record: {string.Join(", ", txt.Text)}");
break;
default:
Console.WriteLine($"Unknown Record Type: {record}");
break;
}
}
}
}
}
DNSサーバの確認
以下の例では、対象のDNSのリストが記述されたファイルを順番に読み込み、存在しない場合は別ファイルに書き込んでいる。
LookupClientクラスのQueryメソッドを使用して、対象のドメインとレコードの種類 (AレコードおよびNSレコード) を指定する。
取得結果が無い場合は、存在しないと判断する。
MXレコードを対象としているが、QueryType (Enum) でレコードの種類 (AレコードおよびNSレコード) が定義されているため、
様々な種類のレコードを対象にすることができる。
using System;
using System.IO;
using DnsClient;
namespace DNSRecordCheck;
class Program
{
public static async void Main(string[] args)
{
// LookupClientクラスのインスタンスを生成
var lookupClient = new LookupClient();
using (var sreader = new StreamReader(@"C:\domains.txt")) {
while (!sreader.EndOfStream) {
// 調査対象のリストから1行ずつ読み込み
var line = await sreader.ReadLineAsync();
using (var swriter = File.AppendText(@"C:\ignores.txt")) {
// 読み込んだDNSを問い合わせる(QueryType.MX : MXレコードを対象とする)
var result = lookupClient.Query(line, QueryType.MX);
if (result.Answers.Count == 0) {
// 結果が0件の場合は存在しないと判断
// 別ファイル (ignores.txt) に書き込む
swriter.WriteLine(line);
}
}
}
}
}
}