Node.js dns モジュール

Java FileNode.js 組み込みモジュール


Node.js のdnsモジュールは、ドメインネームシステム(DNS)クエリのためのコアモジュールです。DNS(Domain Name System)は、人間が読み取れるドメイン名(例:www.example.com)を機械が読み取れるIPアドレス(例:192.0.2.1)に変換するシステムです。

なぜ dns モジュールが必要か

ネットワーク通信では、コンピューターは実際にはIPアドレスによって互いを認識していますが、人々は数字のIPアドレスよりもドメイン名を覚えやすいです。dnsモジュールは、Node.jsアプリケーション内でドメイン名解決を行う機能を提供し、開発者は以下のことができます:

  • ドメイン名をIPアドレスに解決する
  • IPアドレスをドメイン名に逆引き解決する
  • DNSレコード(MX、TXT、SRVなど)を問い合わせる

dns モジュールの基本的な使い方

dns モジュールの導入

使用するにはdnsモジュールを最初に導入する必要があります:

const dns = require('dns');

基本的な名前解決方法

dnsモジュールは複数の名前解決メソッドを提供しており、最も一般的なのはlookupとresolve。

dns.lookup()

dns.lookup()は最も簡単なドメイン名解決メソッドであり、オペレーティングシステムが提供する機能を使用してDNSクエリを実行します:

例

dns.lookup('example.com', (err, address, family) => {
  if (err) throw err;
  console.log(`アドレス: ${address},IPバージョン: IPv${family}`);
});

dns.resolve()

dns.resolve()より細かい制御を提供し、特定の種類のDNSレコードを問い合わせることができます:

例

dns.resolve('example.com', 'A', (err, addresses) => {
  if (err) throw err;
  console.log(`Aレコード: ${JSON.stringify(addresses)}`);
});

dns モジュールの主要メソッド

正引き

正引きは、ドメイン名をIPアドレスに解決するプロセスです:

例

dns.resolve4('google.com', (err, addresses) => {
  if (err) throw err;
  console.log(`IPv4アドレス: ${addresses}`);
});

dns.resolve6('google.com', (err, addresses) => {
  if (err) throw err;
  console.log(`IPv6アドレス: ${addresses}`);
});

逆引き

逆引きは、IPアドレスをドメイン名に解決するプロセスです:

例

dns.reverse('8.8.8.8', (err, hostnames) => {
  if (err) throw err;
  console.log(`逆引き結果: ${hostnames}`);
});

その他のDNSレコードの問い合わせ

dnsモジュールは他の種類のDNSレコードの問い合わせもサポートしています:

例

// MXレコード(メール交換レコード)
dns.resolveMx('google.com', (err, addresses) => {
  if (err) throw err;
  console.log(`MXレコード: ${JSON.stringify(addresses)}`);
});

// TXTレコード(テキストレコード)
dns.resolveTxt('google.com', (err, records) => {
  if (err) throw err;
  console.log(`TXTレコード: ${JSON.stringify(records)}`);
});

同期と非同期メソッド

非同期メソッド

デフォルトでは、dnsモジュールのメソッドは非同期であり、コールバック関数を使用して結果を処理します:

例

dns.lookup('nodejs.org', (err, address, family) => {
  console.log('非同期結果:', address);
});

Promise バージョン

Node.js v10.6.0 以降、dnsモジュールのメソッドはPromiseベースのバージョンも提供しています:

例

const { promises: dnsPromises } = require('dns');

async function lookupExample() {
  try {
    const result = await dnsPromises.lookup('nodejs.org');
    console.log('Promise結果:', result.address);
  } catch (err) {
    console.error(err);
  }
}

lookupExample();

エラー処理

DNSクエリは失敗する可能性があるため、エラーを適切に処理することが非常に重要です:

例

dns.lookup('nonexistent.example.com', (err, address) => {
  if (err) {
    if (err.code === 'ENOTFOUND') {
      console.log('ドメイン名が存在しません');
    } else {
      console.log('不明なエラー:', err);
    }
    return;
  }
  console.log('アドレス:', address);
});

一般的なDNSエラーコードは次のとおりです:

  • ENOTFOUND: ドメイン名が存在しません
  • ESERVFAIL: DNSサーバーが失敗を返しました
  • ETIMEOUT: DNSクエリがタイムアウトしました

実際の応用例

