続 カッコの付け方

AWSを始めとしたクラウドコンピューティング全般と、唯一神emacsにおける()の付け方についてだらだら書きます

CLI向けhttpsキャプチャーを使う

全部httpsじゃないとだめな時代になりました。http通信の中身を見るだけならproxyで抜けばよかったですが、httpsの場合はそうも行きません。mitm(man-in-the-middle)をやって、httpsの暗号をproxyでほどかないといけません。
この手の情報がほしい人は限られていると思うので、細かい解説はすっ飛ばします。わかってらっしゃる方向け

f:id:iga-ninja:20190630015954p:plain

tl;dr

  • mitmproxyというcli向けproxyがある、cliなら多分これ一択
  • ca証明書指すのが面倒 がんばって調べて指す

元も子もないですが、もしあなたがhttps通信を行うプログラムの作者自体なら、log-level=debug,trace とかにしたときにヘッダを含めて全部標準出力などに垂れ流すようにしたほうが100倍楽です。そもそも世の中のhttp(s)クライアントはlog-levelを上げればverboseになるようにできてます。

対してこのmitmproxyは万能・汎用的である点は優れますが、ともかくca証明書がだるい。

mitmproxyの紹介

mitmproxy - an interactive HTTPS proxy

python製です。pipでも入ります。引数なしで起動したら 8080 listenして、 ~/.mitmproxy 配下にCA証明書とかを吐きます。あとは 環境変数 https_proxy と、このCA証明書を信頼してやればいいだけ。
CLIと書きましたが、mitmproxy自体はCLIですが、ローカルPCで動かして、GUIWebブラウザからプロキシ指してCA証明書をインポートすればブラウザ相手でも通信を抜けます。ブラウザ向けのやり方は公式を参照してください。
ブラウザ相手という視点なら、 macなら Charles, winなら Fiddlerとかとおんなじです。こいつらでCLIhttps通信を抜くことももちろんできます。が、Linux上でサクッとやりたいのでmitmproxyが良い。

他の競合はJMeterなどもこの機能があります、試験用のシナリオを楽に作成するときに使います。tcpdumpもサーバ側の秘密鍵が自分で手に入るなら復号化できるのでいけますが、外部サービスやらAPIの呼び出しはそんなの無理なんで、そういうケースを想定してます。

使い方は簡単です。 mitmproxy とコマンド打つだけ。あとは勘でいける。

各種ランタイムの証明書の通し方

こっからが本題です。ブラウザと違ってCLIhttps-clientは証明書の指し方がバラバラです。備忘録のように書き残し&書き足しておきます。

Java

javaはproxy自体の指し方がちょっと特殊です。
-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080
と、オプションを渡せるならそれで、無理なら環境変数 _JAVA_OPTIONS に足してやればOK

問題は証明書です keytool という java 用のコマンドを使って追加します。

sudo $JAVA_HOME/bin/keytool -import -trustcacerts  \
-file /path/to/mitmproxy-ca-cert.pem                 \
-alias mitmproxycert                                 \
-keystore $JAVA_HOME/jre/lib/security/cacerts

$JAVA_HOME/jre/lib/security/cacerts 以外の場所に作るなら java実行時に java vm のオプションである -D<hoge>で指定ができるはず。 $JAVA_HOME/jre/lib/security/cacerts には パスフレーズがついていて、デフォが changeitらしい。

blog.packagecloud.io

のパクリ

ruby

私の経験値が低いため、イレギュラーを知らないせいか比較的散らかってないと思う。 proxy自体は https_proxy環境変数でほとんど通るはず。 証明書は ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE" で調べて、そこに追記しちゃうのが多分てっとり早い。大体システムのデフォルトだと思う。

python

証明書はイレギュラーだらけでやばい、proxy自体は環境変数でまあいける。 package次第だが、たしか requests とかは独自で ca-certを持っていて、バージョン次第では証明書だけで別のpackageになっている。

dev.classmethod.jp

使うライブラリ次第で使っている証明書も異なる。頑張って調べてねとしか言えない。

nodejs

proxy自体は環境変数でOK。 証明書はある意味一番特殊で。システムのca-certは一切参照しておらず。なんとハードコードで nodeのバイナリ本体に内包されている。システムの証明書を使う場合は

--use-bundled-ca, --use-openssl-ca

が使え、今回のような専用の証明書を指すなら

NODE_EXTRA_CA_CERTS=file

https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file

という環境変数で行けるらしいです。対応バージョンは v7.3.0からとなっていますが、旧バージョンにもLTSならばもある程度バックポートされているらしい(未確認)

まとめ

このライブラリがどんな動きしてるかわからない?となったとき

  • ログレベルを上げて実行する (-v とか -l debug とか DEBUG=1 とか)
  • それでトレースできないなら、プログラム意地れるなら loggerにだすなり echoするなりする
  • それでもだめなら、無理なら サーバの秘密鍵取れるなら tcpdumpとか
  • それも無理なら mitmする

見た目はいいんですよ。機能も多機能。だけど使えるようになるまでが面倒。