水曜日, 12月 20, 2017

邪悪なxonsh(の予定だったんだけどなぁ・・・)

Xonshを邪悪に使おうとしたが失敗した話から

beepcap

2017/12/20

はじめに

10日ぶりである。
この記事はXonsh Advent Calendar 2017の20日目だ。


Xonshに対する解説は他の人がたくさん書いているので、 この記事では邪悪な使い方を書こうと思っていた。 まず僕の用途だとXonshはとてもいいものだけど、 ちょっとまだ実用に至ってない。 zshのほうがちょっとだけ便利だ。 補間の学習具合や、historyに溜め込んだコマンドの記録が僕を拘束する。 historyを移植してやろうと思ったが、Xonshの履歴はちょっとばかし 扱いがめんどくさかったんでやめた。 そんなわけで気合が入らないなか、試してみたことの 記録を展開していこうと思う。 なお、この記事はXonsh 0.5.12をベースに書いている。 もしも改善されていたり、間違っていたらどんどん指摘してくれ。 Twitterの@beepcapで待ってるぞ。

最初の不満は

最初の不満はリダイレクトにあった。 Xonshはその性質上Pythonで書いた関数をシェル上で利用できるが、 これをシェルの中の人に渡すにはaliasを使わねばならず、 そうすると折角関数で作ったのに引数が使えずという苦しみが出てくるのだ。 もちろん、そこはこう・・・パラメータを与えてやればいい

$ echo 'hogehoge' | fuga > out.txt

・・・・・・ いやいや正気か? どう考えてもこうやりたい[*]

$ fuga('hogehoge') > out.txt

そこで考えた。 「aliasを使うから引数を付けられないのである」 「!そうだaliasなしでリダイレクト制御すればよくね!?」 Pythonのコードをこうすれば、>を再現することが出来る。

class fuga:
  gtxt = ""
  def __init__(self, in_t):
    fuga.gtxt = in_t
  def __gt__(self, other):
    f = open(other, "w")
    f.write(fuga.gtxt)
    f.close()

$ fuga("hogehoge") > "out.txt"

Oh!Yes!!!
ほんのちょっとばかし"が増えてしまったが、 おおよそ思い通りではないか?!・・・・・・ ・・・うん。そうなんだ。 Pythonは文字列を扱うときには""が必須で、これを外せなかったんだ・・・ 悲しい。 挫折した。 [*]aliasを使う方法に対するメリットがあるとすれば、渡されるオブジェクトが ファイル名でなくても良いという点だろうか。 例えば、


$ fuga("hogehoge") > "twitter"

こういう使い方も考えられるわけだ。 ツイートするのが簡単になる。 [*]
がまぁ、テキストの指定がダサいので失敗とする。

xonshの秘密をあかしてやろうとしたんだが・・・

xonshを今回いじるにあたって、自分に一つのルールを課した。 それは、「ソースコードを見ない」ということである。 我々は開発者であり、しかもxonshを喜んで扱うような人間であるからして Pythonには詳しい[*]。 その我々がソースコードを見ながらhackすれば、そりゃ何でも出来てしまうはずだ。 あくまでも、プロプライエタリ・ソフトウェアに対するように、 ユーザに開示されている情報のみで解析しなければ、面白くないだろう。

そんなわけでxonshをポチポチ遊んでいたのだが、 Twitterでばんくし(@vaaaaanquish)と会話している時に こんな発見があった。

Xonshは色々と強力だが、長くつけっぱなしで使用していると ゴミが多くなってくる。 これはzshなども同じはずなのだが、あいつらはそれが見えないので なんとなく気にされてない。 しかしXonshはPythonなので、dir()を呼べば一覧が出てくる。 もちろんdelで解放することも出来る・・・はずだった。


$ for i in dir():
    del i

このコードを実行してみてほしい。 バージョンによってコードは予想外の動きをする。 例えば私の手元の0.5.12では、「何も起こらない」。 意味が分かるだろうか? dir()内の要素が消せないのだ。 ところがどっこい、例えば


$ del __name__

では、ちゃんとname要素が消えてなくなるのである。 どうもbuiltinsを消そうとするとなにか強制力が働いて、 処理が中断されるようなのだ。 実際、dir()を使った解放コードはある時まで [*]Xonshの本体を巻き込んで死亡していた。

