読者です 読者をやめる 読者になる 読者になる

LGTM

Looks Good To Me

知ったかぶりしない NETCONF

最近ネットワーク関連のカンファレンスなどで 再び注目され始めたNETCONF について調べてみた.

NETCONF はネットワークデバイスの設定や状態を取得/更新するための管理用プロトコルで, 特にネットワーク全体を統合管理できるという特徴を持つ. RFC で標準化されている.

背景

NETCONF のはじまりは結構古くて, 2001 年くらいから「こんなのあったらいいよね」という議論があったっぽい. ネットワーク運用者にとって 当時の大きな問題は「CLI + SNMP によるネットワーク管理はめんどい」ということ.

2002 年のIAB Network Management Workshop でも議論され, その結果がInformational なRFC としてまとめられている.

RFC3535: Overview of the 2002 IAB Network Management Workshop

  • IAB: Internet Architecture Board
    • ワークショップにはIAB のメンバーに加え, 各分野のエキスパートが参加
    • アプリエンジニアにとっては, アジャイルマニフェストと その土台となった議論をイメージしてもらうといいかもしれない
  • 当時 管理用プロトコルとして広く実装されていたのは, CLISNMP
    • CLI には問題があった
    • SNMP にも問題があった
      • 仕様上はデバイスの設定変更も可能だが, 実装が普及しなかった
      • ほとんど監視とエラー通知に使われていた

そこで議論された「こんなのあったらいいよね」はまとめると14項目あって,

  1. 運用者が簡単に使えること
  2. 設定値, 状態, 統計情報を区別して扱えること
  3. 設定値, 状態, 統計情報を個別に取得できること. デバイス間で比較できること
  4. ネットワーク全体を統合的に扱えること
  5. 複数デバイスにまたがる設定について, トランザクション処理できること
  6. ある設定が投入されたとき, 不要な変更, 不要な状態遷移をしないこと
  7. 設定のセーブ/リストアができること
  8. 設定のバリデーションができること
  9. 設定データの標準的なスキーマがあること
  10. 設定はテキストとして扱えること
  11. ロールベースのアクセスコントロールが効くこと
  12. デバイス間でACL (Access Control List) の比較/検証ができること
  13. 複数バージョンの設定を投入できること. どのバージョンも個別に有効化できること
  14. データ志向のアクセスコントロール / タスク志向のアクセスコントロール, 両方をサポートすること
    • SNMP: データ志向 (どんなデータにアクセスできるか)
    • CLI: タスク志向 (どんな操作を許可するか)

こんな要件をスタートとしてIETF で議論され, 2006 年にRFC4741~4744 として標準化された. 当時 SOAP とかWSDL がバズっていたようで, NETCONF もその影響を受けている.

私が初めてNETCONF を知ったのは2008 年だったが, マーケットが小さかったのか 周辺仕様が定まってなかったのか, 実装を目にすることはあまりなかった.

ようやく見えてきた形

その後も継続的に議論されていたが

  • ネットワークデバイスからの通知
  • RPC 向け部分ロック
  • デフォルト値の扱い
  • トランスポート
  • データモデル

なども含めて標準化が進んできたのが2011 年. アクセスコントロールモデルの標準化が2012 年. 現在は

  • ネットワークデバイスからの通知に デバイス側からのSSH セッションを使う (Reverse SSH)
  • やっぱREST だよ (RESTCONF)
  • 初期設定の自動投入 (Zero Touch Provisioning)

このような標準化のための議論が進んでいる.

最近になってNETCONF が再注目されているのは, SDN / NFV がバズっていることと関係があると思っている. 解決する問題やユースケースについてNETCONF とは一致しないものの, 自動化という意味合いで方向性は一緒. SDN がデプロイされ始めてネットワークの自動化が一般的になり, 既存の資産について「こいつも自動化したいんだけど」という強い要望が背景にあるんだろうなと考えている.

NETCONF とは

NETCONF はRFC4741 として2006年に標準化された. (NETCONF1.0) その後デバイス操作の拡張やロックのしくみ, エラーハンドリングなどを含めて2011年にRFC6241 としてまとめられている. (NETCONF1.1)

NETCONF のベースはXML-RPC で, オーケストレーター(client) がネットワークデバイス(server) を制御する.

大まかに言えばNETCONF は

  1. Operations レイヤー
  2. Messages レイヤー
  3. Secure Transport レイヤー

の3層構造で, 上にはContent レイヤーと呼ばれる層がある.

           Layer                 Example
      +-------------+      +-----------------+      +----------------+
  (4) |   Content   |      |  Configuration  |      |  Notification  |
      |             |      |      data       |      |      data      |
      +-------------+      +-----------------+      +----------------+
             |                       |                      |          YANG
