2014年06月03日

TR-069 - GenieACS で始める Auto Configuration Server

ネットワーク上に存在する端末、そう例えば今貴方が手にしている端末を IT 事業者が管理したいと考えたらどうすれば良いでしょうか? その仕組みの1つが TR-069 (Technical Report 069) と呼ばれる北米 Broadband Forum を中心に標準化が行われている規格です。 TR-069 では端末管理を行うサーバーを ACS と呼ぶのですが今日は今最もアクティブなオープンソースの ACS サーバー、GenieACS を紹介します。
 
cooltext1588454754

TR-069 の概要とオープンソース ACS の現状


時代の変化と共にインターネットとそれを利用する IP デバイスの関係はより複雑になっています。 例えば教育現場ではタブレット・デバイスと電子コンテンツを使った授業が評価されはじめ、ホームネットワークを見ても全てのデバイスが IP 化されようとしています。 これら末端のデバイスが正常に動作しているか、ファームウェアは常に最新の状態になっているかを管理・監視するのは大変難しい作業です。 複雑、大規模化する情報と運用管理、さらに末端のデバイス(端末)が直接通信出来ないファイヤーウォールや NAT の内側に隠れている場合もあるからです。

これらの課題に対するソリューションの1つが TR-069 及びその関連規格で標準化が進められている CWMP (CPE WAN Management Protocol) と呼ばれる仕組みです。 
 
cwmp_network

TR-069 では末端にある顧客側デバイスを CPE (Customer Premises Equipment) 、それを一元管理するサーバーを ACS (Auto Configuration Server) と呼び、両者は SOAP、つまり XML メッセージをペイロードとした HTTP トラフィックを交換しながらプロセス/サービス間でのコミュニケーションを実現しています。 NAT 問題に関しても PERIODIC と呼ばれる CPE から ACS への定期的なイベント通信を組み合わせる事で一定の管理が可能になっています(定期的な通信以外に STUN を組み合わせる方式も規格化されていますが、実際の運用例は少ないようです)。

今日ここで CWMP の詳しい話をするには僕の知識もスペースも足りないのですが、この TR-069/CWMP クライアントを調べると比較的簡単にオープンなコードが見つかります。 一方 ACS となると OpenACS 以外である程度の実績があるプロダクトは見つからないというのがここ最近の状況でした(同じ名前のプロジェクトがあるので注意して下さいね)。

OpenACS は Java + JBoss/Tomcat + EJB/MySQL で構成され、固有のビジネス・ロジックは JavaScript を使って定義出来るというユニークなアプリケーション。 仮想マシンのイメージも配布されておりすぐに試すことも可能なんですが、ここ数年は開発活動がほぼ停止しているところが気になります。 他のオープンソース ACS プロダクトもほぼ同様の状況で悩ましい。

そんな寂しい状況の中、彗星のごとく現れたのが今日紹介する GenieACS なんです。

GenieACS


GenieACS が面白いのは上位システム側 API (North Bound Interface)、CWMP インタフェース (South Bound Interface)、UI アプリケーションがそれぞれ分離・モジュール化されているところ。

TR-069 End-to-End アーキテクチャ

NBI の RESTful な API だけを使ってユーザ・インタフェースは独自に実装する、ということも可能なんです。 

ミドルウェアには Node.js, MongoDB, Redis, Ruby On Rails を採用(クールですけど少し気後れしますね・・・)。


GenieACS のセットアップ


百聞は一見にしかず。 ここでは OS に CentOS 6.5 を使い GenieACS を構築してみます。

[root@genie ~]# cat /etc/redhat-release
CentOS release 6.5 (Final)

[root@genie ~]# uname -a
Linux genie 2.6.32-431.17.1.el6.i686 #1 SMP Wed May 7 20:52:21 UTC 2014 i686 i686 i386 GNU/Linux


まずは Ruby 実行環境と Rasis をインストール。 必要なパッケージと YAML を先にインストールして、

[root@genie ~]# yum -y install gcc openssl-devel zlib-devel readline-devel sqlite-devel