このbuiltins、何か秘密が隠れているに違いない。

調査のために、以下のように確認してみる。 [*]


$ dir(__builtins__)

ふむふむ、ちょっと中身は違うが標準的なbuiltinsの要素を含んでいそうだ・・・ オブジェクトの名前でも確認してやろうかな・・・


$ print(__builtins__.__name__)

AttributeError: 'dict' object has no attribute '__name__'

は?

え?いやいや、オブジェクトならそれが引けないって致命的でしょ・・・

ちょっとまて、あ、手が滑った


$ print(__builtins__)

'__name__': 'builtins', '__doc__': "Built-in functions,
 exceptions, and other objects.\n\nNoteworthy: None is the `nil' object;
 Ellipsis represents `...' in slices.", '__package__': ”, '__loader__':
 <class '_frozen_importlib.BuiltinImpor
...略
 

お、おい・・・お前これ・・・ dictじゃねーか!!!!!!!!!!!!!!!!!!!

そう、そういうことなのだ。 Xonshはbuiltinsの中身をまるごと置き換えていたのだ。 しかも、built-inモジュールではなく、辞書型のオブジェクトとして。 この中身は大変面白いので、みんなもぜひいじってみてほしい。 例えば、


$ __builtins__['testtxt'] = "test text."
$ testtxt
'test text.'

といった感じである。 aliasなどの定義もこの中にある。

が、時間不足でこの遊びも失敗した。 subprocessを利用している処理を一部置き換えることには成功したのだが、 まだ、根幹の定義済み命令を置き換えると、xonshがハングアップしてしまう。 [*]これでは大して悪いことに使えない。

ということで、失敗である。

イカロスの翼

神話の時代にイカロスは翼を作って飛び立ったが、 太陽の熱に焼かれて翼が壊れ、落下して死んだそうだ。 あれから得られる教訓は、「パワーが足りない」である。 なぜロケット推進にしなかったのか。

そんなわけで、xonshでも処理するにパワーが足りない時がある。 パワーといえばマルチプロセスだ!!! しかし、bashやzshのように、pipeでつなげばプロセスが起きたり、 xargsを使った今流行りのhackも使えない。 Pythonにはmultiprocessing()があるが、 CPythonがベースのxonshではGILがある。 性能への影響がどの程度とかそういうの関係なく嫌だ。 Cとの結合をしようとしたらGILが働く設計にしとけばよかったじゃんか [*]

ということで、os.fork()を使うことにした。

fork()を使用したマルチプロセス化の問題点として fork()は子と親でメモリ以外の資源を共有する、という点が挙げられる。 例えばxonshで


$ import os
$ os.fork()

とやると、とんでもないことになる。 入出力が多重化し、まともに入力を受け付けなくなるだけではなく、 表示も二重に出て、有り体に言えばバグる。 [*]そして、親プロセスを終わらせたが最後、ゾンビと化した子供は エラーを吐き続けターミナルを埋め尽くすのである。

何が悪いのか。 xonshはターミナルの上で動くCUIプログラムなので、 ターミナルソフトとの通信には当然、stdin, stdoutを利用している。 fork()するということは、これらを複数のプロセスで共有してしまうことになる。

ここで、経験の多い人はこう思うだろう。

「stdinとstdoutを閉じればいいんだよ馬鹿だなぁ」

やってみよう。


$ import sys
$ sys.stdin.close()

どうなっただろうか。 おそらく例外が発生して/bin/shへfallbackされたのではないだろうか? コードを見ないルールなので、これは予測だが、 トレースバックを見るにどうやらstdinに対してxonshはポーリングを掛けており、 これが閉じられてしまうケースを想定していないようなのだ。 Oh...じゃあfork()しても、stdinをclose()した段階で、 プロセス落ちちゃうじゃん。

ところが、ここに光明が見える。


$ import sys
$ sys.stdout.close()

どうなっただろうか? 何も起こらない? ではこうして見てほしい。


$ import sys
$ sys.stdout

お分かりだろうか。 そう、このstdoutは_ioに属していないのだ。 stdoutが別のclassに差し替えられているということは、 同じことをstdinにも施してやればいい。 無害なインタフェースクラスを作り、stdoutとstdinを差し替えてやればオッ!

・・・

ところが、そうは行かなかったのである・・・。

