You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 10 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. # Martian Proxy [![Build Status](https://travis-ci.org/google/martian.svg?branch=master)](https://travis-ci.org/google/martian)
  2. Martian Proxy is a programmable HTTP proxy designed to be used for testing.
  3. Martian is a great tool to use if you want to:
  4. * Verify that all (or some subset) of requests are secure
  5. * Mock external services at the network layer
  6. * Inject headers, modify cookies or perform other mutations of HTTP requests
  7. and responses
  8. * Verify that pingbacks happen when you think they should
  9. * Unwrap encrypted traffic (requires install of CA certificate in browser)
  10. By taking advantage of Go cross-compilation, Martian can be deployed
  11. anywhere that Go can target.
  12. ## Requirements
  13. Go 1.9
  14. ## Getting Started
  15. ### Installation
  16. Martian Proxy can be installed using `go install`
  17. go get github.com/google/martian/ && \
  18. go install github.com/google/martian/cmd/proxy
  19. ### Start the Proxy
  20. Assuming you've installed Martian, running the proxy is as simple as
  21. $GOPATH/bin/proxy
  22. If you want to see system logs as Martian is running, pass in the verbosity
  23. flag:
  24. $GOPATH/bin/proxy -v=2
  25. By default, Martian will be running on port 8080, and the Martian API will be running on 8181
  26. . The port can be specified via flags:
  27. $GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
  28. ### Logging
  29. For logging of requests and responses a [logging
  30. modifier](https://github.com/google/martian/wiki/Modifier-Reference#logging) is
  31. available or [HAR](http://www.softwareishard.com/blog/har-12-spec/) logs are
  32. available if the `-har` flag is used.
  33. #### HAR Logging
  34. To enable HAR logging in Martian call the binary with the `-har` flag:
  35. $GOPATH/bin/proxy -har
  36. If the `-har` flag has been enabled two HAR related endpoints will be
  37. available:
  38. GET http://martian.proxy/logs
  39. Will retrieve the HAR log of all requests and responses seen by the proxy since
  40. the last reset.
  41. DELETE http://martian.proxy/logs/reset
  42. Will reset the in-memory HAR log. Note that the log will grow unbounded unless
  43. it is periodically reset.
  44. ### Configure
  45. Once Martian is running, you need to configure its behavior. Without
  46. configuration, Martian is just proxying without doing anything to the requests
  47. or responses. If enabled, logging will take place without additional
  48. configuration.
  49. Martian is configured by JSON messages sent over HTTP that take the general
  50. form of:
  51. {
  52. "header.Modifier": {
  53. "scope": ["response"],
  54. "name": "Test-Header",
  55. "value": "true"
  56. }
  57. }
  58. The above configuration tells Martian to inject a header with the name
  59. "Test-Header" and the value "true" on all responses.
  60. Let's break down the parts of this message.
  61. * `[package.Type]`: The package.Type of the modifier that you want to use. In
  62. this case, it's "header.Modifier", which is the name of the modifier that
  63. sets headers (to learn more about the `header.Modifier`, please
  64. refer to the [modifier reference](https://github.com/google/martian/wiki/Modifier-Reference)).
  65. * `[package.Type].scope`: Indicates whether to apply to the modifier to
  66. requests, responses or both. This can be an array containing "request",
  67. "response", or both.
  68. * `[package.Type].[key]`: Modifier specific data. In the case of the header
  69. modifier, we need the `name` and `value` of the header.
  70. This is a simple configuration, for more complex configurations, modifiers are
  71. combined with groups and filters to compose the desired behavior.
  72. To configure Martian, `POST` the JSON to `http://martian.proxy/modifiers`. You'll
  73. want to use whatever mechanism your language of choice provides you to make
  74. HTTP requests, but for demo purposes, curl works (assuming your configuration
  75. is in a file called `modifier.json`).
  76. curl -x localhost:8080 \
  77. -X POST \
  78. -H "Content-Type: application/json" \
  79. -d @modifier.json \
  80. "http://martian.proxy/configure"
  81. ### Intercepting HTTPS Requests and Responses
  82. Martian supports modifying HTTPS requests and responses if configured to do so.
  83. In order for Martian to intercept HTTPS traffic a custom CA certificate must be
  84. installed in the browser so that connection warnings are not shown.
  85. The easiest way to install the CA certificate is to start the proxy with the
  86. necessary flags to use a custom CA certificate and private key using the `-cert`
  87. and `-key` flags, or to have the proxy generate one using the `-generate-ca-cert`
  88. flag.
  89. After the proxy has started, visit http://martian.proxy/authority.cer in the
  90. browser configured to use the proxy and a prompt will be displayed to install
  91. the certificate.
  92. Several flags are available in `examples/main.go` to help configure MITM
  93. functionality:
  94. -key=""
  95. PEM encoded private key file of the CA certificate provided in -cert; used
  96. to sign certificates that are generated on-the-fly
  97. -cert=""
  98. PEM encoded CA certificate file used to generate certificates
  99. -generate-ca-cert=false
  100. generates a CA certificate and private key to use for man-in-the-middle;
  101. most users choosing this option will immediately visit
  102. http://martian.proxy/authority.cer in the browser whose traffic is to be
  103. intercepted to install the newly generated CA certificate
  104. -organization="Martian Proxy"
  105. organization name set on the dynamically-generated certificates during
  106. man-in-the-middle
  107. -validity="1h"
  108. window of time around the time of request that the dynamically-generated
  109. certificate is valid for; the duration is set such that the total valid
  110. timeframe is double the value of validity (1h before & 1h after)
  111. ### Check Verifiers
  112. Let's assume that you've configured Martian to verify the presence a specific
  113. header in responses to a specific URL.
  114. Here's a configuration to verify that all requests to `example.com` return
  115. responses with a `200 OK`.
  116. {
  117. "url.Filter": {
  118. "scope": ["request", "response"],
  119. "host" : "example.com",
  120. "modifier" : {
  121. "status.Verifier": {
  122. "scope" : ["response"],
  123. "statusCode": 200
  124. }
  125. }
  126. }
  127. }
  128. Once Martian is running, configured and the requests and resultant responses you
  129. wish to verify have taken place, you can verify your expectation that you only
  130. got back `200 OK` responses.
  131. To check verifications, perform
  132. GET http://martian.proxy/verify
  133. Failed expectations are tracked as errors, and the list of errors are retrieved
  134. by making a `GET` request to `host:port/martian/verify`, which will return
  135. a list of errors:
  136. {
  137. "errors" : [
  138. {
  139. "message": "response(http://example.com) status code verify failure: got 500, want 200"
  140. },
  141. {
  142. "message": "response(http://example.com/foo) status code verify failure: got 500, want 200"
  143. }
  144. ]
  145. }
  146. Verification errors are held in memory until they are explicitly cleared by
  147. POST http://martian.proxy/verify/reset
  148. ## Martian as a Library
  149. Martian can also be included into any Go program and used as a library.
  150. ## Modifiers All The Way Down
  151. Martian's request and response modification system is designed to be general
  152. and extensible. The design objective is to provide individual modifier
  153. behaviors that can arranged to build out nearly any desired modification.
  154. When working with Martian to compose behaviors, you'll need to be familiar with
  155. these different types of interactions:
  156. * Modifiers: Changes the state of a request or a response
  157. * Filters: Conditionally allows a contained Modifier to execute
  158. * Groups: Bundles multiple modifiers to be executed in the order specified in
  159. the group
  160. * Verifiers: Tracks network traffic against expectations
  161. Modifiers, filters and groups all implement `RequestModifer`,
  162. `ResponseModifier` or `RequestResponseModifier` (defined in
  163. [`martian.go`](https://github.com/google/martian/blob/master/martian.go)).
  164. ```go
  165. ModifyRequest(req *http.Request) error
  166. ModifyResponse(res *http.Response) error
  167. ```
  168. Throughout the code (and this documentation) you'll see the word "modifier"
  169. used as a term that encompasses modifiers, groups and filters. Even though a
  170. group does not modify a request or response, we still refer to it as a
  171. "modifier".
  172. We refer to anything that implements the `modifier` interface as a Modifier.
  173. ### Parser Registration
  174. Each modifier must register its own parser with Martian. The parser is
  175. responsible for parsing a JSON message into a Go struct that implements a
  176. modifier interface.
  177. Martian holds modifier parsers as a map of strings to functions that is built
  178. out at run-time. Each modifier is responsible for registering its parser with a
  179. call to `parse.Register` in `init()`.
  180. Signature of parse.Register:
  181. ```go
  182. Register(name string, parseFunc func(b []byte) (interface{}, error))
  183. ```
  184. Register takes in the key as a string in the form `package.Type`. For
  185. instance, `cookie_modifier` registers itself with the key `cookie.Modifier` and
  186. `query_string_filter` registers itself as `querystring.Filter`. This string is
  187. the same as the value of `name` in the JSON configuration message.
  188. In the following configuration message, `header.Modifier` is how the header
  189. modifier is registered in the `init()` of `header_modifier.go`.
  190. {
  191. "header.Modifier": {
  192. "scope": ["response"],
  193. "name" : "Test-Header",
  194. "value" : "true"
  195. }
  196. }
  197. Example of parser registration from `header_modifier.go`:
  198. ```go
  199. func init() {
  200. parse.Register("header.Modifier", modifierFromJSON)
  201. }
  202. func modifierFromJSON(b []byte) (interface{}, error) {
  203. ...
  204. }
  205. ```
  206. ### Adding Your Own Modifier
  207. If you have a use-case in mind that we have not developed modifiers, filters or
  208. verifiers for, you can easily extend Martian to your very specific needs.
  209. There are 2 mandatory parts of a modifier:
  210. * Implement the modifier interface
  211. * Register the parser
  212. Any Go struct that implements those interfaces can act as a `modifier`.
  213. ## Contact
  214. For questions and comments on how to use Martian, features announcements, or
  215. design discussions check out our public Google Group at
  216. https://groups.google.com/forum/#!forum/martianproxy-users.
  217. For security related issues please send a detailed report to our private core
  218. group at martianproxy-core@googlegroups.com.
  219. ## Disclaimer
  220. This is not an official Google product (experimental or otherwise), it is just
  221. code that happens to be owned by Google.