----------------------------------------------------------------------------
             |                       |                      |       NETCONF
      +-------------+      +-----------------+              |
  (3) | Operations  |      |  <edit-config>  |              |
      |             |      |                 |              |
      +-------------+      +-----------------+              |
             |                       |                      |
      +-------------+      +-----------------+      +----------------+
  (2) |  Messages   |      |     <rpc>,      |      | <notification> |
      |             |      |   <rpc-reply>   |      |                |
      +-------------+      +-----------------+      +----------------+
             |                       |                      |
      +-------------+      +-----------------------------------------+
  (1) |   Secure    |      |  SSH, TLS, BEEP/TLS, SOAP/HTTP/TLS, ... |
      |  Transport  |      |                                         |
      +-------------+      +-----------------------------------------+

(4) Content レイヤー

  • 設定, 状態, 通知などのデータ
    • 「YANG」と呼ばれるNETCONF のためのデータモデルに従って格納する
      • RFC6020
  • NETCONF の範疇ではない
  • オーケストレーター上のアプリケーションはこのデータにアクセスするため,
    • データ構造がデバイス種別やメーカーに依存しない
    • データ構造が明確

    であることが望ましい

たとえば, デバイス上のインターフェイス設定データは次のような構造になっている.

container interfaces {
  list interface {
    key "name";
    leaf name { type string; }
    leaf description { type string; }
    leaf type {
      type identityref { base interface-type; }
      mandatory true;
    }

    leaf enabled {
      type boolean;
      default "true";
    }

    leaf link-up-down-trap-enable {
      if-feature if-mib;
      type enumeration {
        enum enabled { value 1; }
        enum disabled { value 2; }
      }
    }
  }
}
データストア

設定データは「データストア」に保存される. データストアは3種類ある.

名前 概要
<running> 現在アクティブな設定を保存
<candidate> アクティブでない設定を保存
<startup> 起動後にロードされる設定を保存

<running> を変更すれば動作を変えることができるが, デバイスを再起動すると その変更が失われる. 変更を保存するには<running> を<startup> にコピーすればよい.

(3) Operations レイヤー

XMLベースで, デバイス操作方法やデータストアへのアクセス方法, パラメーターを規定している.

操作 概要
<get-config> 設定データの一部または全部を取得する
<edit-config> 設定データを一部または全部を変更する
<copy-config> 設定データを入れ換える (<candidate> を <running> に, など)
<delete-config> 設定データを全削除する (<candidate> を削除, など)
<lock> 設定データをロックする
<get> デバイスの状態を取得する
<unlock> 設定データをアンロックする
<close-session> NETCONF セッションを終了する
<kill-session> NETCONF セッションを強制終了する

なお, NETCONF server / client が各種Capability をサポートすることにより 機能拡張できる.

操作 概要
<commit> <candidate> を<running> にコピーする
<confirmed> パラメーターが指定された場合, Confirmed <commit> 動作をする.
(再度<confirmed>パラメーターなしで<commit>が実行されない限り, 10分後に設定が巻き戻る)
<discard-changes> <commit> 前の<candidate> を削除する
<cancel-commit> Confirmed <commit> をキャンセルする
<validate> 設定データを検証する
<get-schema> NETCONF サーバーからXML スキーマを取得する (RFC6022)

(2) Messages レイヤー

  • RPC とNotification のしくみを規定
    • <rpc> message と, それに対する<rpc-reply>
    • ステータス<rpc-error> と<ok>

Ethernet0/0 のMTU を1500 にする例:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <top xmlns="http://example.com/schema/1.2/config">
        <interface>
          <name>Ethernet0/0</name>
          <mtu>1500</mtu>
        </interface>
      </top>
    </config>
  </edit-config>
</rpc>

成功した場合:

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

(1) Secure Transport レイヤー

  • 様々なトランスポートプロトコルが利用可能だが, SSH が主流
  • 現在はNETCONF1.1 over TLS の仕様策定が進んでいる

NFV / SDN との比較

NETCONF はOpenFlow などSDN と比較される場合があるけれども, 解決する問題が違う. ネットワークデバイスを制御するプロトコルであって, トラフィックを自由に扱えるわけではない. もちろん設定を変えることでデバイスのふるまいを変えて 間接的にトラフィックを制御することは可能だが, トラフィック制御の機能はデバイスの仕様次第だし, リアルタイムに動的制御するには向かないアーキテクチャ.

逆に言えばNETCONF はシンプルで, ハードウェア依存が小さそう. 「OpenFlow スイッチみたいなデバイスじゃなくても 自動化できるかも」という期待が持てる. もうひとつ「デバイスを設定するプロトコルを統一したい(SDN 用のHWも含めて)」という要求にはNETCONF がマッチすると思う.

