
Martianは、カスタムHTTP/Sプロキシを構築するためのライブラリです。
Martian Proxy は、テスト用に設計されたプログラム可能な HTTP プロキシです。
Martian は、以下のことを行いたい場合に最適なツールです:
Go のクロスコンパイルを活用することで、Martian は Go がターゲットにできるあらゆる場所にデプロイできます。
v3.0.0
Go 1.11
Martian Proxy は v3.0.0 以降、Go modules をサポートしています。モジュールをサポートしていない Go バージョンを使用している場合、これは動作しません。Go modules をサポートしていない最新バージョンは v2.1.0 としてタグ付けされています。
Martian Proxy は go install を使用してインストールできます。
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
Martian をインストール済みであれば、プロキシの実行は次のように簡単です。
$GOPATH/bin/proxy
Martian の実行中にシステムログを確認したい場合は、詳細度フラグを渡します:
$GOPATH/bin/proxy -v=2
デフォルトでは、Martian はポート 8080 で実行され、Martian API は 8181 で実行されます。ポートはフラグで指定できます:
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
リクエストとレスポンスのロギングには、ロギング モディファイア が利用可能です。また、-har フラグを使用すると HAR ログも利用できます。
Martian で HAR ロギングを有効にするには、-har フラグを付けてバイナリを実行します:
$GOPATH/bin/proxy -har
-har フラグが有効な場合、HAR 関連の2つのエンドポイントが利用可能になります:
GET http://martian.proxy/logs
最後のリセット以降にプロキシが確認したすべてのリクエストとレスポンスの HAR ログを取得します。
DELETE http://martian.proxy/logs/reset
メモリ内の HAR ログをリセットします。ログは定期的にリセットしない限り無制限に増大し続けることに注意してください。
Martian が起動したら、その動作を設定する必要があります。設定がない場合、Martian はリクエストやレスポンスに何も変更を加えずにプロキシ処理を行うだけです。ロギングが有効になっていれば、追加の設定なしでログが記録されます。
Martian は HTTP 経由で送信される JSON メッセージによって設定され、その一般的な形式は次のとおりです:
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
上記の設定は、Martian に対し、すべてのレスポンスに名前 "Test-Header"、値 "true" のヘッダーを注入するよう指示します。
このメッセージの各部分を見ていきましょう。
[package.Type]: 使用したいモディファイアの package.Type です。この場合、それが "header.Modifier" で、これはヘッダーを設定するモディファイアの名前です(header.Modifier の詳細については、モディファイアリファレンス を参照してください)。
[package.Type].scope: モディファイアをリクエスト、レスポンス、またはその両方のどれに適用するかを示します。"request"、"response"、またはその両方を含む配列を指定できます。
[package.Type].[key]: モディファイア固有のデータです。header モディファイアの場合、ヘッダーの name と value が必要です。
これは単純な設定です。より複雑な設定では、モディファイアをグループやフィルターと組み合わせて、目的の動作を構成します。
Martian を設定するには、JSON を http://martian.proxy/modifiers に POST します。HTTP リクエストを行うには、お好みの言語で提供されている任意の仕組みを使用してください。ただし、デモ目的であれば curl で十分です(設定が modifier.json というファイルに保存されている場合)。
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
Martian は、設定されていれば HTTPS リクエストとレスポンスの変更をサポートします。
Martian が HTTPS トラフィックを傍受するには、接続警告が表示されないように、カスタム CA 証明書をブラウザにインストールする必要があります。
CA 証明書をインストールする最も簡単な方法は、-cert フラグと -key フラグを使用してカスタム CA 証明書と秘密鍵を利用するために必要なフラグを付けてプロキシを起動するか、-generate-ca-cert フラグを使用してプロキシに証明書を生成させることです。
プロキシの起動後、プロキシを使用するように設定されたブラウザで http://martian.proxy/authority.cer にアクセスすると、証明書をインストールするためのプロンプトが表示されます。
MITM 機能の設定に役立ついくつかのフラグが examples/main.go で利用できます:
-key=""
PEM encoded private key file of the CA certificate provided in -cert; used
to sign certificates that are generated on-the-fly
-cert=""
PEM encoded CA certificate file used to generate certificates
-generate-ca-cert=false
generates a CA certificate and private key to use for man-in-the-middle;
most users choosing this option will immediately visit
http://martian.proxy/authority.cer in the browser whose traffic is to be
intercepted to install the newly generated CA certificate
-organization="Martian Proxy"
organization name set on the dynamically-generated certificates during
man-in-the-middle
-validity="1h"
window of time around the time of request that the dynamically-generated
certificate is valid for; the duration is set such that the total valid
timeframe is double the value of validity (1h before & 1h after)
Martian が特定の URL へのレスポンスに特定のヘッダーが存在することを検証するように設定したと仮定します。
example.com へのすべてのリクエストが 200 OK のレスポンスを返すことを検証するための設定は次のとおりです。
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
Martian が起動して設定され、検証したいリクエストとその結果のレスポンスが発生したら、200 OK レスポンスのみが返ってきたという期待を検証できます。
検証を確認するには、次を実行します:
GET http://martian.proxy/verify
失敗した期待はエラーとして追跡され、エラーのリストは host:port/martian/verify への GET リクエストで取得されます。これによりエラーのリストが返されます:
{
"errors" : [
{
"message": "response(http://example.com) status code verify failure: got 500, want 200"
},
{
"message": "response(http://example.com/foo) status code verify failure: got 500, want 200"
}
]
}
検証エラーは、以下の操作で明示的にクリアされるまでメモリ内に保持されます:
POST http://martian.proxy/verify/reset
Martian は任意の Go プログラムに組み込んで、ライブラリとして使用することもできます。
Martian のリクエストとレスポンスの変更システムは、汎用的で拡張可能なように設計されています。設計目標は、ほぼすべての望ましい変更を構築できるように組み合わせることが可能な、個々のモディファイアの動作を提供することです。
Martian を使用して動作を構成する際には、以下の異なるタイプのインタラクションを理解している必要があります:
モディファイア、フィルター、グループはすべて、RequestModifier、ResponseModifier、または RequestResponseModifier(martian.go で定義)を実装します。
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
コード全体(およびこのドキュメント)では、"modifier" という言葉が、モディファイア、グループ、フィルターを包含する用語として使用されています。グループはリクエストやレスポンスを変更しませんが、それでも "modifier" と呼びます。
modifier インターフェースを実装するものはすべて Modifier と呼びます。
各モディファイアは、Martian に独自のパーサーを登録する必要があります。パーサーは、JSON メッセージをパースして、モディファイアインターフェースを実装する Go 構造体に変換する役割を担います。
Martian は、モディファイアパーサーを、実行時に構築される「文字列から関数へのマップ」として保持します。各モディファイアは、init() 内で parse.Register を呼び出してパーサーを登録する役割を担います。
parse.Register のシグネチャ:
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register は、package.Type の形式の文字列をキーとして受け取ります。たとえば、cookie_modifier はキー cookie.Modifier として自身を登録し、query_string_filter は querystring.Filter として自身を登録します。この文字列は、JSON 設定メッセージ内の name の値と同じです。
次の設定メッセージでは、header.Modifier が header_modifier.go の init() で header モディファイアが登録されるキーです。
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
header_modifier.go でのパーサー登録の例:
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
モディファイア、フィルター、またはベリファイアがまだ開発されていないユースケースをお考えの場合、Martian をあなたの特定のニーズに合わせて簡単に拡張できます。
モディファイアには必須の要素が2つあります:
これらのインターフェースを実装する任意の Go 構造体が modifier として機能できます。
Martian の使用方法に関する質問やコメント、機能の発表、設計に関する議論については、公開 Google Group (https://groups.google.com/forum/#!forum/martianproxy-users) をご覧ください。
セキュリティ関連の問題については、詳細なレポートを非公開のコアグループ ([email protected]) に送信してください。
これは Google の公式製品(実験的製品かどうかに関わらず)ではありません。たまたま Google が所有しているコードにすぎません。