解析中にトレースバックで見たのだが・・・


$ import os
$ os.close(1)

これ[*]をやって出てくる トレースバックに、 あろうことか


  File "/usr/lib/python3/dist-packages/xonsh/__amalgam__.py",
  line 15626, in settitle
      with open(1, 'wb', closefd=False) as f:

fuxx!!! オイオイオイオイ、その使い方は無いだろオイオイ!

stdoutをですね!ダイレクトにですね! 叩いてるコードがいるんですね!!!

俺の言えた義理じゃないが邪悪すぎやしませんかね?

ということで、いまだに俺はXonshを使ってfork()をうまく使うことが出来ない。 だれか助けてくれ。

最後に

新たなおもちゃを手に入れたと思って遊んでいたが、成果だけが出ていなかった。 皆さまはこのような悪い大人になってはいけませんよ?

それではまた。

About this document ...

Xonshを邪悪に使おうとしたが失敗した話から

This document was generated using the LaTeX2HTML translator Version 2017.2 (Released Jan 23, 2017)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -split 0 xonsh.tex

The translation was initiated on 2017-12-20


Footnotes

... どう考えてもこうやりたい[*]
これ実は出来るよって情報求む
... 挫折した。[*]
これも出来るなら教えてほしいと思うが・・・いやこれは無理やろ
... ツイートするのが簡単になる。[*]
ほんとか?tweet()みたいな関数用意しとけばいいだけじゃね?
... Pythonには詳しい[*]
そんな気がする
... 実際、dir()を使った解放コードはある時まで[*]
バージョン控えておかなかったんだよなぁ
...調査のために、以下のように確認してみる。 [*]
Pythonにおいては未知のオブジェクトを調べる標準的な手法だ
... まだ、根幹の定義済み命令を置き換えると、xonshがハングアップしてしまう。[*]
なにやら新しいバージョンで試したら、今度はハングアップしなくなっているのかな?これは期待が持てる
... Cとの結合をしようとしたらGILが働く設計にしとけばよかったじゃんか[*]
愚痴
... 表示も二重に出て、有り体に言えばバグる。[*]
xonshのバグではないと思うけど
...これ[*]
stdoutを無理やり止めようとしたのだ

日曜日, 12月 10, 2017

web スクレイピング隠蔽技術

web スクレイピング隠蔽技術

beepcap

2017/12/10

はじめに

なんか気づいたらアドベントカレンダーに登録してた。 webスクレイピングの10日目だ。 beepcapである。


webスクレイピング... 最近はwebスクレイピングなどとかっこいい名前が付いているが、 昔はwebクローラといった気がする。厳密な定義がどうかは分からんのだが、 軽く調べてみても両者を明確に区別する文言は見つからない。 本記事ではwebクローラと言うことにする。[*]

さて、古くからwebを扱っている人間にとって、 webクローラというのは親の敵のような存在だ。 ネットワークが従量課金性であった時代では、 アップロードとダウンロード双方に回線料が発生するのだ。 クローラにアクセスされた分の料金を支払わねばならない個人サイトの運営者は とにかくクローラを排除する必要に迫られた。

その検出手法と攻防の推移を紹介しながら話を進めよう。

基本編

初歩的なクロール対策

「初歩的な」と書いたが、一般的なwebクローラの攻防は大体これだ。 [*]まずさくっとwebクロールしてみよう。 きっと今回のACの他の記事にwgetによるクロールの話が出てくると思うので 仔細は語らないが、


$ wget -r -l inf -k -nc -E -np http://targ.et

といったところだろうか。 上記は最速で取得しようとするので、 httpdのアクセスログは単一のIPアドレスでうめつくされる。 管理者側からはバレバレだ。

この行為への対策はIPアドレスフィルタリングとなる。 自動化して一定時間のアクセスを禁止するものから、[*]


$ iptables -A INPUT -p tcp -m hashlimit -dport 80
  -hashlimit-name no_robot -hashlimit 5/s -hashimit-burst 3
  -hashlimit-mode srcip -j ACCEPT
$ iptables -A INPUT -dport 80 -j DROP

やらかしたら二度とアクセスを許さないものまで多種多様だが、


$ iptables -A INPUT -s xx.xx.xx.xx/32 -j DROP