一方でSDN がすごいのは, OpenFlow で言う「Flow Table によって動的にトラフィックが制御できる」点であって, たとえば「DDoS を受けたらトラフィックを絞る」みたいなリアルタイム制御が実現可能なこと. 「デプロイされるアプリに応じて必要なサービスVLAN を作る」ような自動プロビジョニング的ニーズもあるが, そのためだけに「ハードウェアはOpenFlow スイッチに限る」という制約を課せる事業者は多くないんじゃないかと思う.

半分期待を込めて言えば 自動設定程度のことはハードウェアによらず実現できるべきなので, NETCONF の良い実装が出てきて, ネットワーク設計やハードウェア選定の幅が広がって欲しい.

それから, NFV は「ネットワーク機能の仮想化 = 汎用サーバ上でのネットワーク機能具現化」だから「ネットワークハードウェアを抽象化」しようとするNETCONF とはちょうど反対のコンセプトに見える. NFV とSDN が補完関係にあるように, NETCONF もSDN を補完して「Flow コントローラーだけど, ついでにハードウェアルーターまで面倒みるよ」みたいな動きをするかもしれない.

所感

いまどき XML?

メッセージエンコーディングには流行があるので「JSON やMessagePack じゃないとダメ」とは思わないが, エンコーディングを変更できる余地が残っていると良かったかも.

  • 設定が馬鹿デカいとXML はオーバーヘッド大きそう
  • JSON で読み書きできたら, web 界隈の知見が生かせたかもしれない

と思う.

SSH 以外は使えないの?

メッセージングだけのためにSSH はオーバーヘッド大きいので, せめてTLS, できればWebSocket を使いたい.

  • NETCONF1.0 over TLS は5539 になっているが, NETCONF1.1 がまだ
  • NETCONF over WebSocket はI-D (Internet Draft. 標準化前の状態)

で, 結局やりたかったことは実現できそうなの?

RFC3535 の14コの夢のうち, 半分ほどは定義されている.

2 . 設定値, 状態, 統計情報を区別して扱えること
3 . 設定値, 状態, 統計情報を個別に取得できること. デバイス間で比較できること
7 . 設定のセーブ/リストアができること
8 . 設定のバリデーションができること
10 . 設定はテキストとして扱えること
11 . ロールベースのアクセスコントロールが効くこと
13 . 複数バージョンの設定を投入できること. どのバージョンも個別に有効化できること
14 . データ志向のアクセスコントロール / タスク志向のアクセスコントロール, 両方をサポートすること

複数デバイスをまとめて 1つのネットワークとして扱う, 下記オーケストレーション機能については実装次第.

4 . ネットワーク全体を統合的に扱えること
5 . 複数デバイスにまたがる設定について, トランザクション処理できること
12 . デバイス間でACL (Access Control List) の比較/検証ができること

NETCONF client アプリで頑張らないといけない部分だが, まだ問題があるように見える.

9. 設定データの標準的なスキーマがあること

現時点で標準的なスキーマがないので, 設定の構造やパラメーター名はデバイス種別+メーカー依存. NETCONF client が差分を吸収しないといけない. さらにはNETCONF 向けXML スキーマを公開していないメーカーもあるので, CLI やリファレンスマニュアルから想像しつつXML を作らないといけないが... 厳しそう.

Juniper のようにNETCONF ライブラリをOSS で出してもらうとか, Brocade のようにYANG モデルを公開してもらうとか, 何かしら情報がないと実装できないよね.

YANG によるモデル化は進んでるの?

  • 調査できた範囲では, まだまだModule が足りない. おそらくinterface + IP のみ
    • Routing Protocol もまだ
  • GitHub
  • YANG が柔軟すぎて, メーカー依存が増える予感

「運用者が簡単に使える」ってどういうこと?

SIer やソフトウェア開発者がいなくても, 運用者が使える」と説明しているスライド もあるが, 「運用者でもライブラリを使えば簡単にコーディングできる」であって欲しい.

rancid / exscript で自動化してるけど,NETCONF 使うべき?

比較的ちゃんと動くし,ぜひ検討するべきだと思う. 正しくエラーを捕捉できるし, リターンコードの検証が正確になる.

  • デバイス個別にCLI コマンドを出し分けていると思うが, XML を出し分けるようにすればいい
  • YANG モデル化が進んだとしてもXML スキーマは共通にならず, デバイス種別+メーカー依存が残ると思われる
    • 本気でやるなら YANG モデルをもう一段wrap して自分たちのモデルを作り, デバイス+メーカー差分を吸収するようにすれば 扱いやすくなるはず

最後に

長く書いてしまいましたが, NETCONF には期待しています.

さて, 次回は やってみよう NETCONF です.