labunix's blog

labunixのラボUnix

graph-easyとdotを組み合わせてネットワーク図を書いてみる。

■graph-easyとdotを組み合わせてネットワーク図を書いてみる。
 普段使用しているNW環境とは異なる、
 評価NW環境の評価NW環境のIPアクセス方法をすぐに忘れてしまうので、
 NW図を書いてみる。
 面白いsedのオプションを見つけたので、今回は出来るだけシェル芸で。

 Wheezyにlibgraph-easy-perlを導入、ASCIIでネットワーク図を描く。
 http://d.hatena.ne.jp/labunix/20130619

 Fortigate-60CのHA構成を外してトランスペアレントに変更する。
 http://labunix.hateblo.jp/entry/20150901/1441037405

 vSRXのシャーシクラスタ(HA構成/A-P)を試してみる。
 http://labunix.hateblo.jp/entry/20150919/1442600451

■graph-easyとdotを使用する作図環境は以下。

$ lsb_release -d
Description:	Debian GNU/Linux 8.2 (jessie)

$ graph-easy --version
Graph::Easy v0.75  (c) by Tels 2004-2008.  Released under the GPL 2.0 or later.

Running under Perl v5.020002 and using Graph::Easy::As_svg v0.23.

$ dot -V
dot - graphviz version 2.38.0 (20140413.2041)

■まずはおおまかな直線となるオブジェクトと関連をgraph-easyで書く。
 [FW-HA]2台構成で1台の仮想的なFW機能を提供するので、1オブジェクトとする。

$ echo "graph { flow: south; } \
  [Router]              --> \
  [FW-HA]               --> \
  [FW],[WLAN-Router]    --> \
  [Client1],[Client2]
  (Trial: [Client2])"       | graph-easy --dot | tee straight.dot
digraph GRAPH_0 {

  // Generated by Graph::Easy 0.75 at Wed Sep 23 23:43:26 2015

  edge [ arrowhead=open ];
  graph [ style=filled ];
  node [
    fillcolor=white,
    fontsize=11,
    shape=box,
    style=filled ];

  subgraph "cluster13" {
  label="Trial:";
  style=filled;
  labelloc=top;
  labeljust=l;
  fontsize="8.8";
  fontname=serif;
  fontcolor="#000000";
  fillcolor="#a0d0ff";
  color=white;

  "Client2"
  }
  Router -> "FW-HA" [ color="#000000" ]
  "FW-HA" -> "WLAN-Router" [ color="#000000" ]
  "FW-HA" -> FW [ color="#000000" ]
  FW -> "Client1" [ color="#000000" ]
  FW -> "Client2" [ color="#000000" ]
  "WLAN-Router" -> "Client1" [ color="#000000" ]
  "WLAN-Router" -> "Client2" [ color="#000000" ]

}

■上記をdot形式に変換

$ echo "graph { flow: south; } \
  [Router]              --> \
  [FW-HA]               --> \
  [FW],[WLAN-Router]    --> \
  [Client1],[Client2]
  (Trial: [Client2])"        | graph-easy --dot | tee straight.dot