対webクローラの手法としてIPアドレスフィルタリングは良く使われていた。 90年代〜2000年代初頭にwebページを運営していた仲間内では 「クロール元のIPリスト」なるものがやりとりされていたりもしたのだ。 こうなってしまっては満足に収集も出来ない。 [*]そこで、次のような対策が打たれた。

初期の対策の対策

これもwgetの例でいいだろう。


$ wget -r -l inf -k -nc -E -np -w 1 http://targ.et

このコードは1秒に1回のアクセスに取得を制限するものだ。 一般的なクローラの動作といっていい。 現代の普通のサイトではクローラを拒否する理由なんて 負荷くらいのものだから、この対策で十分に効果があるし、 目を付けられてブロックされる恐れも無い。
世の中の大半が幸せなら、それ以上の技術はいらない。


などという甘い考え方が通用しない人たちもいる。

例えばセキュリティ技術者のようにログを監視している人々にとっては、 こんなふうにこれらのアクセスが見える。


[水 12月  6 08:30:03 2017] Inbound_tcp_s SRC=xxx.xxx.xxx.xxx DST= LEN=40
 TOS=0x00 PREC=0x00 TTL=238 ID=45566 PROTO=TCP SPT=43146 DPT=80
 WINDOW=1024 RES=0x00 SYN URGP=0
[水 12月  6 08:30:04 2017] Inbound_tcp_s SRC=xxx.xxx.xxx.xxx DST= LEN=40
 TOS=0x00 PREC=0x00 TTL=238 ID=45567 PROTO=TCP SPT=6666 DPT=80
 WINDOW=1024 RES=0x00 SYN URGP=0
[水 12月  6 08:30:05 2017] Inbound_tcp_s SRC=xxx.xxx.xxx.xxx DST= LEN=40
 TOS=0x00 PREC=0x00 TTL=238 ID=45568 PROTO=TCP SPT=22012 DPT=80
 WINDOW=1024 RES=0x00 SYN URGP=0
[水 12月  6 08:30:06 2017] Inbound_tcp_s SRC=xxx.xxx.xxx.xxx DST= LEN=40
 TOS=0x00 PREC=0x00 TTL=238 ID=45569 PROTO=TCP SPT=30153 DPT=80
 WINDOW=1024 RES=0x00 SYN URGP=0
.
.
.

webクローラであることがバレバレだ。 webクローリングを阻止したい人間がいれば、排除されてそれで終わりとなる。

そこで、ここからが本題だ。 如何にしてwebクロールを隠蔽するのか。

アクセスのタイミングの隠蔽

人間が操作しているかのようなログを残せば、機械だと見破られなければ 如何に優秀な管理者が相手であっても、これをブロックして仕舞うことは難しい。

例えばこれをランダム化によって回避しようとする手法がある。 wgetで言えば-random-waitという手法である。 これを行うとアクセスの待ち時間がランダム化し、 パッと見では分からなく・・・ならない。普通に怪しい。 ただし、自動解析ツールを使って監視している場合は検出されなくなることがある。 周期性をキーに監視しているツールが存在するからだ。 それでも、まぁアクセスが多くなるので、 人間に監視を促すよう警告が出る場合がある。そうしたらお陀仏だ。

ランダムではなく、人のような動きをクローラにはさせてやらねばならない。

とここまで書いたが、残り締め切りまで一時間しか無いので、 巻いていこう。タイミング隠蔽を含めて、クロールが発覚しにくい手法の肝要な部分は3つある。

人の動きを模倣するには2つの点で気をつけねばならない。 一つはアクセスする頻度だ。 先程までの話から展開させると、つまり人は文書を読んでから次のリンクをクリックするので、文書上の距離を計測すれば適切な待ち時間を算出できる。 この方法は、レンダリング後の画像を使う確実な方法と、マークアップと文を含めた文字数で算出する方法があるが、 評価し確認してみた所だと、文字数だけでもかなり精度が高い。 これはマークアップという書式の特徴だと思われる。 ただし、画像の中に文書があるような形態の場合はやはり画面上の距離を推定する必要がある。 どの程度の精度と成果をバランス良く摂るのかを検討して設計して欲しい。

アクセス元の偽装

