dogwood008の開発メモ!

最近のマイブームは機械学習, Ruby on Rails。中でも機械学習を使った金融商品の自動取引に興味があります。

【Ruby, Python】開発時に通信傍受プロキシを設置した時、ルート証明書を与えて、ハンドシェイクエラーを回避する

TL;DR

各言語での設定

  • Ruby
    • ENV['SSL_CERT_FILE'] = PATH_TO_SSL_CERT_FILE
  • Python
    • import os; os.environ['CURL_CA_BUNDLE'] = PATH_TO_SSL_CERT_FILE

この文書は誰向け?

サーバサイドの開発者で、通信内容を覗きたい人

暗号化されていないhttpでの通信であれば、後ほど紹介するcharles等をプロキシサーバにするだけで内容を傍受できます。しかし、SSL/TLSで暗号化されているhttpsの通信は、プロキシの設定だけだと「ハンドシェイクに失敗した」といわれて傍受することができません。

実際に開発を行う上で通信を傍受したいケースは、次のようなものが挙げられます。

サーバサイドの人の例:

他のAPIサーバへアクセスしに行く際、正しいパラメータでリクエストしているはずだがレスポンスが期待するものと一致しない。原因の切り分けのために送受信している内容を傍受したいがhttpsでアクセスしているため、SSL/TLSで暗号化されていて読めない…

→この方法で読めるようになります!

フロントエンドの人の例:

仕様書に沿ったリクエストを投げているのに、いっこうに期待するレスポンスをサーバが返してこない。以下同文。

→この文書では扱いませんが、以下で紹介されている方法で傍受することができます。

どうやって覗くの?

この辺を使ってください。私はcharles大好き人間なので課金して使っています。今回はcharlesを使いますが、mitm-pythonの場合もほぼ同様です。

f:id:dogwood008:20180212142311p:plain

予めcharlesを起動し、Help -> SSL Proxying -> Save Charles Root Certificate でルート証明書を保存しておきます。mith-pythonの場合は ~/.mitmproxy/mitmproxy-ca-cert.pem にあるものを使います。

f:id:dogwood008:20180212142042p:plain

各言語での設定

基本的には環境変数で指定された値を与えてやればOKです。

Ruby

http_proxy = 'http://THE_IP_OF_MITM_PROXY:PORT' # 変更する
ENV['HTTP_PROXY'] = http_proxy
ENV['http_proxy'] = http_proxy
ENV['HTTPS_PROXY'] = http_proxy
ENV['https_proxy'] = http_proxy
ENV['SSL_CERT_FILE'] = './charles-ssl-proxying-certificate.pem' # 必要に応じて変更する

Python

import os

http_proxy = 'http://THE_IP_OF_MITM_PROXY:PORT' # 変更する
os.environ['HTTP_PROXY'] = http_proxy
os.environ['http_proxy'] = http_proxy
os.environ['HTTPS_PROXY'] = http_proxy
os.environ['https_proxy'] = http_proxy
os.environ['CURL_CA_BUNDLE'] = './charles-ssl-proxying-certificate.pem' # 必要に応じて変更する

あとはそれぞれスクリプトを走らせれば、通信内容を傍受できます!