Node.js net.isIPv4() でユーザー入力を安全に検証!IPv4アドレスチェックの基本

2025-04-26

関数の役割

  • IPv4アドレスとして無効な場合、falseを返します。
  • IPv4アドレスとして有効な場合、trueを返します。
  • 与えられた文字列がIPv4アドレスの形式に合致するかどうかをチェックします。

具体的な使い方

const net = require('net');

console.log(net.isIPv4('192.168.1.1')); // true
console.log(net.isIPv4('256.256.256.256')); // false
console.log(net.isIPv4('example.com')); // false
console.log(net.isIPv4('2001:0db8:85a3:0000:0000:8a2e:0370:7334')); // false

解説

  • net.isIPv4('2001:0db8:85a3:0000:0000:8a2e:0370:7334')は、IPv6アドレスなのでfalseを返します。
  • net.isIPv4('example.com')は、ドメイン名なのでfalseを返します。
  • net.isIPv4('256.256.256.256')は、IPv4アドレスの各オクテットが0から255までの範囲を超えているため、falseを返します。
  • net.isIPv4('192.168.1.1')は、有効なIPv4アドレスなのでtrueを返します。
  • サーバーが特定のIPv4アドレスからの接続のみを受け付けるように制限する場合。
  • 設定ファイルなどから読み込んだアドレスがIPv4アドレスとして有効かどうかをチェックする場合。
  • ネットワーク通信を行う際に、ユーザーから入力されたアドレスがIPv4アドレスとして正しいかどうかを検証する場合。


一般的なエラーとトラブルシューティング

    • エラー
      net.isIPv4('2001:0db8:85a3:0000:0000:8a2e:0370:7334') のようなIPv6アドレスをnet.isIPv4()に渡すと、falseが返ります。
    • トラブルシューティング
      IPv6アドレスを検証するには、net.isIPv6()を使用する必要があります。IPv4とIPv6を正しく区別して使用してください。
  1. 不正な形式の文字列を渡す

    • エラー
      net.isIPv4('192.168.1.')net.isIPv4('192.168.1.256') のように、IPv4アドレスの形式に合致しない文字列を渡すと、falseが返ります。
    • トラブルシューティング
      入力文字列が正しいIPv4アドレスの形式(xxx.xxx.xxx.xxx、各xxxは0から255までの数値)であることを確認してください。
  2. ドメイン名をIPv4アドレスとして検証しようとする

    • エラー
      net.isIPv4('example.com') のように、ドメイン名を渡すと、falseが返ります。
    • トラブルシューティング
      ドメイン名からIPアドレスを取得するには、dns.lookup()を使用する必要があります。net.isIPv4()はIPアドレスの形式検証のみを行います。
  3. ローカルホストアドレスの扱い

    • 注意
      net.isIPv4('127.0.0.1')trueを返しますが、net.isIPv4('localhost')falseを返します。
    • トラブルシューティング
      ローカルホストを扱う場合は、dns.lookup('localhost', (err, address, family) => { ... })を使用してIPアドレスを取得するか、直接127.0.0.1を使用してください。

コード例

const net = require('net');
const dns = require('dns');

function validateIPv4(address) {
  if (net.isIPv4(address)) {
    console.log(`${address} は有効なIPv4アドレスです。`);
  } else {
    console.log(`${address} は有効なIPv4アドレスではありません。`);
  }
}

validateIPv4('192.168.1.1');
validateIPv4('256.256.256.256');
validateIPv4('example.com');
validateIPv4('2001:0db8:85a3:0000:0000:8a2e:0370:7334');
validateIPv4(' 192.168.1.1');

dns.lookup('example.com', (err, address, family) => {
  if (err) {
    console.error('エラー:', err);
    return;
  }
  console.log(`example.com のIPアドレス: ${address}, ファミリー: ${family}`);
  validateIPv4(address);
});


const net = require('net');
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.question('IPv4アドレスを入力してください: ', (address) => {
  if (net.isIPv4(address)) {
    console.log(`${address} は有効なIPv4アドレスです。`);
  } else {
    console.log(`${address} は有効なIPv4アドレスではありません。`);
  }
  rl.close();
});

解説

  1. readlineモジュールを使用して、ユーザーからの入力を受け取ります。
  2. net.isIPv4(address)addressが有効なIPv4アドレスかどうかを判定し、結果に応じてメッセージを表示します。

この例では、文字列の配列から有効なIPv4アドレスを抽出します。

const net = require('net');

const addresses = [
  '192.168.1.1',
  '256.256.256.256',
  'example.com',
  '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
  '10.0.0.1',
];

const validIPv4Addresses = addresses.filter(net.isIPv4);

console.log('有効なIPv4アドレス:');
validIPv4Addresses.forEach((address) => {
  console.log(address);
});