digraph GRAPH_0 {digraph GRAPH_0 {

  // Generated by Graph::Easy 0.75 at Wed Sep 23 23:44:21 2015

  edge [ arrowhead=open ];
  graph [ style=filled ];
  node [
    fillcolor=white,
    fontsize=11,
    shape=box,
    style=filled ];

  subgraph "cluster13" {
  label="Trial:";
  style=filled;
  labelloc=top;
  labeljust=l;
  fontsize="8.8";
  fontname=serif;
  fontcolor="#000000";
  fillcolor="#a0d0ff";
  color=white;

  "Client2"
  }
  Router -> "FW-HA" [ color="#000000" ]
  "FW-HA" -> "WLAN-Router" [ color="#000000" ]
  "FW-HA" -> FW [ color="#000000" ]
  FW -> "Client1" [ color="#000000" ]
  FW -> "Client2" [ color="#000000" ]
  "WLAN-Router" -> "Client1" [ color="#000000" ]
  "WLAN-Router" -> "Client2" [ color="#000000" ]

}[FW][Client2]の直接的な関連は無いので行を削除

$ cp straight.dot straight.dot.bak; \
  sed -i '/FW.*Client2/d' straight.dot; \
  diff straight.dot*
29a30
>   FW -> "Client2" [ color="#000000" ][WLAN-Router]とClient1も直接の関連は無いので行を削除

$ cp straight.dot straight.dot.bak; \
  sed -i '/WLAN-Router.*Client1/d' straight.dot; \
  diff straight.dot*
29a30
>   "WLAN-Router" -> "Client1" [ color="#000000" ][FW-HA]からは[WLAN-Router]と同様に別の機器が接続されているので、そのオブジェクトを挿入

     1	digraph GRAPH_0 {
     2	
     3	  // Generated by Graph::Easy 0.75 at Wed Sep 23 23:44:21 2015
     4	
     5	  edge [ arrowhead=open ];
     6	  graph [ style=filled ];
     7	  node [
     8	    fillcolor=white,
     9	    fontsize=11,
    10	    shape=box,
    11	    style=filled ];
    12	
    13	  subgraph "cluster13" {
    14	  label="Trial:";
    15	  style=filled;
    16	  labelloc=top;
    17	  labeljust=l;
    18	  fontsize="8.8";
    19	  fontname=serif;
    20	  fontcolor="#000000";
    21	  fillcolor="#a0d0ff";
    22	  color=white;
    23	
    24	  "Client2"
    25	  }
    26	  Router -> "FW-HA" [ color="#000000" ]
    27	  "FW-HA" -> "WLAN-Router" [ color="#000000" ]
    28	  "FW-HA" -> FW [ color="#000000" ]
    29	  FW -> "Client1" [ color="#000000" ]
    30	  "WLAN-Router" -> "Client2" [ color="#000000" ]
    31	
    32	}

$ cp straight.dot straight.dot.bak; \
  sed -i -e '27h;27G;' -e '1,/WLAN-Router/s/WLAN-Router/FW2/' straight.dot; \
  diff straight.dot*
27d26
<   "FW-HA" -> "FW2" [ color="#000000" ]

$ cp straight.dot straight.dot.bak; \
  sed -i -e '31h;31G;' -e '/WLAN-Router/,/Client2/s/Client2/Client3/' straight.dot; \
  diff straight.dot*
31d30
<   "WLAN-Router" -> "Client3" [ color="#000000" ]

$ cp straight.dot straight.dot.bak; \
  sed -i -e '/Client3/s/WLAN-Router/FW2/' straight.dot; \
  diff straight.dot*
31c31
<   "FW2" -> "Client3" [ color="#000000" ]
---
>   "WLAN-Router" -> "Client3" [ color="#000000" ][FW]オブジェクトを削除する。

$ cp straight.dot straight.dot.bak; \
  sed -i -e '1,/FW ->/s/FW ->/"FW-HA" ->/' -e '/"FW-HA" -> FW/d' straight.dot; \
  diff straight.dot*
29c29,30
<   "FW-HA" -> "Client1" [ color="#000000" ]
---
>   "FW-HA" -> FW [ color="#000000" ]
>   FW -> "Client1" [ color="#000000" ]

■FW2、FW-HA、WLAN-Routerを同列にする。
 [rank=same]を使うとエラーは出ないが、graph-easyでは反映されない。
 ここからはdotコマンドの出番になる。

$ cp straight.dot straight.dot.bak; \
  sed -i -e 's/^}$/  {rank=same; FW2 "FW-HA" "WLAN-Router"}\n&/' straight.dot; \
  diff straight.dot*
33d32
<   {rank=same; FW2 "FW-HA" "WLAN-Router"}

$ dot -T svg straight.dot -o straight.svg

■Client1とFW-HAの矢印の方向を逆にする。
 graph-easyでは[dir={forward,both,back,none}]の指定に明確に対応していないエラーが出る。

$ cp straight.dot straight.dot.bak; \
  sed -i -e 's/\(Client1.*\)]/\1,dir=back ]/' straight.dot; \
  diff straight.dot*
29c29
<   "FW-HA" -> "Client1" [ color="#000000" ,dir=back ]
---
>   "FW-HA" -> "Client1" [ color="#000000" ]

$ graph-easy straight.dot 2>&1 | sed -e 's/]/&\n/g'
'[ color="#000000" ,dir=back ]
 "FW2" -> "Client3" [ color="#000000" ]
 "WLAN-Router" -> "Client2" [ color="#000000" ]
 {rank=same; FW2 "FW-HA" "WLAN-Router"} }' not recognized by Graph::Easy::Parser::Graphviz at /usr/bin/graph-easy line 93.

$ dot -T svg straight.dot -o straight.svg

■RouterとFW-HAの矢印の方向も逆にする。

$ cp straight.dot straight.dot.bak; \
  sed -i -e 's/\(Router .*\)]/\1,dir=back ]/' straight.dot; \
  diff straight.dot*
26c26
<   Router -> "FW-HA" [ color="#000000" ,dir=back ]
---
>   Router -> "FW-HA" [ color="#000000" ]

$ dot -T svg straight.dot -o straight.svg

