■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