解説

  1. addresses配列に、検証する文字列を格納します。
  2. addresses.filter(net.isIPv4)で、net.isIPv4()trueを返す文字列のみを抽出し、新しい配列validIPv4Addressesに格納します。
  3. validIPv4Addresses配列の各要素をコンソールに出力します。

この例では、サーバーが特定のIPv4アドレスからの接続のみを受け付けるように制限します。

const net = require('net');

const allowedIPv4 = '192.168.1.100';

const server = net.createServer((socket) => {
  const clientAddress = socket.remoteAddress;

  if (net.isIPv4(clientAddress) && clientAddress === allowedIPv4) {
    console.log(`${clientAddress} からの接続を許可しました。`);
    socket.end('接続が許可されました。\n');
  } else {
    console.log(`${clientAddress} からの接続を拒否しました。`);
    socket.end('接続が拒否されました。\n');
    socket.destroy();
  }
});

server.listen(3000, () => {
  console.log('サーバーがポート3000で起動しました。');
});
  1. allowedIPv4変数に、許可するIPv4アドレスを格納します。
  2. net.createServer()でサーバーを作成し、接続があった際のコールバック関数を定義します。
  3. socket.remoteAddressでクライアントのIPアドレスを取得します。
  4. net.isIPv4(clientAddress)でクライアントのIPアドレスがIPv4アドレスかどうかを検証し、clientAddress === allowedIPv4で許可されたIPアドレスと一致するかどうかを検証します。
  5. 検証結果に応じて、接続を許可または拒否します。
  6. server.listen()でサーバーを起動し、ポート3000で接続を待ち受けます。


正規表現 (Regular Expressions) を使用する

正規表現を使用すると、より柔軟なIPv4アドレスの検証が可能です。

function isValidIPv4(address) {
  const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
  if (!ipv4Regex.test(address)) {
    return false;
  }

  const parts = address.split('.').map(Number);
  return parts.every(part => part >= 0 && part <= 255);
}

console.log(isValidIPv4('192.168.1.1')); // true
console.log(isValidIPv4('256.256.256.256')); // false
console.log(isValidIPv4('example.com')); // false

解説

  1. ipv4RegexでIPv4アドレスの基本的な形式を検証します。
  2. address.split('.')で文字列をドットで分割し、各部分を数値に変換します。
  3. parts.every()で、各部分が0から255の範囲内にあるかどうかを検証します。

利点

  • カスタマイズ性が高い。
  • より詳細な検証が可能(例えば、特定の範囲のIPアドレスのみを許可するなど)。

欠点

  • net.isIPv4()よりもパフォーマンスが低い可能性がある。
  • 正規表現の記述が複雑になる場合がある。

ip-address パッケージを使用する

ip-addressパッケージは、IPアドレスの検証と操作を行うためのライブラリです。

const ipAddress = require('ip-address');

function isValidIPv4UsingPackage(address) {
  const IPv4 = ipAddress.Address4;
  return IPv4.isValid(address);
}

console.log(isValidIPv4UsingPackage('192.168.1.1')); // true
console.log(isValidIPv4UsingPackage('256.256.256.256')); // false
console.log(isValidIPv4UsingPackage('example.com')); // false

解説

  1. ip-addressパッケージをインストールします (npm install ip-address)。
  2. ipAddress.Address4.isValid()でIPv4アドレスの検証を行います。

利点

  • 信頼性が高い。
  • IPv6アドレスの検証やIPアドレスの範囲操作など、高度な機能を提供します。

欠点

  • net.isIPv4()よりもオーバーヘッドが大きい。
  • 外部パッケージのインストールが必要。

dns.lookup() を使用する(間接的な検証)

dns.lookup()を使用して、ドメイン名からIPアドレスを取得し、結果がIPv4アドレスかどうかを検証することもできます。ただし、これは直接的なIPv4アドレス検証ではありません。

const dns = require('dns');
const net = require('net');

function isDomainOrIPv4(address, callback) {
  dns.lookup(address, (err, ipAddress, family) => {
    if (err) {
      callback(false); // ドメイン名解決失敗
      return;
    }
    callback(net.isIPv4(ipAddress));
  });
}

isDomainOrIPv4('192.168.1.1', (isValid) => {
  console.log('192.168.1.1 is valid:', isValid); // true
});

isDomainOrIPv4('example.com', (isValid) => {
  console.log('example.com is valid(IPv4):', isValid); // true(example.comがIPv4アドレスに解決された場合)
});

isDomainOrIPv4('invalid.example', (isValid) => {
    console.log('invalid.example is valid:', isValid); // false
});

解説

  1. dns.lookup()を使用して、与えられたアドレスをIPアドレスに解決します。
  2. 解決されたIPアドレスがIPv4アドレスかどうかをnet.isIPv4()で検証します。

利点

  • ドメイン名とIPアドレスの両方を検証できます。
  • 直接的なIPv4アドレスの形式検証ではない。
  • ドメイン名が解決できない場合、検証に失敗します。
  • 非同期処理が必要。