9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

グラフDBでネットワーク構成図をレイヤごとに可視化できるか試してみた

Last updated at Posted at 2025-12-17

はじめに

ネットワーク構成図は、目的によって見せたい情報が大きく変わります。
物理構成を説明したいときもあれば、IPの経路だけを整理したいとき、アプリケーション間の通信関係だけを示したいときもあります。

そのため、それぞれで別々の構成図を描くことが負担になります。
そこで「データは一か所に集約し、見せ方だけを切り替える」ことを考えました。

この考えを試す手段として、グラフDB使ってネットワーク構成を表現できないかグラフDBの使い方を勉強しつつ試してみました。

やりたいこと

今回はサンプルとして、Client → Switch → Router → WebServer という構成のネットワークで、以下のような見え方を実現できるか試してみました。

network.png

  • 物理レイヤ: 物理的な接続が全て見える
  • IPレイヤ: IPルーティング経路のみ見える
  • アプリケーションレイヤ: HTTPエンドポイント間の経路のみ見える

このように、同じデータから、レイヤごとに異なる情報を取り出せるかを試してみました。

実装

環境構築

グラフDBについて、今回はNeo4jを利用します。(下記に従いDockerで構築しました)

docker compose up -d

これで http://localhost:7474 にアクセスすれば、Neo4j Browserが使えます。

今回は、この Browser 上でデータ登録と可視化を行います。

データの登録

ノードは共通、エッジをレイヤごとに分けることを意識して登録していきます。

以下のステップ通りにデータを登録していきます。

ステップ1: ノードの作成

4つの機器を Device ノードとして登録します。ノードには共通プロパティ(name, type)と、必要に応じてIP情報を追加します。

CREATE (client:Device {name: "Client", type: "client", ip: "192.168.1.100"});
CREATE (switch:Device {name: "Switch", type: "switch"});
CREATE (router:Device {name: "Router", type: "router", ip: "10.0.0.1"});
CREATE (web:Device {name: "WebServer", type: "webserver", ip: "10.0.0.10"});

Cypherの記法に関する補足:

  • client:Device: client は変数名、Device はラベル(ノードの種類)。どちらも任意の名前を付与可能
  • {name: "Client", ...}: {} で囲まれた部分はプロパティ(属性情報)。ノードに持たせたい情報を定義

命名規則の補足:Neo4jでは以下の命名規則が推奨されています(公式ドキュメント参照):

  • Node labels: PascalCase(各単語の先頭が大文字、スペースやアンダースコアなし)例: :Device, :VehicleOwner
  • Relationship types: UPPER_CASE(全て大文字、単語間はアンダースコア)例: :CONNECTS, :OWNS_VEHICLE

ステップ2: 物理レイヤのエッジ(リレーション)を作成

物理レイヤでは、実際にケーブルで接続されている関係を定義します。

MATCH (client:Device {name: "Client"}), (switch:Device {name: "Switch"})
CREATE (client)-[:CONNECTS {layer: "physical", port: "eth0", cable: "CAT6"}]->(switch);

MATCH (switch:Device {name: "Switch"}), (router:Device {name: "Router"})
CREATE (switch)-[:CONNECTS {layer: "physical", port: "eth1", cable: "CAT6"}]->(router);

MATCH (router:Device {name: "Router"}), (web:Device {name: "WebServer"})
CREATE (router)-[:CONNECTS {layer: "physical", port: "eth2", cable: "CAT6"}]->(web);

Cypherの記法に関する補足:

  • MATCH: ラベルが Device のノードの中からname プロパティが "Client" にマッチしたものを変数(client, switch など)に
  • CREATE (client)-[:CONNECTS {...}]->(switch): ノード間の関係を作成
    • CONNECTS はリレーションシップの種類(Relationship Type)で、任意の名前を付与
    • -> はグラフ上の関係の向きを表す(物理的な通信方向を意味するわけではない)
    • プロパティ {} を持たせることが可能