言うまでもないが、アクセス元を偽装しなければ、同じサイトに毎日現れる不審なログに気付かれる可能性がある。 とはいえ、アクセスのたびにProxyを切り替えるような手法はダメだ。 SYNのたびにProxyが切り替わるログは完全に怪しさしかないし、まともなサイトの管理者は、むしろパブリックなProxyを弾くように設定している。 ここで大事なのは、企業などからアクセスしているように見せかけることだ。 この場合、仮に頻度がある程度高くても、同じページを一斉に参照している可能性も考慮されるからだ。

ということで、この場合も最適解だけ書くと、 安価なクラウドサービスをレンタルし、自前のProxyサーバを立てること。 そして、一日以上、短くても数時間以上の長いスパンでProxyの切り替えをすることだ。 同じサイトに同じ人間がいることはおかしくない。 という心理上の正しさを追求すべきである。

クロールする時間

最後の項目だが、これは簡単だ。 24時間ページを見続けられる人間は居ない。 あなたがクロールする時、それをアルバイトに任せることを考えて、稼働のシナリオを考えるのだ。webクローラとは隠密の世界なのである。

最後に

最後に、これらのいかがわしいwebクローラのコードを貼っ付けるのと、 Apache ManifoldCFとApache Solrによって構築するwebクローリングシステムの運用方法に言及しようと思っていたのだが。 時間切れでなんにも出来てません。本当に申し訳ない。 これらの話を聞きたい方は、Twitterで直接話しかけて欲しい。 @beepcapとしていつでもリプライを待っているぞ。

以上

About this document ...

web スクレイピング隠蔽技術

This document was generated using the LaTeX2HTML translator Version 2017.2 (Released Jan 23, 2017)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -split 0 webスクレイピング.tex

The translation was initiated on 2017-12-10


Footnotes

... 本記事ではwebクローラと言うことにする。[*]
そっちの方が短いし
... 「初歩的な」と書いたが、一般的なwebクローラの攻防は大体これだ。[*]
煽ってるんじゃないよ?それで十分なのさ。
... 自動化して一定時間のアクセスを禁止するものから、[*]
同じIPから port 80への3回以上のアクセスは1秒5回まで
... こうなってしまっては満足に収集も出来ない。[*]
リトライをちゃんと仕込んでおけば前者は回避できるが、 後者をされる確率が上がる

水曜日, 5月 17, 2017

愚痴

また標準テーマが気に入らなくてカスタムテーマを作ってしまった。
こうやってカスタムするから、引き継ぎができなくて、
毎回標準テーマが更新されるたびに泣く泣く時間をかけてカスタムする羽目になるというのに。

火曜日, 5月 16, 2017

cgroupを利用して処理ごとに資源を割り振る話


仕事でcgroupを使用したくなってちょっと調べたのですが、
Googleで調べると、昔こんな記事を書いたことが発覚しました。

当時は動いたのだでしょうが、現代では間違いだらけの動かないポンポコピーなので、
書き直すことにします。
なお当該のパッチは現在でも形を変えて(当時ほど率直ではないものの)残ってはいるので、この対応は全くの無駄です

でもgoogleでcgroupの使いかたの日本語記事でこのblogが引っかかるので、訂正しておかなければならないですよね・・・。





日曜日, 2月 12, 2017

なんだかTwitterにプロモーションツイート課金してみた。

どうも。
beepcapです。

最近この喋り出しがyoutuberっぽいって言われました。
そりゃああっちがネットラジオからパクってった文化ですからね!

youtubeできるより前からラジオしてたっての。
もうやってないけど。

さてさて、本題ですが、
Twitterで課金してみました。


土曜日, 12月 17, 2016

SO-FI


この記事はロックバンド Advent Calendar 17日目です。

はい皆様お久しぶりです。
beepcapです。

ばんくしのアドベントカレンダーに合わせて一年ぶりに記事を書いています。
正直眠いです。



土曜日, 11月 28, 2015

たった半日でRaspberry Piを使った監視カメラと配信サーバを作る Step 2



前回

ということで、今回から設定していきます。
beepcapです。

前回で必要なソフトのインストールは大体終わったので、設定を行います。

Raspberry Pi 設定

Raspberry Pi2ではmotionの設定を以下のように変更します。
  • 画像の出力は動体検出ではなく定期的に
  • 画像のファイル名は固定(取得のたびに上書き)
  • 画像の置き場はramfs
そのためには、まずエディタで/etc/motion/motion.conf
を開く必要があります。

