2017年5月14日

Raspberry Pi 3にmitmproxyを導入する


仕事での開発時によくお世話になっているmitmproxyですが、週末プライベートでの開発時にふと使いたくなったものの、自宅PCは無線LANの無いWindowsデスクトップだったり、有線LANの無いMacbook Proだったりするので、そのどちらも持っているRaspberry Pi 3(以下RasPi3)に導入してみました。

準備

まず本作業の前提条件として、RasPi3の無線LAN(wlan0)はアクセスポイントとして利用するため、有線LAN(eth0)もしくはUSB-LAN(eth1)などwlan0以外からインターネットへ接続できている必要があります。

また、/sbin/ifconfig -aコマンドを実行してwlan0が見えない場合、/etc/network/interfacesファイルを編集してwlan0を有効にします。
(iface wlan0 manualの先頭#を削除、次の行のwpa-conf先頭に#を追加)

hostapdのインストール

上記状態であることが確認できたら、以下のコマンドでRasPi3のwlan0をアクセスポイント化するhostapdをインストールします。
sudo apt-get update
sudo apt-get install hostapd
インストールが成功したら、/etc/hostapd/hostapd.conf設定ファイルを作成して以下の設定を書き込みます。
interface=wlan0
ssid=(SSID名)
country_code=JP
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
ieee80211n=1
wpa=2
wpa_passphrase=(SSIDパスフレーズ)
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
設定ファイル作成が完了したら、wlan0に割り当てるIPアドレスを/etc/dhcpcd.confに設定します。
interface wlan0
static ip_address=192.168.137.1/24
最後にsudo hostapd /etc/hostapd/hostapd.confを実行してアクセスポイントを起動します。

OpenSSLのアップデート

次に、最新版のmitmproxyを導入する(apt-getでインストールできるmitmproxyはバージョンが古い)ため、OpenSSLを最新版にアップデートします。
最新版のOpenSSLパッケージを取得するため、/etc/apt/sources.list.d/backports.list設定ファイルを作成して、以下のDebian Backportsのリポジトリーを追加します。
deb http://httpredir.debian.org/debian jessie-backports main contrib non-free
追加したら、以下のコマンドを実行して上記リポジトリーのGPG鍵をインストールします。
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553
上記コマンド実行後、sudo apt-get updateを実行してパッケージデータベースの更新を行います。

最後に以下のコマンドを実行して、最新版のOpenSSLにアップデートします。
sudo apt-get install -t jessie-backports -y openssl libssl-dev

最新版Pythonのインストール

mitmproxyはPython 3.5以上が必要ですが、RasPi3には3.4系までしかインストールされていないため、最新版ソースをダウンロードしてビルド&インストールします。
curl -O https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz
tar xvfJ Python-3.6.1.tar.xz
cd Python-3.6.1
./configure
make
sudo make install
インストールが完了したら、pip3をアップグレードします。
sudo pip3 install --upgrade pip

mitmproxyのインストール

ここまでの作業で最新版のmitmproxyをインストールする準備が整ったので、以下のコマンドを実行してインストールします。
sudo pip3 install mitmproxy
インストールが完了したら、以下のコマンドのどちらかを実行してmitmproxyを起動します。
mitmproxy --insecure --port 1324
mitmweb --insecure --no-browser --web-iface 192.168.0.3 --port 1324

接続テスト

ここまでで、hostapdとmitmproxyが起動した状態になりましたので、スマホなどの無線LANクライアントをhostapdで作成したアクセスポイントに接続します。
今回は導入を簡単にするため、DHCPサーバーなどのインストールは行っていないため、IPアドレスなどの情報は全て手入力します。
上記までの設定の場合、IPアドレスは192.168.137.2、Proxyサーバーアドレスは192.168.137.1、ポート番号は1324となります。

最後に

ここまでの設定で、スマホのHTTP通信は見えるるようになっているかと思いますが、HTTPS通信も見る場合はmitm.itに接続してSSL証明書をインストールするといった作業が必要になります。

また、前述の通りDHCPサーバーの導入や、mitmproxyを透過型モードで動作させるための設定(iptablesやnet.ipv4.ip_forwardなど)は今回行っていないため、必要であれば以下のページを参考に設定してみるといいかもしれません。

Raspberry Pi 3 アクセスポイント化 〜hostapd〜 - はっとてっくろぐ
Raspberry PiとスマートフォンをWiFiでアドホック接続 - karaage. [からあげ]
Raspberry PI 3 + MITMProxy – Adam Engle
Raspberry Pi Debian Backports · superjamie/lazyweb Wiki · GitHub

2017年2月26日

ScalaMatsuri 2017に行ってきた

昨日と今日は、プログラミング言語Scalaのカンファレンスである「ScalaMatsuri 2017」に初参加してきました。

Scala自体は業務でも個人でもまだ使えていないのですが、前職で少し触る機会があったのと、一緒に行こうという事で勢いでチケットを買ってみた次第です。

1日目

事前に発表された講演内容で、自分のScalaレベルと興味のある分野からセッションを選択しました。

Readable Scala

少し触っていた頃に、"~>"とか今まで見たことない(そしてググりにくい)記号が多くて愕然としていたのを思い出したのですが、「”パラダイムやイディオムを知らないから可読性が低い”という主張は意味をなさない」というのは耳の痛いところでした。また、それらがコードをいかに読みやすくするかに主眼を置いて設計されている事がよく分かったセッションでした。
(そしてsprayが今はもうメンテナンスされていない事を今さら知る。。あとググりにくいのは”tilde greater than scala”みたいにすれば探せるのを知ってだいぶ改善された)

新サービスをゼロから開発してローンチするのに大切だった3つのこと

Twitterに新機能(新サービス)を追加した際の知見として、「まずは上から下までとにかくつないで動かす」「内部状態と変更の流れを管理する(一方向にする)」「ちゃんと名前をつけることが大切」があげられていました。個人的には、旧システムからの移行を一部のモデルから行うためにFutureを導入して解決していったくだりがFutureを理解する参考になりました。

Akkaで分散システムの障害に備える

本セッションでは、「障害を前提としたシステム(アンチフラジャイル)」「レジリエントなシステム」をAkkaでどう実現するかが語られましたが、システム障害に対する今までの考え方や備えを改めさせる可能性を感じました。

ゲームサーバのためのScala/Play

もともとPHPで開発していた自社ゲームタイトルのサーバーサイドをScala/Playで実装した事例として、規模感やインフラ周りのTips集などが語られたので、業種や経緯とかいろいろ思い出しながら聞かせて頂きましたが、Scalaの"better Java"としての事例は今後増えていって欲しいなと思いました。
(FPバリバリで書かれているのかもしれませんが。。)

DMMのAPI GatewayをAkka StreamsとAkka HTTPで作り込んでみた


こちらもPHPで作られた旧認証基盤を置き換えるというお話だったので、いろいろ思い出しながら聞かせて頂きました。プロダクションレベルでAkkaが導入された事例としても興味深かったです。


メタメタにしてやんよ。(メタプログラミングもしくは Shapeless のすすめ)

”入出力がデータではなくプログラム”であるマクロとして、Scalaマクロ(今は使ってはいけない)から、それに代わるScala.metaとshapelessの例をライブコーディングで見ることができました。

Scala & Sparkによるデータ・エンジニアリング 7大レシピ

組織でデータを集めて分析に使うために必要な7つの”レシピ”と、その解決方法を聞くことができましたが、前半のレシピにあったチームへの根回しやデータの品質を高める努力は海外でも同じだったのが意外でした。

ChatWorkのScala採用プロダクト “Falcon” リリースまでの失敗と成功の歴史

動いているサービスをScalaに置き換えるプロジェクトとしては国内有数の規模だったかと思われますが、それだけに苦労も多かった感じがひしひしと伝わる内容でした。

2日目

”アンカンファレンス”という、参加者の投票や参加者の中で発表したい(もしくは聞いてみたい)内容を当日決めるといった形式で行われました。

Ad Serving System on Finagle and Thrift

前日の講演でシリアライズライブラリーのThriftを多く見かけたので、使っている事例を聞こうと選択しました。シリアライズしたデータはMySQLのBLOBに入れる(=インデックス付きのKVS)ソリューションはおっと思いましたが、ScalaScriptをSQLのDML代わりに使う事で解決されたのが印象的でした。

採用担当者CTOぶっちゃけ座談会

各社の採用戦略や求められるエンジニア像が生々しく語られました。オフレコだったので詳しい内容は書けないものの、今回メモった量が一番多いセッションでしたw

Poorman’s Type Classes Revisited

Scala初学者が理解に苦しむ(らしい)implicitについて、なぜこれが導入されたのかをHaskellの例を交えて詳しく解説されました。実は1日目のReadable Scalaでもimplicitについては触れられてたのですが、その時は正直分からなかったのがこのセッションで何となく理解することができました。

JavaエンジニアのScalaの話が聞きたい

もともとJavaや他の言語で開発していた組織の中で、Scalaに変えるメリットや導入に関する悩みをざっくばらんにお話する(ちょっとだけ自分も混ぜてもらった)会でした。ScalaをFPで書くか"better Java"で書くかのさじ加減については、「ミッションクリティカルな部分はFP、(リリースの)速さを求められる部分は非FP」という回答が得られたのは個人的には収穫でした。

Lensの基本と基礎

最後のセッションは、「var使えばよくね?」という自分への戒めとして(笑)こちらを選択させて頂きました。”getter/setterを抽象化する”という例をライブコーディングを交えながらの講演で、こちらも理解できれば可能性が広がる感じがしました。
(LL言語のゆるふわなアクセスをカタい形で持ってくる理解、ではないんだろうな。。)

おわりに

今回初めての参加で多少背伸びし過ぎた感はありましたが、ここ最近自己研鑽の時間を疎かにしがちだったので、いい刺激をもらうことができました。
また、今まではAdTech界隈での採用事例が多かったところに、ぽつぽつ他業界でもScalaが採用されつつあるのが印象的でした。
(特にFOLIOさんのようなFinTech系企業でのScala採用は、Javaの牙城にどれだけ食い込めるのか気になります)

2016年12月25日

vimを使ってファイル名を一括変更(リネーム)する

複数のファイル名を一括変更(リネーム)する時、どういった方法で行わているでしょうか?
専用のリネームツールを使うのも一つの手ですが、自分はもっぱらvimとコマンドプロンプトを使った方法で行っています。この方法のメリットとして、

  1. 普段使い慣れたvimコマンドで編集ができる
  2. リネーム操作を(ある程度)やり直すことができる
  3. Windowsに限らず、MacやLinuxでも似たような操作で実行できる

があげられます。
今回は、録画データのファイル名をリネームする方法を例に取って説明します。

リネーム元ファイルパスの取得

まず最初に、リネームしたいファイル一式が格納されているフォルダーをエクスプローラーで開きます。
そこでファイルを全て選択し、Shiftキーを押しながら右クリックを押すと、「パスのコピー」という項目が出てくるので、それを選択してファイルパスをクリップボードにコピーします。
次にvimを開いて、先ほどクリップボードにコピーしたファイルパスをエディター上に貼り付けます。
この際、場合によっては名前順に貼り付いていない事があるので、SHIFT+Vキーを押してこれら全てを行選択し、:sortと入力して選択範囲をソートしておきます。

フォルダーパスの除去(リネーム元ファイル名のみに編集)

貼り付けた文字列を見ると、行毎に両端がダブルクォーテーションでくくられており、ドライブ名から親フォルダーまでのフルパスが記載されています。
リネーム作業自体には影響ないのですが、事故防止のためControl+Vキーを押してドライブ名から親フォルダーまでの部分を矩形選択し、dキーを押して削除しておきます。
これで、ファイル名のみがダブルクォーテーションでくくられた状態になるはずです。
削除が不十分orし過ぎた場合は、慌てずuキーを押してアンドゥ(元に戻して)やり直します。

リネーム先ファイル名の準備

リネーム元ファイル名の準備ができたところで、今度はリネーム先ファイル名を準備します。
番組名には、タイトルや話数の他にサブタイトルなどの情報がありますが、それらをExcelなどの表形式であらかじめまとめておきます。もしくは、インターネット上に同じく表形式でまとまっている場合、それらをクリップボードにコピーしてvimに貼り付けます。
今回はWikipediaの源氏物語より、各帖と名前を話数とサブタイトルに見立ててリネーム先ファイル名とします。
上記表をブラウザーで開いたら、左端の列から右端まで13行分をマウスでドラッグして選択し、クリップボードにコピーしvimに貼り付けます。

リネーム先ファイル名の形式

貼り付けられた文字列をよく見ると、各項目がタブ文字<TAB>で区切られているかと思います。
このように、特定の区切り文字を挟んで行列(行方向は改行)の形になっている文字列を別の形に整形する場合は、正規表現のグループ化による一括置換が便利です。
なお、リネーム先ファイル名は、以下のフォーマットで整形します。

”タイトル<SP>第00話<SP>「サブタイトル」.mp4”
<SP>は半角スペース
00の部分は、話数の番号を2桁でゼロパディングしたもの
サブタイトルは、全角の括弧でくくられるようにする
末尾には拡張子.mp4を設定

リネーム先ファイル名の整形

では実際の整形作業を行ってみます。
まず、第1話~第9話の部分に矩形選択を使って"0"を挿入しておきます。
次に、話数とサブタイトルを行選択し、:キーを押した後に一括置換の正規表現パターンを入力します。

'<,'>s/^\(.\{-}\)<09>\(.\{-}\)<09>.*$/"リネームされた番組名 第\1話 「\2」.mp4"/

'<,'>の部分が「現在選択されている行」を表し、それに対して一括置換"s"をかける宣言を行い、置換元のパターンと置換先のパターンを"/"で区切って入力します。
置換元パターンに含まれるタブ文字<09>は、\tではなくControl+vキーを押した後にTABキーを押して制御文字として入力します。なお、\{-}は最短マッチ(.*?)になります。

リネームコマンドライン文字列の作成

ここまでできたら、リネーム先ファイル名をControl+vキーを押して矩形(ビジュアル)選択し、リネーム元ファイル名の右隣にペーストします。両端の間の空白はいくつあっても構いません。
最後に、先頭行にカーソルを移動してControl+vキーを押し、最下行までカーソルを移動したらShift+iキーを押して"ren "(スペース入力を忘れないこと)と入力し、リネームコマンドを完成させます。

リネームの実行

リネーム元ファイル名とリネーム先ファイル名が一致している事を確認できたら、いよいよリネームコマンドを実行します。
リネーム元ファイル名が格納されているフォルダーを右クリックすると、メニューに「コマンドウィンドウをここで開く」という項目が出てくるので、それを選択してコマンドプロンプトを開きます。
コマンドプロンプトが開いたら、リネーム元ファイルが存在することを確認し、先ほど作成したリネームコマンドライン文字列を貼り付けてリネーム処理を実行します。

リネームに失敗した場合

万が一リネームに失敗していた場合でも、コマンドに誤りがない限りはファイルが消えたりすることはありません。
念のため話数とファイル名が一致している事を確認し、リネーム作業を最初からやり直せばOKです。