ドメイン名が解決可能かどうかを確認する

例

function isDomainResolvable(domain) {
  return new Promise((resolve) => {
    dns.lookup(domain, (err) => {
      resolve(!err);
    });
  });
}

isDomainResolvable('google.com').then(result => {
  console.log('ドメイン名は解決可能:', result);
});

ドメイン名の一括解決

例

const domains = ['google.com', 'facebook.com', 'twitter.com'];

Promise.all(domains.map(domain => dnsPromises.lookup(domain)))
  .then(results => {
    results.forEach((result, index) => {
      console.log(`${domains[index]} => ${result.address}`);
    });
  })
  .catch(err => {
    console.error('解決失敗:', err);
  });

パフォーマンスの考慮事項

DNSクエリはI/O操作であり、アプリケーションのパフォーマンスに影響を与える可能性があります:

  1. 結果のキャッシュ:頻繁に問い合わせるドメイン名については、アプリケーション層で結果をキャッシュすることを検討してください
  2. 並行性の制限:同時に大量のDNSクエリを開始しないようにする
  3. タイムアウト設定:DNSクエリに適切なタイムアウト時間を設定する

例

const cache = new Map();

async function cachedLookup(domain) {
  if (cache.has(domain)) {
    return cache.get(domain);
  }
 
  const result = await dnsPromises.lookup(domain);
  cache.set(domain, result);
  return result;
}


メソッド

メソッド説明例
dns.lookup(hostname[, options], callback)ホスト名を最初の IPv4 または IPv6 アドレスに解決します。オプションのパラメータoptionsは解決方法を指定するために使用され、例えばfamily(4または6)。dns.lookup('example.com', (err, address) => {});
dns.resolve(hostname[, rrtype], callback)指定したレコードタイプの DNS レコードを問い合わせます。デフォルトでは A レコードを返します。サポートされるタイプは A、AAAA、MX、TXT などです。dns.resolve('example.com', 'MX', (err, addresses) => {});
dns.resolve4(hostname, callback)ホスト名の IPv4 アドレスを問い合わせます。dns.resolve4('example.com', (err, addresses) => {});
dns.resolve6(hostname, callback)ホスト名の IPv6 アドレスを問い合わせます。dns.resolve6('example.com', (err, addresses) => {});
dns.resolveMx(hostname, callback)ホスト名の MX(メール交換)レコードを問い合わせます。dns.resolveMx('example.com', (err, addresses) => {});
dns.resolveTxt(hostname, callback)ホスト名の TXT(テキスト)レコードを問い合わせます。dns.resolveTxt('example.com', (err, records) => {});
dns.reverse(ip, callback)IP アドレスをホスト名に解決します。dns.reverse('8.8.8.8', (err, hostnames) => {});
dns.getServers()現在の DNS サーバーの配列を返します。console.log(dns.getServers());
dns.setServers(servers)カスタム DNS サーバーの配列を設定します。dns.setServers(['8.8.8.8', '8.8.4.4']);

rrtypes

以下は dns.resolve() メソッドで有効な rrtypes 値です:

  • 'A'IPV4 アドレス、デフォルト
  • 'AAAA'IPV6 アドレス
  • 'MX'メール交換レコード
  • 'TXT'text レコード
  • 'SRV'SRV レコード
  • 'PTR'IP 逆引きに使用
  • 'NS'ネームサーバーレコード
  • 'CNAME'エイリアスレコード
  • 'SOA'権威レコードの初期値

エラーコード

DNS クエリのたびに以下のエラーコードが返される可能性があります:

  • dns.NODATA: データなしの応答。
  • dns.FORMERR: クエリ形式が正しくありません。
  • dns.SERVFAIL: 一般的な失敗。
  • dns.NOTFOUND: ドメイン名が見つかりません。
  • dns.NOTIMP: 要求された操作は実装されていません。
  • dns.REFUSED: クエリが拒否されました。
  • dns.BADQUERY: クエリ形式が正しくありません。
  • dns.BADNAME: ドメイン名の形式が正しくありません。
  • dns.BADFAMILY: アドレスプロトコルがサポートされていません。
  • dns.BADRESP: 応答形式が正しくありません。
  • dns.CONNREFUSED: DNS サーバーに接続できません。
  • dns.TIMEOUT: DNS サーバーへの接続がタイムアウトしました。
  • dns.EOF: ファイルの終端。
  • dns.FILE: ファイル読み取りエラー。
  • dns.NOMEM: メモリ不足。
  • dns.DESTRUCTION: チャネルが破棄されました。
  • dns.BADSTR: 文字列の形式が正しくありません。
  • dns.BADFLAGS: 無効な識別子。
  • dns.NONAME: 指定されたホストは数値ではありません。
  • dns.BADHINTS: 無効な HINTS 識別子。
  • dns.NOTINITIALIZED: c-ares ライブラリがまだ初期化されていません。
  • dns.LOADIPHLPAPI: iphlpapi.dll の読み込みエラー。
  • dns.ADDRGETNETWORKPARAMS: GetNetworkParams 関数が見つかりません。
  • dns.CANCELLED: DNS クエリをキャンセルしました。