■FW-HAを通る通信はすべて何らかのNATなので、ラベルを挿入

$ cp straight.dot straight.dot.bak; \
  sed -i -e 's/FW-HA.*\[ /& label="NAT" ,/g' straight.dot
  diff straight.dot*
26,29c26,29
<   Router -> "FW-HA" [  label="NAT" ,color="#000000" ,dir=back ]
<   "FW-HA" -> "FW2" [  label="NAT" ,color="#000000" ]
<   "FW-HA" -> "WLAN-Router" [  label="NAT" ,color="#000000" ]
<   "FW-HA" -> "Client1" [  label="NAT" ,color="#000000" ,dir=back ]
---
>   Router -> "FW-HA" [ color="#000000" ,dir=back ]
>   "FW-HA" -> "FW2" [ color="#000000" ]
>   "FW-HA" -> "WLAN-Router" [ color="#000000" ]
>   "FW-HA" -> "Client1" [ color="#000000" ,dir=back ]

■実際には、[Client2][Client3]もNATがかかるけど、
 [Client1]のみ管理出来るという図にしたいので、今回はClient2とClient3を[dir=none]にする。

$ cp straight.dot straight.dot.bak; \
  sed -i -e 's/\(Client[23].*\) ]/\1 ,dir=none ]/g' straight.dot
  diff straight.dot*
30,31c30,31
<   "FW2" -> "Client3" [ color="#000000" ,dir=none ]
<   "WLAN-Router" -> "Client2" [ color="#000000" ,dir=none ]
---
>   "FW2" -> "Client3" [ color="#000000" ]
>   "WLAN-Router" -> "Client2" [ color="#000000" ]

$ dot -T svg straight.dot -o straight.svg

■ここからはdotファイルを手修正しても良さそうだ。
 Client2ではなく、Client3が評価用のFWなので、手修正で対応。
 Client4はFW-HAに接続しているが、Proxyサーバを通してしかそれぞれにアクセス出来ないので破線で表現。
 多分第三オクテットが見れないとどんなNATかも分かりにくいと思う。。。

$ sed -e 's%[0-9]*\.[0-9]*\.[0-9]*/[0-9]*%X.X.X/XX%g' straight.dot | tee Xstraight.dot
digraph GRAPH_0 {

  // Generated by Graph::Easy 0.75 at Wed Sep 23 23:44:21 2015

  edge [ arrowhead=open ];
  graph [ style=filled ];
  node [
    fillcolor=white,
    fontsize=11,
    shape=box,
    style=filled ];

  subgraph "cluster13" {
  label="Trial:";
  style=filled;
  labelloc=top;
  labeljust=l;
  fontsize="8.8";
  fontname=serif;
  fontcolor="#000000";
  fillcolor="#a0d0ff";
  color=white;

  "Client3"
  }
  Router        [label="Router\n172.X.X.X/XX->192.X.X.X/XX"];
  "FW-HA"       [label="FW-HA\n172.X.X.X/XX->192.X.X.X/XX,172.X.X.X/XX"];
  "WLAN-Router" [label="WLAN-Router\n192.X.X.X/XX->10.X.X.X/XX"];
  "FW2"         [label="FW2\n172.X.X.X/XX->172.X.X.X/XX"];
  "Client1"     [label="Proxy\n172.X.X.X/XX"];
  "Client2"     [label="Client2\n10.X.X.X/XX"];
  "Client3"     [label="FW3\n172.X.X.X/XX->172.X.X.X/XX,192.X.X.X/XX"];
  "Client4"     [label="Client4\n172.X.X.X/XX"];

  Router -> "FW-HA" [  label="NAT" ,color="#000000" ,dir=back ]
  "FW-HA" -> "FW2" [  label="NAT" ,color="#000000" ]
  "FW-HA" -> "WLAN-Router" [  label="NAT" ,color="#000000" ]
  "FW-HA" -> "Client1" [  label="NAT" ,color="#000000" ,dir=back ]
  "FW-HA" -> "Client4" [ color="#000000" ,dir=none ,style=dashed ]
  "FW2" -> "Client3" [ color="#000000" ,dir=none ]
  "WLAN-Router" -> "Client2" [ color="#000000" ,dir=none ]
  "Client4" -> "Client1"


  {rank=same; "Client1" "Client4"}
  {rank=same; FW2 "FW-HA" "WLAN-Router"}
}

$ dot -T svg Xstraight.dot -o Xstraight.svg

■ところで、はてなはSVG形式に未対応だったようだ。

$ dot -T png Xstraight.dot -o Xstraight.png

f:id:labunix:20150924001753p:plain