Help us understand the problem. What is going on with this article?

WebからNAPALMを叩くには(NetDevOpsSecの現実解)

More than 3 years have passed since last update.

はじめに

この記事は、NetOpsCoding Advent Calendar 2016 の 2016年12月14日 の記事です。

ネットワーク機器の操作にはCLIが用いられることが多いが、CLIだとプログラムから扱うのが難しい (-_-;)

プログラムから扱いやすくするため、Spotify を中心とした一部のエンジニアが、'napalm' というライブラリを作成している。(Paramikoベース)
https://github.com/napalm-automation/napalm

実際の例

今回はJunos + CGI + napalm の構成で、Webからコンフィグロードを実施してみる。
Web からコマンドを叩きたい場合、(例えば、Firewallのポリシー追加) 以下のようなHTML/CGIを用意する。

firewall-policy.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form action="cgi-bin/firewall-policy.py" method="post">
    srcaddress:<input type="text" name="srcaddress">
    srcnetmask:<input type="text" name="srcnetmask">
    destaddress:<input type="text" name="destaddress">
    destnetmask:<input type="text" name="destnetmask">
    applicationname:<input type="text" name="applicationname">
    policy_then:<input type="text" name="policy_then">
    <input type="submit" value="Go">
</form>
</body>
</html>
firewall-policy.py
#!/usr/bin/python


##
(srxipaddr, srxuser, srxpasswd)=('192.168.xx.xx', 'xx', 'xx')
##

import cgi
from napalm import get_network_driver

fs = cgi.FieldStorage()

js={}
for key in fs.keys():
  js[key]=fs[key].value

##
# do import stuff
##
candidate_config_template="""
security policies from-zone untrust to-zone untrust policy automation-policy {{
   match {{
       source-address automation-policy-src;
       destination-address automation-policy-dest;
       application {applicationname};
       }}
       then {{
           {policy_then};
   }}
}}
security zones security-zone untrust address-book {{
   address automation-policy-src {srcaddress}/{srcnetmask};
   address automation-policy-dest {destaddress}/{destnetmask};
}}
"""
candidate_config=candidate_config_template.format(**js)

driver = get_network_driver('junos')
device = driver(srxipaddr, srxuser,  srxpasswd)
device.open()
print (candidate_config)
device.load_merge_candidate(config=candidate_config)
print (device.compare_config())
device.commit_config()
device.close()

ポイントとしては

  • Webフォームから受け取った引数を、dict (=JSON=YAML) に変換した後、コンフィグテンプレートに適用する

というところだろうか、、

もっと詳しく知りたい方は、以下を参照。
http://qiita.com/taijijiji/items/a3f21c8b9e7a0d3afdc6
http://www.slideshare.net/JuniperJapan/interop-tokyo-2016junos-automation

先駆者諸兄の素晴らしいブログのおかげで、あっさり終わってしまった、、、(-o-;)

これだと、本当にさらっと終わってしまい少々寂しいため、、もう少し複雑な例で考えてみたいと思う (-_-;)

承認フローとは

既に書いてきた通り、定型作業をWebから実施する場合、ユーザー指示(要するに、引数) の流れは、以下であらわせる。

  1. 申請者(=作業者) -> Webアプリ -> napalm

ただ、このフローには

  • ブラウザを操作して、作業内容を記述する人(申請者)
  • 実際に作業を行う人(作業者)

が同じでないと使えない、という制限があり、実際の運用だとここが問題になってくる。

どういうことかというと、ITオペレーションについて監査が発生する、Enterprise環境では、
'申請者(アプリケーション開発ベンダーなど)' が直接、本番環境を操作できない、という制限が発生する。
※ いわゆるDevとOps

(参考)
http://forza.cocolog-nifty.com/blog/2015/02/itdevops-691f.html
http://blogs.itmedia.co.jp/infra/2013/09/devops1devops-7abb.html

この場合、申請者が記述した内容を承認者が承認、その後、作業者が作業実施、という流れになるのだが、
ITIL対応のツール(大抵、監査ではここが集中的に見られる) では、ここが画面として固定され、作業内容は添付ファイルで、という状況が発生する。
※ 少なくとも2つのベンダーのツールで遭遇した、、(-_-;)

なので、この場合の現実的なフローは以下となる。

  1. 申請者 -> 作業指示書(エクセルなど) -> ITILツール -> (ワークフロー) -> 作業者
  2. 作業者 -> Webアプリ -> napalm

この場合、申請者は出来るだけ細かく、作業指示書を記述するのだが、
日本語で説明できる情報には限界がある、、、
Amazon の画面を見ながら、注文は全てメールで出す、という感じで、

  • どこに、いつ届けるのか?
  • 先にピック出来た場合、分割して発送するのか?
  • 支払い方法は?

など、一発で正確に伝えきるのは正直難しい。
さらに、

  • そもそも在庫がいくつあるのか?

等、システムで調べないと分からない内容を確認する、等も含めると、
申請者の方も何らかのWebアプリをベースにして申請書を作るのが望ましい、と思う。

なので、理想的なフローとしては、以下、と思う。

  1. 申請者 -> Webアプリ -> 入力内容をJSONでエクスポート
  2. 申請者-> ITILツール(JSON添付) -> (ワークフロー) -> 作業者
  3. 作業者 -> Webアプリ(JSONをインポート) -> napalm

これが実現できると、以下のメリットがある。

  • 申請者(Dev): 作業可能な内容かどうか、をWebアプリで、自分で調べながら依頼書を作成できる、作業者とのやりとりが減る
  • 作業者(Net, Ops): 作業がJSONインポート、に限定される、実機を操作する必要がない、申請者とのやりとりが減る
  • セキュリティ担当者(Sec(仮)): フロー外の承認が行われにくくなるので、エビデンスの残し方に悩む必要がない、エビデンス保持(3年保管、など)の方法に悩む必要がない

ツールをインプリしてみた

上記の課題について、手前味噌ながら、以下のツールをインプリしてみた。
https://github.com/tnaganawa/execjson

ツールの画面イメージは以下となる。
advent-calendar-2016.png

まず、申請者は実施作業ごと(例では、Firewallポリシー追加) に、入力内容をWebフォームに入力する。
入力し終わったら'exportjson' をクリックすると、JSONがエクスポートされるので、そちらを承認フローに通す。
※ 作成されるJSONは以下

sample.json
{
    "jobapplcode": "", 
    "jobenvcode": "Prod", 
    "joblist": [
        {
            "args": [
                {
                    "applicationname": "junos-vnc", 
                    "destaddress": "192.168.12.11", 
                    "destnetmask": "32", 
                    "policy_then": "permit", 
                    "srcaddress": "192.168.11.11", 
                    "srcnetmask": "32"
                }
            ], 
            "id": "1", 
            "iffail": "stop", 
            "name": "addfirewallpolicy", 
            "time": ""
        }
    ]
}

その後、JSONを受け取った作業者は、'load'で、JSONを再度インポートし、'execjson' を押すと、今度は処理が流れ始める、はずである。
※ 実際にはもう少しいろいろあるので、wiki 参照 (-_-;)

まとめ

上記ツールで、ユーザー依頼作業の自動化について、とっかかりが得られるとよい、と思う。(環境依存なので何ともいえないが)
実際、DevOpsの流れはだいたいセキュリティで止まるのだが、上記のようなツールを使って、

  • DevOps -> NetDevOps -> NetDevOpsSec <- New!

の順で、徐々に改善範囲を広げていければよいのではなかろうか。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away