[root@genie ~]# wget http://pyyaml.org/download/libyaml/yaml-0.1.6.tar.gz
[root@genie ~]# tar xvzf yaml-0.1.6.tar.gz
[root@genie yaml-0.1.6]# ./configure
[root@genie yaml-0.1.6]# make && make install

ソースコードから Ruby をビルド。

[root@genie ~]# wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz
[root@genie ~]# tar xvzf ruby-2.1.2.tar.gz
[root@genie ruby-2.1.2]# ./configure
[root@genie ruby-2.1.2]# make && make install

[root@genie ruby-2.1.2]# ruby  -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [i686-linux

Rails と bundle をインストールしたらおしまい。 ちなみに Ruby, Rails は UI アプリケーションの実行環境で独自に UI 開発する場合は必要ありません。

[root@genie ~]# gem install rails --no-ri --no-rdoc
[root@genie ~]# gem install bundle --no-ri --no-rdoc


Node.js 実行環境もソースコードからビルド及びインストール。

[root@genie ~]# wget http://nodejs.org/dist/v0.10.28/node-v0.10.28.tar.gz
[root@genie ~]# tar xvzf node-v0.10.28.tar.gz

[root@genie node-v0.10.28]# yum -y install g++
[root@genie node-v0.10.28]# ./configure
[root@genie node-v0.10.28]# make && make install

[root@genie node-v0.10.28]# node -v
v0.10.28


続いてストレージ系のセットアップ。 まずはキャッシュに利用する Redis。

[root@genie ~]# wget http://download.redis.io/releases/redis-2.8.9.tar.gz
[root@genie ~]# tar xvzf redis-2.8.9.tar.gz

[root@genie redis-2.8.9]# yum -y install tcl
[root@genie redis-2.8.9]# make
[root@genie redis-2.8.9]# make test

\o/ All tests passed without errors!

Cleanup: may take some time... OK

[root@genie redis-2.8.9]# make install

# start redis server.
[root@genie redis-2.8.9]# redis-server


データベースは MongoDB。 登録された CPE(CWMP クライアント)の情報やアップロードしたファームウェア・ファイルなどは MongoDB に保存されます。

[root@genie ~]# wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.4.10.tgz
[root@genie ~]# tar xvzf mongodb-linux-i686-2.4.10.tgz
[root@genie ~]# mkdir -p /data/db

# start MongoDB server. shutdown: ./bin/mongod --shutdown
[root@genie mongodb-linux-i686-2.4.10]# ./bin/mongod --fork --syslog
Fri May 30 21:15:37.394
Fri May 30 21:15:37.395
about to fork child process, waiting until server is ready for connections.
forked process: 20880
using syslog ident: mongod.27017
child process started successfully, parent exiting


後もう少し。 次の手順で GenieACS エンジンと Web UI をインストール。

# install GenieACS Core(North Bound Interface, CWMP Interface, File Server)
[root@genie opt]# yum -y install git
[root@genie opt]# git clone https://github.com/zaidka/genieacs.git
[root@genie opt]# cd genieacs/
[root@genie genieacs]# npm install
[root@genie genieacs]# npm run configure
[root@genie genieacs]# npm run compile

# install Web UI
[root@genie opt]# git clone https://github.com/zaidka/genieacs-gui
[root@genie opt]# cd genieacs-gui/
[root@genie genieacs-gui]# bundle


初期動作設定は /opt/genieacs-gui/config 配下にあるサンプルをリネームして使いましょう。

[root@genie config]# cp index_parameters-sample.yml index_parameters.yml
[root@genie config]# cp parameter_renderers-sample.yml parameter_renderers.yml
[root@genie config]# cp parameters_edit-sample.yml parameters_edit.yml
[root@genie config]# cp roles-sample.yml roles.yml
[root@genie config]# cp summary_parameters-sample.yml summary_parameters.yml
[root@genie config]# cp users-sample.yml users.yml
[root@genie config]# cp graphs-sample.json.erb graphs.json.erb


