Nmapのスキャン結果を比較し、ホストの稼働状況やポートの開閉状態などの変化を可視化するツール
- Ndiff -
ネットワーク内で新しいホストが出現したり、意図しないポートが開放されたりしても、その変化に気づけなければセキュリティ上のリスクを見逃す可能性があります。こうした変化を効率的に把握するために役立つのが、Nmapのスキャン結果を比較するツール「Ndiff」です。
本記事では、Ndiffのインストールからコマンドの実行方法、オプションまで解説します。
具体的な実行例に加え、不審なポート開放やシャドーITの検出、外部公開サーバーの定点チェックなど、実務で役立つ活用事例も紹介します。
Ndiffとは
Ndiffは、Nmapで取得した2つのスキャン結果を比較し、ホストやポート、サービスなどの変化を可視化するためのツールです。単に現在のネットワーク状態を確認するだけでなく、「前回の確認時点から何が変わったのか」を把握できる点が大きな特徴です。定期的なネットワーク監視や設定変更後の確認など、継続的なセキュリティ管理に活用できます。
- ホストの状態
- ポートの状態
- サービスやバージョン情報
- OSの判定結果
- Nmap Scripting Engine(NSE)の出力結果
Ndiffは、単純な文字列の比較ではなく、Nmapのスキャン結果に含まれる情報を解析し、その内容を比較します。具体的には、ホストやポートなどの項目単位でスキャン結果を照合します。これにより、実行ごとに変動する応答時間などの情報に左右されず、確認すべき変化だけを把握できます。