例

以下は、dns モジュールの一般的なメソッドの例で、ホストの IP アドレスを問い合わせたり、DNS レコードを取得する方法を示しています。

1. dns.lookup() を使用して IP アドレスを取得する

例

const dns = require('dns');

// ドメイン名の IPv4 アドレスを検索する
dns.lookup('example.com', (err, address, family) => {
  if (err) throw err;
  console.log(`IP アドレス: ${address},アドレスファミリー: IPv${family}`);
});

dns.lookup() は簡素化されたインターフェースであり、指定された hostname で最初の IPv4 または IPv6 アドレスを検索します。

2. dns.resolve() を使用してさまざまな種類の DNS レコードを問い合わせる

例

const dns = require('dns');

// MX レコードを問い合わせる
dns.resolve('example.com', 'MX', (err, addresses) => {
  if (err) throw err;
  console.log('MX レコード:', addresses);
});

// TXT レコードを問い合わせる
dns.resolve('example.com', 'TXT', (err, records) => {
  if (err) throw err;
  console.log('TXT レコード:', records);
});

dns.resolve() を使用すると、レコードタイプ(MX、TXT など)を指定して、さまざまな DNS レコードを照会できます。

3. dns.reverse() を使用した逆 DNS クエリ

例

const dns = require('dns');

// IP アドレスをホスト名に逆引きします
dns.reverse('8.8.8.8', (err, hostnames) => {
  if (err) throw err;
  console.log(`8.8.8.8 のホスト名: ${hostnames}`);
});

逆引きは IP アドレスをドメイン名に解決します。これは、ドメイン名と IP アドレスの対応関係を確認するためによく使用されます。

4. DNS サーバーの取得と設定

例

const dns = require('dns');

// 現在の DNS サーバーのリストを取得
console.log(現在の DNS サーバー:, dns.getServers());

// カスタム DNS サーバーを設定
dns.setServers(['1.1.1.1', '8.8.8.8']);
console.log('新しい DNS サーバー:', dns.getServers());

dns.getServers() を使用すると、現在システムに設定されている DNS サーバーのリストを取得できます。dns.setServers() を使用すると、DNS サーバーをカスタマイズして、クエリ時に特定の DNS 解決サービスを使用できます。

非同期と同期メソッド

  • 非同期メソッド: 例:dns.lookup()、dns.resolve()などはノンブロッキングで、並行タスクに適しています。
  • 同期メソッド: 例:dns.lookupSync()、dns.resolve4Sync()はブロッキングで、小規模な使用に適しています。高並行シナリオでの使用は避けるべきです。

実際の適用シーン

  • Web アプリケーションのドメイン名解決: サーバー上でドメイン名の IP アドレスを照会して、Web ページやリソースを取得します。
  • メールサーバー設定の確認: MX レコードを使用して、メールサーバー設定の正しさを検証します。
  • スパム対策: 逆 DNS クエリを使用して、メールを送信するサーバーがドメイン名と一致するかどうかを検出し、スパムメールの送信元を特定します。
  • 負荷分散: ドメイン名のさまざまな IP アドレスを解決することで、負荷分散スキームを作成し、トラフィックを複数のサーバーに分散します。

dnsモジュールにより、Node.js アプリケーションはドメイン名解決と DNS クエリを実行でき、ネットワーク通信をより柔軟に処理できます。非同期インターフェースを使用することで、メインスレッドをブロックせずに DNS クエリを効率的に完了できます。

Java FileNode.js 組み込みモジュール

その他の拡張