最後に GenieACS サービスを起動。

# start North Bound/RESTful Interface service.
[root@genie ~]# /opt/genieacs/bin/genieacs-nbi
30 May 17:39:19 - Worker 26283 listening to 0.0.0.0:7557
30 May 17:39:19 - Worker 26284 listening to 0.0.0.0:7557

# start ACS/CWMP service.
[root@genie ~]# /opt/genieacs/bin/genieacs-cwmp
30 May 17:36:49 - Worker 26233 listening to 0.0.0.0:7547 # HTTP
30 May 17:36:49 - Worker 26233 listening to 0.0.0.0:7548 # HTTPS

# start HTTP/File streaming service.
[root@genie ~]# /opt/genieacs/bin/genieacs-fs
2 Jun 16:00:02 - Worker 13083 listening to 0.0.0.0:7567
2 Jun 16:00:02 - Worker 13084 listening to 0.0.0.0:7567

# start GenieACS/Web UI
[root@genie ~]# cd /opt/genieacs-gui/
[root@genie genieacs-gui]# rails server
=> Booting WEBrick
=> Rails 4.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server


GenieACS ファースト・インプレッション


全てのサービスを起動したらブラウザで次の URL にアクセスしてみましょう。

http://[Your GenieACS Host]:3000

お、トップ画面が表示されました。

genieacs_web_top


users.yml に定義されている admin/admin でログインすると Home, Devices, Faults, Presets, Object, Files 計5つメニューが現れます。
 
genieacs_top_menu

これだけではよくわかりませんね。 実際に ACS へ CWMP メッセージを送信し、CPE を登録してみましょう。 まず次のような SOAP メッセージ(XML ファイル)を用意します。
 
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
    <SOAP-ENV:Header>
      <cwmp:ID SOAP-ENV:mustUnderstand="1">0000000001</cwmp:ID>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
      <cwmp:Inform>
        <DeviceId>
          <Manufacturer>NETBUFFALO</Manufacturer>
          <OUI>0055ee</OUI>
          <ProductClass>N5000</ProductClass>
          <SerialNumber>sn1234567890</SerialNumber>
        </DeviceId>
        <Event SOAP-ENC:arrayType="cwmp:EventStruct[2]">
          <EventStruct>
            <EventCode>0 BOOTSTRAP</EventCode>
            <CommandKey></CommandKey>
          </EventStruct>
          <EventStruct>
            <EventCode>1 BOOT</EventCode>
            <CommandKey></CommandKey>
          </EventStruct>
        </Event>
        <MaxEnvelopes>1</MaxEnvelopes>
        <CurrentTime>2014-05-30T23:17:08Z</CurrentTime>
        <RetryCount>0</RetryCount>
        <ParameterList SOAP-ENC:arrayType="cwmp:ParameterValueStruct[0007]">
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceSummary</Name>
              <Value xsi:type="xsd:string">CWMP client device.</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.ManagementServer.ParameterKey</Name>
              <Value xsi:type="xsd:string"></Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.ManagementServer.ConnectionRequestURL</Name>
              <Value xsi:type="xsd:string">http://200.100.100.1:3000/cleint/cwmp/</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress</Name>
              <Value xsi:type="xsd:string">200.100.100.1</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress</Name>
               <Value xsi:type="xsd:string">00:55:ee:00:00:01</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceInfo.HardwareVersion</Name>
              <Value xsi:type="xsd:string">HW.1.00</Value>
            </ParameterValueStruct>
            <ParameterValueStruct>
              <Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name>
              <Value xsi:type="xsd:string">1.00.00</Value>
            </ParameterValueStruct>
        </ParameterList>
      </cwmp:Inform>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

この Inform と呼ばれるメッセージにはイベント・コードとして工場出荷又はリセット後初めての起動である 0 BOOTSTRAP 及び 機器の起動を表す 1 BOOT イベントが含まれており、 ACS からすると”初めての登録”に相当するデバイスからメッセージを受信したことになります。