layer: "physical" を付与し、物理レイヤ特有の情報(ポート番号、ケーブル種別)をプロパティとして持たせます。

ステップ3: IPレイヤのエッジ(リレーション)を作成

IPレイヤでは、IPパケットのルーティング観点で接続を定義します。IPレイヤなので、L2のSwitchは記載しません。

MATCH (client:Device {name: "Client"}), (router:Device {name: "Router"})
CREATE (client)-[:CONNECTS {layer: "ip", src_ip: "192.168.1.100", dst_ip: "10.0.0.10"}]->(router);

MATCH (router:Device {name: "Router"}), (web:Device {name: "WebServer"})
CREATE (router)-[:CONNECTS {layer: "ip", src_ip: "192.168.1.100", dst_ip: "10.0.0.10"}]->(web);

layer: "ip"` という情報と、IPレイヤ特有の情報(送信元IP、宛先IP)を持たせます。

ステップ4: アプリケーションレイヤのエッジ(リレーション)を作成

アプリケーションレイヤでは、エンドポイント間の通信のみを定義します。

MATCH (client:Device {name: "Client"}), (web:Device {name: "WebServer"})
CREATE (client)-[:CONNECTS {layer: "application", protocol: "HTTP", endpoint: "/index.html"}]->(web);

layer: "application" という情報と、アプリケーションレイヤ特有の情報(プロトコル、エンドポイント)を持たせます。

データ構造のまとめ

  • ノードは全レイヤ共通
  • エッジ(リレーション)はレイヤごとに分離
  • レイヤの違いは、layer プロパティで区別

これにより、「同じノードセットから、レイヤに応じて異なるエッジ(リレーション)を取り出す」ことができます。

レイヤ別可視化クエリ

各レイヤを可視化するCypherクエリを紹介します。(あとでNeo4j Browserの設定や表示内容を説明します)

物理レイヤ

MATCH path = (a:Device)-[r:CONNECTS {layer: "physical"}]->(b:Device)
RETURN path

Cypherの記法に関する補足:

  • MATCH path = ...: 条件に合うパターンを検索し、結果を変数 path に格納
  • (a:Device): Device ノードを変数 a に格納
  • -[r:CONNECTS {layer: "physical"}]->: リレーションがCONNECTS で、layer プロパティが "physical" のものを変数 r に格納
  • RETURN path: マッチしたパス全体(ノード a、エッジ r、ノード b)を返します

つまり、「物理レイヤで繋がっている全てのノードペア」を取得するクエリとなります。

IPレイヤ

MATCH path = (a:Device)-[r:CONNECTS {layer: "ip"}]->(b:Device)
RETURN path

アプリケーションレイヤ

MATCH path = (a:Device)-[r:CONNECTS {layer: "application"}]->(b:Device)
RETURN path

layer プロパティでフィルタリングするだけで、各レイヤのグラフが取得できます。

Neo4j Browserの設定

Neo4j Browserでは、デフォルト設定のままだと指定していないリレーションまで表示されるので、オフにします。

  1. Neo4j Browserの左下にある歯車アイコン(Settings)をクリック
  2. 「Graph Visualization」セクションを探す
  3. 「Connect result nodes」のチェックを外す

この設定変更により、クエリで指定したリレーションのみが表示されます。

結果

実際にNeo4j Browserでクエリを実行してみた結果がこちらです。 期待通り、レイヤごとに異なる可視化ができました。

物理レイヤ

L1.png

IPレイヤ

L3.png

アプリケーションレイヤ

L8.png

まとめ

グラフDBでは、「同じノードセットに対して、複数の異なる関係性を定義する」ことができるため、このようなレイヤ別可視化を実現できることがわかりました。

一方で、実際に使っていくには、以下のような改善点が残ります。

  • データ登録の簡易化
  • 可視化にあたってのUI改善

それでも、「構成図を描く」という作業を改善できる可能性は十分に感じられました。

参考リンク

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?