tag:blogger.com,1999:blog-3827973235209558306Thu, 24 Sep 2026 11:46:07 +0000Cstatisticsdatabaseruby設計・運用時の注意点commandnetworkprotocolwebconfighardwareosthreaddesign_patternjavascriptrailsclusterwatsonL2-L3L4backuplogmonitorreviewsearchtelephonevirtualizationプログラム テクニック分散処理暗号化GCalgorithmbotcontainerdebugdiskdnseditorldaplibrarylispmobilemqttparserrobotsecuritysignaltoolwindowswireless文字コードBlog Alpha Networkingネットワークとプログラムを扱う技術屋。 Blog では linux 周りの技術を中心に更新。noreply@blogger.com (alpha.netzilla)Blogger157125tag:blogger.com,1999:blog-3827973235209558306.post-6074115069922300433Wed, 05 Apr 2017 14:56:00 +00002017-04-13T02:20:01.916+09:00webChrome extentionを使い、iframe内外でデータ通信<span style="font-size: large;"><b>◆ 目的</b></span><br />
Webページ(親ページ)とそこからiframeで読み込んだ子ページ間でデータの授受を行う。<br />
ただし、iframe内のコンテンツは親ページのドメイン外に存在する任意のサイトとする。<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>◆ 課題</b></span><br />
解決する課題は2つある。<br />
<b>1. クロスドメイン制約への対応</b><br />
XMLHttpRequestを投げる際などにも必ず気に掛ける点だろう。<br />
Same Origin Policy(同一生成元ポリシー)を回避しなければならない。<br />
<br />
今回は任意の外部サイトをiframeに取り込むことを前提としているため、<br />
CORS(Cross-Origin Resource Sharing)もJSONP(JSON with padding)も今回は使えない。<br />
<br />
<b>2. iframe内での読み込み不許可ヘッダへの対応</b><br />
HTTPのレスポンスヘッダに、iframe内からWebページが読み込まれるのを防止するオプション(X-Frame-Options)が付与されていればiframe内で表示はできない。<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>◆ 解決策</b></span><br />
<b>1. postMessageの利用</b><br />
クロスドメイン制約への対応として、HTML5で用意されたpostMessageの利用を思いつく。<br />
<br />
(親サイト)<br />
<pre><iframe id="ifrm" src="外部サイト"></iframe>
<script type="text/javascript">
window.onload = function() {
var ifrm = document.getElementById('ifrm').contentWindow
ifrm.postMessage("hello", '外部サイト')
};
</script></pre>
<br />
(外部サイト)<br />
<pre><script type="text/javascript">
window.addEventListener('message', function(event) {
alert(event.data)
}, false);
</script></pre>
<br />
しかし、Chromeが許可しない。<br />
※Safariでは警告なく、実施できた。<br />
<br />
(エラー例)<br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">Failed to execute 'postMessage' on 'DOMWindow': The target origin provided (';) does not match the recipient window's origin (';).</span><br />
<div>
<div>
<br />
<br /></div>
<div>
<b>2. iframeを使わない</b></div>
<div>
iframeを使う前提を変え、コンテンツをダウンロードし、外部サイトを親側で再現させる。つまり、前提を変える。<br />
が、しかし、JavaScriptが生成する動的ページのリソースの管理は困難があるため、やはり、iframeは使いたい。前提は戻す。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>3. Google Chromeの拡張機能の利用</b></div>
<div>
Chromeに限定されるが、Chromeの拡張機能を使えば対応ができそうである。</div>
<div>
データの共有は、バックグラウンドで動作させるスクリプト内でセッションストレージを使えばいいだろう。</div>
<div>
また、ヘッダの書き換えも実施できる。</div>
<div>
<br /></div>
<div>
<br />
<br /></div>
</div>
<div>
<div>
<span style="font-size: large;"><b>◆ 拡張コード概要</b></span></div>
<div>
chrome拡張を利用することにした。</div>
<div>
拡張コードを有効にするには、最低限以下の3つのファイルを用意し、それらを適当なフォルダに入れ、Chromeブラウザの拡張機能からインポートすれば良い。</div>
<div>
<br /></div>
<div>
<b>○ マニフェスト ファイル</b></div>
<div>
拡張機能に関する情報を与える。</div>
<div>
<br /></div>
<div>
<b>○ コンテンツ スクリプト</b></div>
<div>
ブラウザで表示させるページで読み込むjsとは別空間で実行させるjsである。</div>
<div>
このファイルは親サイトと、iframe内の外部サイト、両方に読み込まれる。</div>
<div>
空間は分かれているため、コンテンツスクリプト内で利用しているjQueryなどのライブラリがサイトで利用しているバージョンと異なっていても問題は起きない。</div>
<div>
<br /></div>
<div>
<b>○ バックグラウンド スクリプト</b></div>
<div>
Chromeのバックエンド側で処理させるjsである。</div>
<div>
表示コンテンツには取り込まれないが、コンテント ファイルとの間でメッセージ通信ができる。</div>
<div>
<br /></div>
<div>
<br />
簡易図で表すと下記のような感じである。</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> parent</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">+----------+</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| |← contentScripts.js</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| iframe | </span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| +----+ |</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| | | |</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| | |←-|-- contentScripts.js</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| +----+ |</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">| |</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">+----------+</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">background.js</span></div>
<div>
<br /></div>
<div>
contentScripts.js、background.jsの名称はmanifest.json内で指定する。</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div>
<span style="font-size: large;"><b>◆ 試験</b></span></div>
<div>
1. iframe内でマウスを操作。マウスオーバしたタグ要素に色がつくようにしている。</div>
<div>
そのタグ要素でクリックすると、タグ名がセッションストレージへ保存される。</div>
<div>
<br /></div>
<div>
2. 親側でiframe外の要素をクリックする。</div>
<div>
iframeで取得した要素がalert表示されれば成功である。</div>
</div>
<div>
<br />
<br /></div>
<div>
<br /></div>
<div>
<span style="font-size: large;"><b>◆ コード例</b></span><br />
<b>○ manifest.json</b><br />
<script src=" />
<br />
<b>○ contentScripts.js</b><br />
<script src=" />
<br />
<b>○ background.js</b><br />
<script src=" />
<br />
<br />
<span style="font-size: large;"><b>◆ コード解説</b></span><br />
1点、解説を加えておく。<br />
contentScript.jsは親子両方に読み込まれるため、共通処理以外のjsコードは、親子用で条件を加えている。<br />
<pre>// iframe用
if (window != parent) {
~snip~
} // 親用
else{
~snip~
}</pre>
<br /></div>
2017/04/chrome.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-7144978178746351357Sat, 04 Mar 2017 05:36:00 +00002017-03-09T00:06:16.948+09:00botChatHub(LINE上で動作する、Q&Aを中心としたSNSサービス)<br />
LINE上で動作する、お互いに顔までは知らない関係の、身近なコミュニティ内で、匿名のまま情報交換ができるQ&Aを中心としたSNSサービス、ChatHubを作成した。最近はやりのbotの一つである。<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="; imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="; width="640" /></a></div>
<br />
<span id="goog_454594896"></span><span id="goog_454594897"></span><br />
<br />
※内部でAI的な要素を使ったおもしろい仕組みを導入している。<br />
技術詳細に関しては随時公開予定。<br />
<br />
<br />
<br />2017/03/chathub.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-8969255122037891566Tue, 10 Jan 2017 11:51:00 +00002017-10-14T15:07:45.974+09:00CCのselect、epollを使ったI/O多重化<br />
複数のファイルディスクリプタを監視し、その中のいずれが入出力可能な状態であるかを確認するCのシステムコールとしては、select、epoll、kqueue(BSD系)が有名だろう。<br />
ここでは、selectとepollを使い、1プロセス1スレッドでのイベント駆動によるI/O多重化コードを備忘録として残しておく。<br />
<br />
(参考)<br />
最近ではselectではなく、epoll、kqueueが使われることが多い。<br />
selectは待ち受けられるファイルディスクリプタの数に上限があり、またパフォーマンス問題も存在するためである。<br />
I/Oからの入力に応じて発生するイベントを処理するライブラリとしてはlibevent, libev, libuvなどがあるがこの内部でもepollやkqueueが利用されている。<br />
※libevはlibeventの速度改善、FDの制限撤廃の対応がされた改良版である。<br />
※libuvはnode.js用のためにlibevをベースに開発されたライブラリである。<br />
<br />
<br />
<br />
(select.c)<br />
<script src=" />
<br />
(epoll.c)<br />
<script src=" />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>$ gcc ファイル名</b></span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>$ ./a.out /dev/tty /dev/input/mouse0 10</b></span><br />
<span style="color: #741b47; font-family: "courier new" , "courier" , monospace;">hello</span><br />
<span style="color: #741b47; font-family: "courier new" , "courier" , monospace;">/dev/tty: hello</span><br />
<span style="color: #741b47; font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="color: #741b47; font-family: "courier new" , "courier" , monospace;">no input after 10 seconds</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br />
</span> <span style="font-family: "courier new" , "courier" , monospace;">マウス操作</span><br />
<span style="color: #741b47; font-family: "courier new" , "courier" , monospace;">/dev/input/mouse0: (</span><br />
<div>
<br />
<br />
(補足)<br />
readで指定したバッファサイズ以上のデータがあった場合、ループでepoll_waitの処理へ戻るとはどのような動作をするか分かるだろうか。<br />
残りのデータを引き続き読み込めると判断されるた、待ち状態にはならない。<br />
しかし、次のようにイベント条件を指定した場合は一度しかイベントは発火しない。<br />
<span style="font-family: Courier New, Courier, monospace;">ev.events = EPOLLIN | EPOLLONESHOT</span><br />
<br />
イベントを継続させる場合には、再度epoll_ctlを同じepfdとEPOLL_CTL_MOD値を渡して呼べばよい。<br />
<span style="font-family: Courier New, Courier, monospace;">epoll_ctl(epfd, EPOLL_CTL_MOD, fd1, &ev)</span><br />
<br /></div>
2017/01/io-multiplexing.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-6528325107461908132Fri, 06 Jan 2017 02:47:00 +00002021-06-28T15:48:35.398+09:00algorithmrubyRubyで深さ優先探索(DFS)と幅優先探索(BFS)グラフ操作の基本、深さ優先探索(DFS: Depth First Search)と幅優先探索(BFS: Breadth First Search)のアルゴリズムをRubyで書く。<br />
<br />
<div><br />
</div><div>◆ DFS</div><div><script src=" />
<br />
</div><div>◆ BFS</div><script src=" />
2017/01/graph-traversal.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-4370935211092556195Sun, 25 Sep 2016 14:39:00 +00002023-04-29T08:51:48.918+09:00日本語文字列の自然なソート手元にあった海外製のJavaで書かれたソフトで日本語の文字列をソートすると、<br />
漢字部分が無秩序、訳わからない並びになった。<br />
Unicodeの並びに沿わせていないからであろうか?<br />
<br />
※JavaはUnicodeの文字コードでUTF-16の符号化方式である。<br />
つまり、StringクラスはUTF-16形式で扱うわけである。<br />
char型は符号なし16ビット整数である。Characterクラスはこのラッパ。<br />
<br />
<span style="color: #990000;">【参考:一般的な文字コード(文字集合)と符号化方式】</span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> -文字コード- -符号化(エンコード)方式-</span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> JIS X 0201 8bit符号</span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> 7bit符号</span><br />
<span style="color: #990000;"><span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;"> JIS X 0208 EUC-JP</span></span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> ISO-2022-JP</span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> Shift_JIS</span><br />
<span style="color: #990000;"><span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;"> Unicode UTF-16</span></span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> UTF-32</span><br />
<span style="color: #990000; font-family: "courier new" , "courier" , monospace;"> UTF-8</span><br />
<br />
<br />
しかし、ASCII部分、ひらがな、カタカナ、は問題なく、Unicodeに沿っているように見える。なぜ漢字にだけ違和感を感じるのだろうか。<br />
少し調べたところ、Unicodeの漢字は部首順に並べられているようである。規則性を感じなかったのはそのためである。部首単位でまとまるためそれが統一性を感じることも逆にあるだろうが。<br />
<br />
国や言語固有の文化を反映した自然だと思われる並びにするにはJavaであれば<a href="; target="_blank">java.text.Collator</a>クラスを使うと解決することが分かった。日本語に限らず、他言語にも対応している。英語圏発のソフトウェアはこのあたりへ考え及ばせること難しいかもしれないが考慮入れていただきたい点の一つである。<br />
<div>
<br />
<br />
<br />
<b>(脱線1)</b><br />
文字列比較をする際にはCollator#compare()メソッドを使えばいいが、繰り返しソートする場合は性能面から<a href="; target="_blank">CollationKey</a>を利用したビット単位比較をさせた方がいい。<br />
<br />
<b>(</b><b>脱線</b><b>2)</b><br />
Javaと文字列の話ついでに、もう一つ。<br />
charの単位は1文字ではない。適切な区切りを得るためにはBreakIteratorクラスあたりを使うこと。<br />
<br />
なぜかというと、UTF-16はBMP(Basic Multilingual Plane)以外の面の文字を表すためにサロゲートペア(surrogate pair)や、あと複数のパーツで1文字を表現する結合文字を存在しているからである。濁点、半濁点との結合などである。<br />
<br />
<b>(</b><b>脱線3</b><b>)</b><br />
Rubyの1.8系までは少しおもしろい取り組みをしている。<br />
<br />
JavaやPythonなどはシステムの内部コードをUnicodeの文字コードに統一するUCS(Universal Code Set)方式を取っている。そのためUnicodeに含まれない文字を扱いたければ、ライブラリを使うか、自力でchar単位で処理するしかない。Unicodeだけで問題あるのかというと、このセットに含まれない文字は実は結構あるらしい。<br />
<br />
一方、Ruby1.8系までは8bitの列に符号化方式の情報をセットにしたものを文字列だと定義する、CSI(Code Set Independent)方式を採用している。文字コードはUnicodeではなく、ただのバイナリでしかない。どのような文字コードでも直接保存できるが、実装、最適化あたりの処理は複雑にならざるを得ないだろうと容易に想像できる。<br />
ちなみに、Ruby1.9系以降のディフォルトのエンコーディング方式はUTF-8である。<br />
<div>
<br /></div>
<div>
<br /></div>
〜参考〜<br />
<a href="; target="_blank"> />
<a href="; target="_blank"> />
<a href="; target="_blank"> />
<br />
<br />
<br />
<br /></div>
2016/09/sort.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-2483657485036648308Wed, 24 Aug 2016 04:53:00 +00002016-09-28T02:37:07.431+09:00mqttMQTT理解(publisher/subscriber: ruby利用、broker: Bluemixサービス)<br />
<span style="font-size: large;"><b>◆ 目的</b></span><br />
IoTやM2Mで使われるpublisherとsubscriberモデルの軽量なメッセージプロトコルであるMQTTの動作をrubyクライアントを使い確認する。rubyのmqttライブラリは<a href="; target="_blank">こちら</a>を使う。<br />
<br />
brokerとなるサーバは構築の手間を省くため、IBM Bluemix上にあるサービス、<a href="; target="_blank">Internet of Things Platform</a> を利用する。<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>◆ publisher接続仕様</b></span><br />
IBMが提供するIoTのbrokerの作法の詳細は<a href="; target="_blank">こちら</a>。<br />
以下ではコードを書く上で必要なところを抽出してまとめる。<br />
<div>
<br /></div>
(フォーマット)<br />
<span style="font-family: "courier new" , "courier" , monospace;">● 認証(ユーザ) : use-token-auth(固定値)</span><br />
<span style="font-family: "courier new", courier, monospace;"> (パスワード) : デバイス登録時に払い出されるトークン</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">● Client ID : d:{org_id}:{device_type}:{device_id}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">● Topic(event) : iot-2/evt/{event_id}/fmt/{format}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> (command) : iot-2/cmd/{command_id}/fmt/{format}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> 今回はeventトピック(commandではない)のフォーマットを利用する</span><br />
<br />
{}の各変数はそれぞれ以下の意味である。<br />
<span style="font-family: "courier new" , "courier" , monospace;">org_id : brokerが払い出し(接続先エンドポイントのURIに付与される)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">device_type : 任意のものを作成</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ここではラズベリーパイを使うことを想定しraspiとする</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">device_id : デバイス単位で固有の値を任意に作成</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">event_id : 任意のものを作成(ここではtype01とする)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">command_id : 任意のものを作成</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">format : jsonとする</span><br />
<br />
下記変数部分は文字列ワイルドカード文字(+)を使用することができる。<br />
device_type、device_id、event_id、format<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>◆ subscriber接続仕様</b></span><br />
(フォーマット)<br />
<span style="font-family: "courier new" , "courier" , monospace;">● 認証(ユーザ) : APIキー(broker管理画面で作成)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> (パスワード) : APIトークン(broker管理画面で作成)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">● Client ID : a:{org_id}:{app_id}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">● Topic(event) : <span style="font-size: x-small;">iot-2/type/{device_type}/id/{device_id}/evt/{event_id}/fmt/{format}</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> (command) : <span style="font-size: x-small;">iot-2/type/{device_type}/id/{device_id}/cmd/{command_id}/fmt/{format}</span></span><br />
<br />
{}の各変数はそれぞれ以下の意味である。<br />
<span style="font-family: "courier new" , "courier" , monospace;">app_id : 任意のものを作成(ここではapp01とする)</span><br />
<br />
下記変数部分は文字列ワイルドカード文字(+)を使用することができる。<br />
device_type、device_id、cmd_id、format<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>◆ publisherコード</b></span><br />
<script src=" />
<br />
<br />
<span style="font-size: large;"><b>◆ subscriberコード</b></span><br />
<script src=" />
<br />
<br />
<span style="font-size: large;"><b>◆ 試験</b></span><br />
1. <br />
<span style="color: blue;">$ ./subscriber.rb</span><br />
待ち<br />
<br />
2.<br />
<span style="color: blue;">$ ./publisher.rb</span><br />
<br />
3.<br />
subscriber.rbのプロンプトへ以下が出力される。<br />
<span style="color: #b45f06; font-family: "courier new" , "courier" , monospace;">"iot-2/type/android/id/12345/evt/type01/fmt/json"</span><br />
<span style="color: #b45f06; font-family: "courier new" , "courier" , monospace;">"{\"d\":{\"test_data\":10}}"</span><br />
<br />
<br />
<br />2016/08/mqtt.htmlnoreply@blogger.com (alpha.netzilla)tag:blogger.com,1999:blog-3827973235209558306.post-3968764920667127894Mon, 09 May 2016 14:04:00 +00002016-05-23T10:09:30.317+09:00ldapOpenLDAPを利用したディレクトリサーバの構築(OLC対応版)<br />
OpenLDAP2.4系がOLC(On-Line Configuration)を利用する設定方式に変わっている。<br />
その仕様にあわせたサーバの構築手順(Red Hat 7、CentOS 7 用)をまとめておく。<br />
<br />
-目次-<br />
【設計・簡易構成案】<br />
【インストールから設定】<br />
【試験ユーザの登録】<br />
【TLS(SSL)化】<br />
【その他、設定検討事項項目】<br />
<div>
<br /></div>
<div>
<br /></div>
<br />
<span style="font-size: large;"><b>【設計・簡易構成案】</b></span><br />
今回、模擬的に作成するツリー構成は以下とする。<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">dc=jp</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> dc=example</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=root ・・・特権アカウント</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ou=managers ・・・管理アカウントディレクトリ</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=readmgr</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=writemgr</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ou=users ・・・ユーザディレクトリ</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=user1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=user2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ou=groups ・・・グループディレクトリ</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=group1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cn=group2</span><br />
<br />
<br />
dc(domain component)としてjp, exampleを上位に配置する。<br />
その配下に全権限をもたせたrootアカウントを作成し、<br />
また各種ou(organization unit)を並行に配置する。<br />
<br />
managersでは役割に特化した(権限を絞った)管理者アカウントを作成する。<br />
具体的には、users、groupsディレクトリ配下を参照、または更新ができるアカウントをそれぞれ用意する。<br />
<br />
利用者アカウントの管理はusersの下で行う。ここで各ユーザが追加、削除、参照される。<br />
オブジェクトクラスはinetOrgPersonを利用する。<br />
<br />
各アカウントが所属する組織はgroups下で作成し、ユーザを各グループへmemberとして登録する。<br />
オブジェクトクラスはgroupOfNamesを利用する。<br />
<br />
<br />
~補足~<br />
(オブジェクトクラスの決め方)<br />
今回ユーザの管理にinetOrgPersonというオブジェクトクラスを選んだ。<br />
ただし、用途次第で最適なオブジェクトクラスは異なるため慎重に選択するべきである。<br />
<br />
例えば今回はユーザの属性の一つとして、メールアドレスを登録させることを想定したため、inetOrgPersonを選んだ。<br />
mail属性をディフォルトの補足属性としてもっているためである。<br />
<br />
オブジェクトクラスの属性を調べるにはこのあたりのファイルを開けばよい。<br />
/etc/openldap/schema/*.schema<br />
<br />
<br />
ユーザ管理であってもサーバのログインアカウントなどでであればposixAccountの方がいいかもしれない。<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> DESC 'Abstraction of an account with POSIX attributes'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> SUP top AUXILIARY</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MAY ( userPassword $ loginShell $ gecos $ description ) )</span><br />
<br />
<br />
またそれにあわせてグループもposixGroupの方がいいだろう。<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> DESC 'Abstraction of a group of accounts'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> SUP top STRUCTURAL</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MUST ( cn $ gidNumber )</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MAY ( userPassword $ memberUid $ description ) )</span><br />
<br />
※オブジェクトクラスは継承環境があるため、上位クラス(SUP)の必須、補足属性の定義にも影響される。<br />
<br />
<br />
(ツリーの構成)<br />
ツリーの設計として、グループの下にユーザディレクトリを掘っていくような案も考えられる。<br />
広さよりも、深さをより優先する設計という意味である。<br />
深さ優先のメリットとしては、検索のベースを下げられ、ロック粒度を下げられる点があるだろう。<br />
しかし、グループ属性が流動的であれば、そことディレクトリを共有し密に紐づくユーザの管理が煩雑になるデメリットもある。<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>【インストールから設定】</b></span><br />
<b>● パッケージのインストール</b><br />
<span style="color: #0b5394; font-family: "courier new" , "courier" , monospace;">$ sudo yum install openldap-servers openldap-clients</span><br />
<br />
<br />
<b>● 初期設定</b><br />
DB設定はサンプル例を利用する。<br />
<span style="color: #0b5394; font-family: "courier new" , "courier" , monospace;">$ sudo cp -iv /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG</span><br />
<br /&g