パラメータのより詳しい説明は Technical Reports 又は Data Model Definitions をどうぞ。

このメッセージを informBootsBoot.xml とう名前で保存し、 POST コマンドを使って ACS へ HTTP POST してみましょう。
(CPE から ACS へのメッセージ送信は POST を利用するという決まりがあります)

linux $ POST -ec 'text/xml' http://[Your GenieACS Host]:7547  < ./informBootsBoot.xml

200 OK
Connection: keep-alive
Date: Mon, 02 Jun 2014 07:12:20 GMT
Server: GenieACS/0.9.9
Content-Length: 566
Content-Type: text/xml; charset="utf-8"
Client-Date: Mon, 02 Jun 2014 07:12:09 GMT
Client-Peer: x.x.x.x:7547
Client-Response-Num: 1
Set-Cookie: ZGV2aWNlSWQ=MDA1NWVlLU41MDAwLXNuMTIzNDU2Nzg5MA
Set-Cookie: Y3dtcFZlcnNpb24=MS4w
SOAPServer: GenieACS/0.9.9

<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope 
  xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cwmp="urn:dslforum-org:cwmp-1-0">
  <soap-env:Header>
    <cwmp:ID soap-env:mustUnderstand="1">0000000001</cwmp:ID>
  </soap-env:Header>
  <soap-env:Body>
    <cwmp:InformResponse>
      <MaxEnvelopes>1</MaxEnvelopes>
    </cwmp:InformResponse>
  </soap-env:Body>
</soap-env:Envelope>
 
ACS から InformResponse が届きましたね。 

本来であれば、この後 empty と呼ばれる ContentLength が 0 (HTTPヘッダーのみ)のメッセージのやり取りが行われた場合に1つのトランザクションが成立・終了します。 また、次のように empty リクエストに対して新たなリモート・メソッドの呼び出しが発生することもあります。

TR-069 Session Example

さあ、GenieACS に CPE は登録されたでしょうか。

genieacs_cpe_registered


お、登録されたみたい。 Device 情報を見ると送信したデバイスのプロファイルが登録され、GenieACS から端末をコントロールすることも可能になります。

genieacs_device_details


この他にも利用頻度の高い、Firmware イメージの管理及び CPE への配信にも対応しています(実際には試してないですけどコードを見た限り動きそうでしたよ)。

genieacs_firmware_upgrade_image

利用ポート、バインド・アドレスなどの設定は config.json で。

[root@genie ~]# cat /opt/genieacs/config/config.json
{
  "DATABASE_NAME" : "genieacs",
  "MONGODB_SOCKET" : "/tmp/mongodb-27017.sock",
  "REDIS_SOCKET" : "6379",
  "ACS_INTERFACE" : "0.0.0.0",
  "ACS_PORT" : 7547,
  "ACS_HTTPS_INTERFACE" : "0.0.0.0",
  "ACS_HTTPS_PORT" : 7548,
  "API_INTERFACE" : "0.0.0.0",
  "API_PORT" : 7557,
  "FILES_INTERFACE" : "0.0.0.0",
  "FILES_PORT" : 7567,
  "FILES_IP" : "192.168.0.1",
  "LOG_INFORMS" : true,
  "DEBUG_DEVICES" : {}
}


TR-069 では SSL, TLS による暗号化及び Basic, Digest 方式による認証も求められますから、このあたりの実装状況も気になるのですが、少なくとも今最も気になる・アクティブなオープンソース ACS という点には間違いなさそうです。

Redis入門 インメモリKVSによる高速データ管理 (アスキー書籍)
KADOKAWA / アスキー・メディアワークス (2014-01-16)
売り上げランキング: 23,654

はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-
松島 浩道
ソフトバンククリエイティブ
売り上げランキング: 8,716

Posted by netbuffalo at 22:00│Comments(0)TrackBack(0)ネットワーク | ユーティリティ


この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/netbuffalo/4794185

コメントする

名前
URL
 
  絵文字