通常のdiffコマンドとの違い
Ndiffと似た名前のコマンドに、Linuxなどで利用されるdiffがあります。どちらも2つのデータの差分を確認するために使用しますが、対象とするデータが異なります。
| Ndiff | diff | |
|---|---|---|
| 主な用途 | Nmapスキャン結果の比較 | 一般的なファイルの比較 |
| ファイル形式 | NmapのXML出力のみ | テキストファイルなど |
| 比較対象 | ホスト、ポート、サービスなど | 行単位の文字列 |
| Nmapのスキャン結果の理解 | あり | なし |
| 汎用性 | Nmap専用 | 高い |
〝diff〟は汎用的な比較コマンドであり、ファイルの内容を主に行単位で比較します。そのため、Nmapの結果を比較すること自体は可能ですが、「その行がホスト情報なのか、ポート情報なのか」といったNmap固有の意味を考慮して比較するわけではありません。
【diffの問題点】
- スキャンのたびに変動する値(レイテンシなど)も差分として出力される。スキャン対象が数百台規模になれば、こうした値が大量に出力され、本来注目すべき変化を見落とす可能性がある。
- 複数ホストを対象とするスキャンでは、差分の行だけを見ても、そのポートがどのホストのものかを判別できない。
一方、〝Ndiff〟はNmapのスキャン結果を単なるテキストとしてではなく、その構造を理解したうえで比較します。これにより、上記(diff)の問題を解消し、ホストやポート状態、サービス情報など変化を分かりやすく表示します(具体的な出力例は後述します)。
Nmapとの関係
Ndiffは、Nmapプロジェクトが開発・配布している公式ツールで、Nmapスイートの一部として提供されています。
| ツール | 概要 | 備考 |
|---|---|---|
| Nmap | ホストの発見、ポートスキャン、サービスやOSの検出を行う本体 | |
| Zenmap(*) | NmapのGUIフロントエンド | |
| Ncat | ポートへの接続や待ち受け、データ転送などができる多機能ツール | |
| Nping | パケットの生成と応答の解析を行うツール | |
| Ndiff | 2つのスキャン結果を比較するツール | 本記事のメインテーマ |
* Zenmapに搭載されているスキャン結果の比較機能も、内部ではNdiffを利用しています。
Nmapスイートの各ツールの詳細は、以下の記事をご覧ください。
Ndiffのインストール
NdiffはNmapプロジェクトの一部として提供されていますが、インストール方法はOSやディストリビューションによって異なります。Nmap本体と一緒に導入される環境もあれば、Ndiffを個別にインストールする環境もあるため注意してください。詳細はNdiff公式サイトをご覧ください。
Nmap公式ダウンロードページでは、各OSごとのインストーラーを入手できます。
- Windows向け:
.exe形式 - macOS向け:
dmg形式 - Linux向け:
.rpm形式
.deb形式は提供していないため、Debian系ディストリビューションの場合、OS標準のパッケージマネージャ(APT)を使用してインストールします。
Kali LinuxやUbuntuなどのDebian系ディストリビューションでは、Ndiffが独立したndiffパッケージとして提供されています。(Kali Linuxにはプリインストール済みです。)
Ubuntu Server 26.04 LTSの場合
# パッケージリストの更新
$ sudo apt update
# Ndiffパッケージの確認
$ apt show ndiff
Package: ndiff
Version: 7.98+dfsg-1
Priority: extra
Section: universe/net
Source: nmap
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Security Tools <team+pkg-security@tracker.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 108 kB
Depends: python3-lxml, python3:any
Recommends: nmap
Breaks: nmap (<< 7.98+dfsg-1)
Homepage: https://nmap.org/
Download-Size: 23.0 kB
APT-Sources: http://jp.archive.ubuntu.com/ubuntu resolute/universe amd64 Packages
Description: The Network Mapper - result compare utility
Ndiff is a tool to aid in the comparison of Nmap scans. It takes two
Nmap XML output files and prints the differences between them them:
hosts coming up and down, ports becoming open or closed, and things like that.
It can produce output in human-readable text or machine-readable XML formats.
# Ndiffのインストール
$ sudo apt install ndiffNdiffの実行方法
NdiffはCLIツールであるため、ターミナル(Windows環境の場合はコマンドプロンプトまたはPowerShell)上で実行します。
Ndiffの実行の流れ
基本的な流れ
| 作業内容 | コマンド例 | |
|---|---|---|
| 1 | 比較元(基準)となるスキャン結果を取得する | nmap -oX baseline.xml 192.0.2.1 |
| 2 | 比較先となるスキャン結果を取得する | nmap -oX current.xml 192.0.2.1 |
| 3 | 2つのスキャン結果を比較する | ndiff baseline.xml current.xml |
| 4 | 検出された差分が想定された変更か確認する |
Ndiffで比較するNmapのスキャン結果は、同一の条件で取得することが重要です。使用するオプションや対象範囲が異なれば、その違いまで差分として現れます。詳細は、後述のNdiffを使用する際の注意事項をご覧ください。
ndiffコマンドの基本構文
$ ndiff [オプション] <比較元のXMLファイル> <比較先のXMLファイル>- オプション:出力形式や表示内容を指定(省略可)
- 比較元のXMLファイル:基準となる過去のスキャン結果
- 比較先のXMLファイル:比較したい新しいスキャン結果
Ndiffが読み込めるのは、Nmapの-oXオプション、または-oAオプションで保存したXML形式のスキャン結果だけです。通常形式(-oN)やGrep可能形式(-oG)のファイルは比較できません。
# 最もシンプルなXML出力のコマンド例
$ nmap -oX output.xml 192.0.2.1例えば、ある時点で取得した結果をbaseline.xml、後から取得した結果をcurrent.xmlを比較する場合は次のように実行します。
実行結果のイメージ
$ ndiff baseline.xml current.xml
〜 実行結果の抜粋 〜
-22/tcp close ssh
+22/tcp open sshオプションを省略すると、差分がテキスト形式で標準出力に表示され、各行の先頭に付く記号で「どちらのスキャン結果にあった情報か」を示します。
| 記号 | 意味 |
|---|---|
- | 比較元(1つ目のファイル)に存在するが、比較先(2つ目のファイル)に存在しない |
+ | 比較先(2つ目のファイル)にのみ存在する |
| なし | 比較元(1つ目のファイル)と比較先(2つ目のファイル)の内容が一致する ※ -v(--verbose)オプション指定時のみ有効 |
上記の実行結果の場合、sshで使用しているTCPポート22の状態がcloseからopenに変化したことが確認できます。
ndiffコマンドの終了コード
ndiffコマンドは、比較結果を終了コード(戻り値)でも返します。
| 終了コード | 意味 |
|---|---|
| 0 | 差分なし(Ndiffが比較するすべての項目で一致) |
| 1 | 差分あり |
| 2 | 実行時エラー(指定したXMLファイルを開けない など) |
LinuxなどUNIX系OSの場合、Ndiff実行直後にecho $?を実行すると終了コードを確認できます。
$ ndiff baseline.xml current.xml
$ echo $?
1注意が必要なのが、終了コード1がコマンドの失敗を意味するわけではないという点です。一般的なコマンドでは、終了コードが0以外の場合にエラーと判断するケースがあります。しかしNdiffの場合、1は「比較処理は正常に完了したが、差分が見つかった」という意味です。
オプション一覧
| オプション | 機能 | 主な用途 |
|---|---|---|
-h、--help | ヘルプを表示する | |
-v、--verbose | 変更のないホストやポートも表示する | 全体像の把握、監査用の記録 |
--text | 比較結果をテキスト形式で出力する(デフォルト) | 比較結果の目視確認 |
--xml | 比較結果をXML形式で出力する | スクリプト処理、他システムとの連携 |
Ndiffのオプションは4種類だけです。--textと--xmlは、出力形式を指定するオプションなので、どちらか一方だけを指定します。-vは、どの出力形式でも組み合わせ可能です。
-h、--help
$ ndiff -h
Usage: /usr/bin/ndiff [option] FILE1 FILE2
Compare two Nmap XML files and display a list of their differences.
Differences include host state changes, port state changes, and changes to
service and OS detection.
-h, --help display this help
-v, --verbose also show hosts and ports that haven't changed.
--text display output in text format (default)
--xml display output in XML format--helpは、Ndiffのヘルプを表示するオプションです。短縮形の-hも使用できます。
-v、--verbose
$ ndiff -v baseline.xml current.xml
-Nmap 7.99 scan initiated Fri Oct 09 17:11:45 2026 as: /usr/lib/nmap/nmap --privileged -oX baseline.xml 192.168.10.100-110
+Nmap 7.99 scan initiated Fri Oct 09 17:22:06 2026 as: /usr/lib/nmap/nmap --privileged -oX current.xml 192.168.10.100-110
192.168.10.103, 08:00:27:CB:9E:0C:
Host is up.
-Not shown: 998 filtered ports
+Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh
+80/tcp open http
9090/tcp open zeus-admin
192.168.10.106, 08:00:27:22:FB:7E:
Host is up.
Not shown: 999 closed ports
PORT STATE SERVICE VERSION
22/tcp open sshNdiffは通常、変化のあったホストとポートだけを出力しますが、-vまたは--verboseオプションを付けると、変化のないホストやポートも含めてすべて出力します。行頭に+または-の記号がない行が、変化のない情報です。
例えば、単に差分を確認するだけでなく、「前回から状態が変わっていない項目も含めて全体を確認したい」という場合に適しています。ただし、対象となるホストやポートが多いケースでは出力量も増えます。変化した部分だけを素早く確認したい場合、-vを付けずに実行した方が結果を追いやすいでしょう。
--text
$ ndiff --text baseline.xml current.xml # --textを指定
$ ndiff baseline.xml current.xml # 省略可能--textは、比較結果を人が読みやすいテキスト形式で出力するオプションです。出力形式を指定しない場合も、デフォルトでテキスト形式が適用されます。
結果はdiffコマンドに近い書式で出力され、行頭の記号が変化の種類を表します。
-:1つ目のスキャン結果にだけ存在する。または、変更前の状態。+:2つ目のスキャン結果にだけ存在する。または、変更後の状態。- 空白:変更なし(
-vまたは--verbose指定時のみ)
例えば、次の実行結果はSSHサービスのバージョンが更新されたことを示しています。
-22/tcp open ssh OpenSSH 8.9p1
+22/tcp open ssh OpenSSH 9.6p1--xml
# 日付付きのファイルに差分を保存する
$ ndiff --xml baseline.xml current.xml > ndiff_$(date +%Y%m%d).xml--xmlは、Ndiffの比較結果をXML形式で出力するオプションです。--textが目視による確認に適しているのに対し、--xmlはスクリプトによる自動処理や他のツール・システムとの連携に適しています。
XML形式の構造は、Nmapに同梱されているndiff.dtdで定義されています。導入方法によっては同梱されていない場合がありますが、公式GitHubからも確認できます。
比較結果をファイルとして保存する場合、シェルのリダイレクトを使用します。保存したXMLを別のプログラムで解析すれば、「前回から状態が変化した項目を抽出する」「差分情報を管理システムへ取り込む」といった自動化につなげられます。
Ndiffの実行例
このセクションでは、よく検出される以下のケースを例に、Ndiffの実行方法と出力結果を解説します。
- 新規ホストの出現
- 新規ポートの開放
- サービス・バージョンの変化
例)新規ホストの出現
-snオプションを指定し、ホストの稼働状況を調査します。$ nmap -sn -oX baseline.xml 192.168.10.0/24$ nmap -sn -oX current.xml 192.168.10.0/24$ ndiff baseline.xml current.xml
-Nmap 7.99 scan initiated Fri Oct 02 19:12:13 2026 as: /usr/lib/nmap/nmap --privileged -sn -oX baseline.xml 192.168.10.0/24
+Nmap 7.99 scan initiated Fri Oct 02 20:14:29 2026 as: /usr/lib/nmap/nmap --privileged -sn -oX current.xml 192.168.10.0/24
+192.168.10.12, 08:00:27:11:B3:0B:
+Host is up.1回目のスキャンでは確認できなかった192.168.10.12が、2回目のスキャンで検出されました。
例)新規ポートの開放
$ nmap -oX baseline.xml 192.168.10.103$ nmap -oX current.xml 192.168.10.103$ ndiff baseline.xml current.xml
-Nmap 7.99 scan initiated Fri Oct 09 19:25:36 2026 as: /usr/lib/nmap/nmap --privileged -oX baseline.xml 192.168.10.103
+Nmap 7.99 scan initiated Fri Oct 09 19:28:47 2026 as: /usr/lib/nmap/nmap --privileged -oX current.xml 192.168.10.103
192.168.10.103, 08:00:27:CB:9E:0C:
-Not shown: 998 filtered ports
+Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
+80/tcp open httpこの出力結果から、192.168.10.103のTCPポート80が開いたことが確認できます。
例)サービス・バージョンの変化
-sVオプションを指定し、サーバーで稼働しているサービスのバージョン情報を取得します。$ nmap -sV -oX baseline.xml 192.168.10.106$ nmap -sV -oX current.xml 192.168.10.106$ ndiff baseline.xml current.xml
-Nmap 7.99 scan initiated Fri Oct 09 19:30:09 2026 as: /usr/lib/nmap/nmap --privileged -sV -oX baseline.xml 192.168.10.106
+Nmap 7.99 scan initiated Fri Oct 09 19:32:20 2026 as: /usr/lib/nmap/nmap --privileged -sV -oX current.xml 192.168.10.106
192.168.10.106, 08:00:27:22:FB:7E:
PORT STATE SERVICE VERSION
-22/tcp open ssh OpenSSH 10.2p1 Ubuntu 2ubuntu3.5 (Ubuntu Linux; protocol 2.0)
+22/tcp open ssh OpenSSH 10.2p1 Ubuntu 2ubuntu3.7 (Ubuntu Linux; protocol 2.0)この出力結果から、TCPポート22で稼働しているOpenSSHについて、Ubuntuパッケージのリビジョンが更新されていることを確認できます。
Ndiffの活用事例
- 不審なポート開放・サービス起動の検出
- シャドーITの発見
- ソフトウェアのアップデート前後の比較
- ファイアウォールの設定変更前後の比較
- 外部公開サーバーの定点チェック
不審なポート開放・サービス起動の検出
サーバーで開いているポートは、本来、設計書や変更管理で把握されているべきもの。しかし現実には、「検証用に起動したサービスの停止漏れ」「ミドルウェアのデフォルト設定」「承認されていないソフトウェアの導入」などにより、想定外のポートが開いていることがあります。
こうした変化を捉えるには、正常時のスキャン結果を「ベースライン」として保存し、定期スキャンの結果と比較する方法が有効です。その結果、意図していないポートが新たにopenになっていれば、設定変更や新しいサービスの起動が発生した可能性があります。
また、Nmap実行時にサービス検出(-sVオプション)を指定している場合、ポートの開閉だけでなく、検出されたサービスの変化も確認できます。
- 新しく開放されたポートがないか
- 不要になったポートが閉じられているか
- 起動しているサービスに変化がないか
- サービスのバージョン情報が変わっていないか
ただし、ポートが新たに開放されたからといって、必ずしも問題があるとは限りません。システム更新や運用上の設定変更による可能性もあります。そのため、Ndiffで変化を検出した後は、変更管理記録やサーバー設定と照合し、想定された変更かどうかを確認することが重要です。
シャドーITの発見
シャドーITとは、企業の情報システム部門が把握・管理していない機器やサービスのこと。「個人が持ち込んだWi-Fiルーター」「部署単位で購入したNAS」「検証用に構築したまま放置された仮想マシン」などが典型例です。これらはパッチ適用や監視の対象から外れやすく、セキュリティ上の盲点になりがちです。
ホスト探索(-sn:ポートスキャンを行わないオプション)の結果を定期的に比較すれば、ネットワークに新たに接続された端末を効率よく洗い出せます。
ソフトウェアのアップデート前後の比較
OSやミドルウェアのアップデートは、脆弱性対策の基本です。しかし、アップデートによって追加機能や関連サービスが既定で有効化されるなど、意図しないネットワーク設定の変化が発生することがあります。アップデート前後のスキャン結果を比較すれば、こうした変化を速やかに把握することができます。
ファイアウォールの設定変更前後の比較
ファイアウォールやサーバーの設定変更では、たった1行の記述ミスが意図しない外部公開や不正アクセスといった重大なセキュリティインシデントにつながりかねません。こうしたリスクを抑えるため、変更前後にNmapでスキャンを実施し、Ndiffで差分を確認することで、ポートの状態がどのように変化したかを検証できます。
外部公開サーバーの定点チェック
インターネット上に公開されたサーバーは、常に第三者から観測される可能性があります。設定変更に伴う意図しないサービスの公開や、保守作業時に一時開放したポートの閉じ忘れは、攻撃対象領域の拡大につながるため注意が必要です。
NmapとNdiffを組み合わせた定点チェックは、外部公開されているIT資産を継続的に把握し、攻撃対象領域を管理する「ASM(Attack Surface Management)」の第一歩といえます。
Ndiffを使用する際の注意事項
Ndiffは、2つのスキャン結果を比較し、その差分を確認するためのツールです。出力される差分には、実際のネットワーク構成の変化だけでなく、スキャン条件の違いや通信状況の変動に起因するものも含まれます。差分を正しく判断するため、以下のポイントを押さえておきましょう。
同一条件でスキャンした結果を比較する
Ndiffで比較するNmapのスキャン結果は、同一の条件で取得することが重要です。使用するオプションやスキャンの対象範囲が異なれば、「ネットワーク構成の変化」ではなく「実行条件の違い」が差分として検出される可能性があります。
- スキャン対象のIPアドレスやネットワーク範囲
- 対象ポート
- TCP・UDPなどのスキャンタイプ
- サービス・バージョン検出の有無
- OS検出の有無
- タイミングやタイムアウト関連の設定
- Nmapを実行する端末やネットワーク上の位置
- Nmapを実行するユーザーの権限
- 使用したNmapのバージョン
例えば、前回は-sVを指定してサービス・バージョン検出を行い、今回は指定しなかった場合、サービス情報に多数の差分が表示されます。これは対象システムの変更ではなく、スキャン条件の違いによって生じた差分です。
【見落としやすいのが実行権限】
既定ではroot権限で実行するとSYNスキャン(-sS)を使い、一般ユーザー権限ではTCP接続スキャン(-sT)を使います。同じコマンドでも、sudoを付けるかどうかだけでスキャンタイプが変わるので、オプションで明示的にスキャンタイプを指定することを推奨します。
実行条件を揃える最も確実な方法は、スキャンコマンドのスクリプト化
定期的にスキャン結果を比較する場合、スキャンをスクリプト化し、cronなどで自動実行する方法が有効です。毎回手入力するのではなく、同じコマンドを使用する仕組みにしておけば、オプションの指定漏れや対象範囲の入力ミスを減らせます。
比較できるスキャン結果はXML形式のみ
Ndiffで比較できるのは、Nmapが出力したXML形式(-oXオプション)のスキャン結果だけです。通常形式(-oN)やGrep可能形式(-oG)で保存したファイルは使用できません。
Ndiffの利用を予定している場合、Nmapの-oAオプションを利用する方法もあります。-oAを指定すると、「通常形式」「XML形式」「Grep可能形式」をまとめて保存できます。目視確認には「通常形式」、Ndiffでの比較には「XML形式」というように、用途に応じて使い分けることができます。
OSやサービスの検出結果は推定値を含む
Nmapは対象ホストから得られた応答を分析し、保有しているシグネチャなどと照合してOSやサービスを判定します。そのため、取得できた応答の違いによって、検出結果が変化する場合があります。
OSやサービスに差分が確認された場合は、Ndiffの結果だけで変更が発生したと断定せず、対象ホストの設定情報やソフトウェア管理情報などと照合することが重要です。
ネットワーク状況による揺らぎ
Nmapは、送信したパケットへの応答の有無や内容からスキャン結果を判定します。そのため、スキャン時のネットワーク状況によって、同じ対象でも結果が変わることがあります。
- 一時的なパケットロス
- ネットワーク遅延
- ファイアウォールやACLによる通信制御
- レート制限
- 対象ホストの一時的な高負荷
- サービスの一時停止や再起動
こうした影響により、同じ対象を同じ条件でスキャンしても一時的に応答が得られず、ホストやサービスを正しく検出できないことがあります。
DHCPによるIPアドレス自動割り当て環境での注意点
NdiffはIPアドレスでホストを識別します。そのため、DHCP環境では同じホストがIPアドレスの変化によって「-(消えたホスト)」と「+(新しいホスト)」の両方に現れることがあります。MACアドレスを手掛かりに、同一端末かどうかを見極めましょう。
例)DHCP環境の場合
$ ndiff baseline.xml current.xml
-Nmap 7.99 scan initiated Fri Oct 02 22:44:47 2026 as: /usr/lib/nmap/nmap --privileged -sn -oX baseline.xml 192.168.10.0/24
+Nmap 7.99 scan initiated Sat Oct 03 00:37:23 2026 as: /usr/lib/nmap/nmap --privileged -sn -oX current.xml 192.168.10.0/24
-192.168.10.226, 08:00:27:22:3E:BC:
-Host is up.
+192.168.10.234, 08:00:27:22:3E:BC:
+Host is up.上記の実行結果では、192.168.10.226が消失し、新たに192.168.10.234が検出されています。しかし、両者のMACアドレスは同一(08:00:27:22:3E:BC)であるため、同じホストのIPアドレスが変更されたものと判断できます。