raspbianではデフォルトでnanoが採用されているので、
sudo nano /etc/motion/motion.conf
とします。

とりあえず僕は以下のように変更しました。
<<後日設定ファイルをはりつける>>

## デーモンモードを切る
daemon on

daemon off

## 常にキャプチャを取得する
emulate_motion off

emulate_motion on

## 動画の出力を停止する
ffmpeg_output_movies on

ffmpeg_output_movies off

## ramfsにファイルを出力する
target_dir /var/lib/motion

target_dir /dev/shm

## 出力ファイル名を固定する
picrure_filename  %v-%Y%m%d%H%M%S-%q

picure_filename output

ここで、動作確認をしてみます。
USBカメラをRaspberry Pi2に接続し

sudo motion

を実行し、出力された/dev/shm/output.jpgを確認して下さい。
画面がキャプチャされていれば成功です。

さて、サーバにuploadするための仕組みも作りましょう。

以下のようにしてスクリプトを書きます。

nano upload.sh
以下ファイル内

#!/bin/bash
while :
do
  scp -i "azureサーバの秘密鍵" /dev/shm/output.jpg azureuser@******.test-serv.cloudapp.net:/home/azureuser/output.jpg
sleep 1
done
秘密鍵は事前に作っておく必要があります。
秘密鍵の作成手順は、あとで例として載せますが、同じ手順である必要はありません。


上のスクリプトは1秒に一回、画像ファイルを/home/azureuser/output.jpgに上書きします。

 あとはこれらを起動時にじっこうするよう、Raspberry Pi2に登録します。

sudo nano /etc/rc.local
 このファイルのexit 0 の前に以下の2行を追加します。

motion&
/bin/bash /home/pi/upload.sh&

これで、Raspberry Pi2は起動後からカメラだ撮った内容をサーバにuploadし続ける機器になりました。

サーバ側の設定

さて、Azure側では受け取った画像を公開しなければなりません。
今回は気取って、canvasを使いました。
web 1.0な人はimgタグをつかってreloadすればおしまいです。

nano index.html
ここで新規に作成して


<html>
<script>
onload = function() {
  draw();
  setInterval("draw()", 1000);
};

function draw() {
  var canvas = document.getElementById('c1');
  if ( ! canvas || ! canvas.getContext ) { return false; }
  var ctx = canvas.getContext('2d');
  var img = new Image();
  img.src = "output.jpg?" + new Date().getTime();
  img.onload = function() {
    ctx.drawImage(img, 0, 0, 640, 480);
  }
}
</script>
<canvas id="c1" width="640" height="480"></canvas>
</html>




こんな感じのスクリプトを仕込みます。

上のスクリプトが何をやっているのかは見ていただければわかりますが、
最大限手抜きをしているので資源がもったいないとかはご容赦下さい。

さて、index.htmlがAzureの /home/azureuserに出来たかとおもうので、
webサーバを立ち上げます。

~/thttpd-2.27/thttpd -d .

終わり!!!(※1)

※1 Azureの場合はポートを開ける動作として、エンドポイントの設定でHTTPを開いて下さい。

あとは、Raspberry Pi2を起動して、サーバのwebページにアクセスすれば、
バッチリカメラ画像が更新されているはずです。




さいごに

どうだったでしょうか?
半日で出来たでしょうか?

普段、ちょっとほしいなと思いつつも、中々ハードルが高そうで出来ないこと。
それを実現するのがIoTと呼ばれる、簡易組み込みの世界だと思います。

こうやってどんどん、楽に、色々作っていけたら楽しいですよね!

ではでは。
beepcapでした。




おまけ

サーバで公開鍵認証を行う方法

ssh-keygen -t rsa
cd ~/.ssh
cat id_ras.pub >> authorized_keys
あとは、id_rsaをRaspberry Pi2側に転送すればok

使いまわさないように注意。


たった半日でRaspberry Piを使った監視カメラと配信サーバを作る Step 1

「たった半日でRaspberry Piを使った監視カメラと配信サーバを作る」
という流行りっぽい名前で記事を書いてみようかと思います。

beepcapです。
皆様お久しぶりです。

====ここから下は隠すみたいな表記も忘れてしまった====

さて、Twitterでふぁぼは募ったのですが、集まらなければこっちで公開した内容をあっちに貼らなければ良いだけなので、先に記事を書いておきます。

