google/martian
GitHub: google/martian
Martian 是一个可编程的 HTTP/HTTPS 代理库,专为测试场景中拦截、修改和验证网络流量而设计。
Stars: 2044 | Forks: 253
# Martian Proxy [](https://travis-ci.org/google/martian)
Martian Proxy 是一个可编程的 HTTP 代理,专为测试而设计。
如果您想实现以下需求,Martian 是一个绝佳的工具:
* 验证所有(或部分子集)请求是否安全
* 在网络层 Mock 外部服务
* 注入 header、修改 cookie 或对 HTTP 请求
和响应执行其他修改
* 验证 pingback 是否在您认为应该发生的时候发生
* 解密流量(需要在浏览器中安装 CA 证书)
借助 Go 的交叉编译优势,Martian 可以被部署到
任何 Go 能够作为目标平台的地方。
## 最新版本
v3.0.0
## 环境要求
Go 1.11
## 快速开始
### 安装
Martian Proxy 可以使用 `go install` 进行安装
```
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
```
### 启动 Proxy
假设您已经安装了 Martian,运行该 proxy 非常简单:
```
$GOPATH/bin/proxy
```
如果您想在 Martian 运行时查看系统日志,请传入详细程度
标志(flag):
```
$GOPATH/bin/proxy -v=2
```
默认情况下,Martian 将运行在 8080 端口,而 Martian API 将运行在 8181 端口。
可以通过标志(flag)指定端口:
```
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
```
### 日志记录
若要记录请求和响应,可以使用 [日志记录
modifier](https://github.com/google/martian/wiki/Modifier-Reference#logging),或者如果使用了 `-har` 标志,则可以使用 [HAR](http://www.softwareishard.com/blog/har-12-spec/) 日志。
#### HAR 日志
要在 Martian 中启用 HAR 日志,请使用 `-har` 标志调用该二进制文件:
```
$GOPATH/bin/proxy -har
```
如果启用了 `-har` 标志,将会提供两个与 HAR 相关的 endpoint:
```
GET http://martian.proxy/logs
```
将检索自上次重置以来该 proxy 接收到的所有请求和响应的 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" 的 header。
让我们分解一下此消息的各个部分:
* `[package.Type]`:您想使用的 modifier 的 package.Type。在
本例中,它是 "header.Modifier",即用于设置 header 的 modifier 的名称(要了解有关 `header.Modifier` 的更多信息,请
参阅 [modifier 参考文档](https://github.com/google/martian/wiki/Modifier-Reference))。
* `[package.Type].scope`:指示是否将 modifier 应用于
请求、响应或两者。这可以是一个包含 "request"、
"response" 或同时包含两者的数组。
* `[package.Type].[key]`:modifier 特定的数据。在 header
modifier 的情况下,我们需要该 header 的 `name` 和 `value`。
这是一个简单的配置;对于更复杂的配置,可以将 modifier
与 group 和 filter 结合使用,以组合出所需的行为。
要配置 Martian,请将 JSON `POST` 到 `http://martian.proxy/modifiers`。您会
想使用您所选语言提供的任何机制来发送
HTTP 请求,但出于演示目的,可以使用 curl(假设您的配置
位于一个名为 `modifier.json` 的文件中)。
```
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
```
### 拦截 HTTPS 请求和响应
如果进行了相应配置,Martian 支持修改 HTTPS 请求和响应。
为了让 Martian 拦截 HTTPS 流量,必须在浏览器中安装自定义 CA 证书,这样才不会显示连接警告。
安装 CA 证书最简单的方法是,使用
必要的标志启动 proxy,通过 `-cert`
和 `-key` 标志来使用自定义的 CA 证书和私钥;或者通过 `-generate-ca-cert`
标志让 proxy 生成一个。
在 proxy 启动后,在配置为使用该 proxy 的浏览器中访问 http://martian.proxy/authority.cer,系统将显示一个安装
证书的提示。
`examples/main.go` 中提供了几个标志,以帮助配置 MITM
功能:
```
-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)
```
### 检查 Verifier
假设您已经配置了 Martian,去验证对特定 URL 的响应中是否存在某个特定的
header。
以下是一个配置,用于验证对 `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 作为 Library 使用
Martian 也可以被引入到任何 Go 程序中,并作为 library 使用。
## 无尽的 Modifier
Martian 的请求和响应修改系统被设计为通用
且可扩展的。其设计目标是提供独立的 modifier
行为,通过排列组合这些行为可以构建出几乎任何所需的修改。
在使用 Martian 组合行为时,您需要熟悉
以下几种不同类型的交互:
* Modifier:更改请求或响应的状态
* Filter:有条件地允许其包含的 Modifier 执行
* Group:将多个 modifier 打包,按照在 group 中指定的顺序
执行
* Verifier:根据预期追踪网络流量
Modifier、Filter 和 Group 都实现了 `RequestModifier`、
`ResponseModifier` 或 `RequestResponseModifier`(定义在
[`martian.go`](https://github.com/google/martian/blob/master/martian.go)中)。
```
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
```
在整个代码库(以及本文档)中,您会看到 “modifier” 这个词
被用作一个统称,涵盖了 modifier、group 和 filter。即使
group 并不修改请求或响应,我们仍然将其称为
“modifier”。
我们将任何实现了 `modifier` 接口的事物都称为 Modifier。
### Parser 注册
每个 modifier 必须向 Martian 注册其自己的 parser。parser
负责将 JSON 消息解析为实现
modifier 接口的 Go struct。
Martian 将 modifier parser 保存为一个从字符串映射到函数的 map,并在
运行时构建出来。每个 modifier 负责通过在 `init()` 中调用 `parse.Register` 来注册其 parser。
parse.Register 的签名:
```
Register(name string, parseFunc func(b []byte) (interface{}, error))
```
Register 接受一个形式为 `package.Type` 的字符串作为 key。例如,
`cookie_modifier` 使用 key `cookie.Modifier` 进行注册,而
`query_string_filter` 使用 `querystring.Filter` 进行注册。此字符串与
JSON 配置消息中 `name` 的值相同。
在以下配置消息中,`header.Modifier` 是该 header
modifier 在 `header_modifier.go` 的 `init()` 中注册的名称。
```
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
```
来自 `header_modifier.go` 的 parser 注册示例:
```
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
```
### 添加自定义 Modifier
如果您遇到我们尚未开发出 modifier、filter 或
verifier 的用例,您可以轻松地根据您的特定需求扩展 Martian。
modifier 有两个必须满足的部分:
* 实现 modifier 接口
* 注册 parser
任何实现了这些接口的 Go struct 都可以充当 `modifier`。
## 联系方式
有关 Martian 的使用问题和建议、功能公告,或者
设计讨论,请访问我们的公开 Google Group:
https://groups.google.com/forum/#!forum/martianproxy-users。
对于与安全相关的问题,请向我们私密的核心
小组 martianproxy-core@googlegroups.com 发送详细的报告。
## 免责声明
这不是一个正式的 Google 产品(实验性的或其他形式的),它只是
恰好由 Google 拥有所有权的代码。
标签:EVTX分析, Go, HTTP/S, Ruby工具, 日志审计, 流量修改, 网络测试