三分間クッキングよろしくまず材料を集めます。

材料


  • Raspberry Pi2 Model B (Raspberry Piでもよし)
  • なんかサーバ(※1)
  • USB接続のwebカメラ(※2)
  • LANケーブル、マイクロUSB給電ケーブル
  • micro SDカード
  • マウスとキーボード(※3)

    ※1 WANから参照可能でsshが使えればなんでもいいです。(今回はAzure)
    ※2 市販のwebカメラで大丈夫ですが、RPiの場合専用カメラもあります。
    ※3 実働には不用です。開発のために調達してください。

座料は揃いましたか?
ない人は買ってきましょう。
Raspberry Pi 2 Model B
なんかサーバ
USB接続のwebカメラ
LANケーブル
マイクロUSB給電ケーブル
micro SDカード

マイクロUSB給電ケーブルは100円ショップのものでも良いのですが、
Raspberry Pi2は比較的大食いなので、発熱などに気をつけて下さい。

「なんかサーバ」は今回はWindows Azureを採用してみました。
Microsoft AzureはAWSとして使うと幸せなんです。
多彩な機能はぶっちゃけ使いにくいAzureですが、Linuxサーバとしては優秀です。
ただ、料金は240円/日くらいかかります。
月額7200円ですね。
なので、この記事を見ている方々は自身のお好きな資源を使われたほうが良いと思います。

材料はこんなもんです。

 下準備

下準備を始めましょう。
Raspberrt Pi2にはRaspbianを入れておきます。
といっても楽をしたいので、NOOBSで入れましょう。


上記のリンクから、NOOBSをダウンロードしてきます。
多分Liteでもいいのですが、標準版にはRaspbianがすでに格納されています。

ダウンロードしてきたzipを解凍し、フォーマット済みのmicro SDに入れます。
あとはRaspberry Pi2にmicro SDを挿入し、マイクロUSB給電ケーブルで
USB電源と接続してください。

<<忘れなかったらここにNOOBSの画面>>


このへんの記事を参照に、Rasbianをインストールして下さい。



AzureにはLinuxサーバをインストールする必要があります。
Azureを使わない人はVMでも何でもいいので、Linuxのインストールと読み替えて下さい。
なお、Linux側は楽をするために、Ubuntu 14.04 LTSを使っています。


Azureのメニューの新規作成からこんなふうに新しいサーバを作成します。


作成すると、sshdが有効になったサーバが立つので、
user: azureuser
pass: 上記画面で指定したもの
でsshログインができます。

ssh azureuser@******.test-serv.cloudapp.net

といった感じでしょうか。



ソフトのインストール

では今回使用するソフトをインストールしていきましょう。
 まずは、Raspberry Piから。

  • Motionの導入
    Motion Wiki Home Motion - Web Home
    今回はビデオキャプチャとしてmotionを使います。
    motionを選択した理由は、
    1. 導入が簡単
    2. 定期的に画像ファイルとして出力できる
    3. 同じファイルに連続して上書き出来る。
    ということで、今回はこれを選択しました。
    3が重要です。
ではインストールします。
ディストリビューションはdebianベースなので、
sudo apt-get install motion
終わりです。

次にwebサーバをAzure側に作ります。
といっても、Apacheとかnginxとか巨大だしめんどくさいですよね?

ということで、

  • thttpdの導入
    thttpd
    導入の理由は
    1. とにかく簡単に設定(?)が終わる
    これに尽きます。
こちらもAzure上のubuntuなので
sudo apt-get install thttpd
とやりたいところなのですが、
コレではダメです。
なぜダメかというと、Ubuntu 14.04 TLSでは愚かなことに、thttpdが
パッケージに含まれなくなってしまったのです。

仕方がないので、野良ビルドします。

先ほどのページからthttpdをダウンロードして、ビルドします。
wget http://acme.com/software/thttpd/thttpd-2.27.tar.gz
tar -xf thttpd-2.27.tar.gz
cd thttpd-2.27
./configure
make
こんなかんじでしょうか。

さて、重要なソフトのインストールは出来たので、
次回から、設定と環境構築と楽しいコーディングと行きましょう。

ではでは

次回

自己紹介

自分の写真
NetRadioDJ ...since 2003, Programer ...since 1994