
Martian es una biblioteca para construir proxies HTTP/S personalizados
Martian Proxy es un proxy HTTP programable diseñado para ser utilizado en pruebas.
Martian es una gran herramienta para usar si quieres:
Aprovechando la compilación cruzada de Go, Martian puede desplegarse en cualquier lugar al que Go pueda apuntar.
v3.0.0
Go 1.11
Martian Proxy añadió soporte para Go modules desde la v3.0.0. Si usas una versión de Go que no soporta modules, esto te romperá. La última versión sin soporte para Go modules fue etiquetada como v2.1.0.
Martian Proxy se puede instalar usando go install
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
Asumiendo que has instalado Martian, ejecutar el proxy es tan simple como
$GOPATH/bin/proxy
Si quieres ver los registros del sistema mientras Martian se está ejecutando, pasa el indicador de verbosidad:
$GOPATH/bin/proxy -v=2
Por defecto, Martian se ejecutará en el puerto 8080, y la API de Martian se ejecutará en 8181 . El puerto puede especificarse mediante indicadores:
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
Para el registro de solicitudes y respuestas, hay un modificador de registro disponible, o registros HAR disponibles si se usa el indicador -har.
Para habilitar el registro HAR en Martian, llama al binario con el indicador -har:
$GOPATH/bin/proxy -har
Si el indicador -har ha sido habilitado, dos endpoints relacionados con HAR estarán disponibles:
GET http://martian.proxy/logs
Recuperará el registro HAR de todas las solicitudes y respuestas vistas por el proxy desde el último reinicio.
DELETE http://martian.proxy/logs/reset
Reiniciará el registro HAR en memoria. Ten en cuenta que el registro crecerá sin límite a menos que se reinicie periódicamente.
Una vez que Martian está en ejecución, necesitas configurar su comportamiento. Sin configuración, Martian solo actúa como proxy sin hacer nada con las solicitudes o respuestas. Si está habilitado, el registro se llevará a cabo sin configuración adicional.
Martian se configura mediante mensajes JSON enviados a través de HTTP que tienen la forma general de:
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
La configuración anterior le dice a Martian que inyecte una cabecera con el nombre "Test-Header" y el valor "true" en todas las respuestas.
Desglosemos las partes de este mensaje.
[package.Type]: El package.Type del modificador que quieras usar. En
este caso, es "header.Modifier", que es el nombre del modificador que
establece cabeceras (para aprender más sobre header.Modifier, consulta
la referencia de modificadores).
[package.Type].scope: Indica si se aplica el modificador a
solicitudes, respuestas o ambas. Puede ser un array que contenga "request",
"response" o ambas.
[package.Type].[key]: Datos específicos del modificador. En el caso del
modificador de cabecera, necesitamos el name y el value de la cabecera.
Esta es una configuración simple; para configuraciones más complejas, los modificadores se combinan con grupos y filtros para componer el comportamiento deseado.
Para configurar Martian, haz un POST del JSON a http://martian.proxy/modifiers. Querrás usar el mecanismo que tu lenguaje de programación preferido te ofrezca para hacer solicitudes HTTP, pero para fines de demostración, curl funciona (asumiendo que tu configuración está en un archivo llamado modifier.json).
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
Martian soporta la modificación de solicitudes y respuestas HTTPS si está configurado para hacerlo.
Para que Martian intercepte tráfico HTTPS, debe instalarse un certificado CA personalizado en el navegador para que no se muestren advertencias de conexión.
La forma más sencilla de instalar el certificado CA es iniciar el proxy con los indicadores necesarios para usar un certificado CA personalizado y una clave privada mediante los indicadores -cert y -key, o hacer que el proxy genere uno usando el indicador -generate-ca-cert.
Después de que el proxy se haya iniciado, visita http://martian.proxy/authority.cer en el navegador configurado para usar el proxy y se mostrará un aviso para instalar el certificado.
Hay varios indicadores disponibles en examples/main.go para ayudar a configurar la funcionalidad 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)
Supongamos que has configurado Martian para verificar la presencia de una cabecera específica en las respuestas a una URL específica.
Aquí tienes una configuración para verificar que todas las solicitudes a example.com devuelvan respuestas con un 200 OK.
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
Una vez que Martian está en ejecución, configurado y las solicitudes y respuestas resultantes que deseas verificar han tenido lugar, puedes verificar tu expectativa de que solo recibiste respuestas 200 OK.
Para comprobar las verificaciones, realiza
GET http://martian.proxy/verify
Las expectativas fallidas se rastrean como errores, y la lista de errores se recupera haciendo una solicitud GET a host:port/martian/verify, que devolverá una lista de errores:
{
"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"
}
]
}
Los errores de verificación se mantienen en memoria hasta que se borran explícitamente mediante
POST http://martian.proxy/verify/reset
Martian también puede incluirse en cualquier programa Go y usarse como biblioteca.
El sistema de modificación de solicitudes y respuestas de Martian está diseñado para ser general y extensible. El objetivo de diseño es proporcionar comportamientos de modificador individuales que puedan organizarse para construir casi cualquier modificación deseada.
Cuando trabajes con Martian para componer comportamientos, necesitarás familiarizarte con estos diferentes tipos de interacciones:
Los modificadores, filtros y grupos implementan todos RequestModifier, ResponseModifier o RequestResponseModifier (definidos en martian.go).
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
A lo largo del código (y de esta documentación) verás la palabra "modificador" utilizada como un término que engloba modificadores, grupos y filtros. Aunque un grupo no modifica una solicitud o respuesta, seguimos refiriéndonos a él como un "modificador".
Nos referimos a cualquier cosa que implemente la interfaz modifier como un Modificador.
Cada modificador debe registrar su propio parser en Martian. El parser es responsable de analizar un mensaje JSON en una estructura de Go que implemente una interfaz de modificador.
Martian almacena los parsers de modificadores como un mapa de cadenas a funciones que se construye en tiempo de ejecución. Cada modificador es responsable de registrar su parser con una llamada a parse.Register en init().
Firma de parse.Register:
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register recibe la clave como una cadena con la forma package.Type. Por ejemplo, cookie_modifier se registra con la clave cookie.Modifier y query_string_filter se registra como querystring.Filter. Esta cadena es la misma que el valor de name en el mensaje de configuración JSON.
En el siguiente mensaje de configuración, header.Modifier es la forma en que el modificador de cabecera se registra en el init() de header_modifier.go.
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
Ejemplo de registro de parser desde header_modifier.go:
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
Si tienes en mente un caso de uso para el que no hayamos desarrollado modificadores, filtros o verificadores, puedes extender fácilmente Martian a tus necesidades muy específicas.
Hay 2 partes obligatorias en un modificador:
Cualquier estructura de Go que implemente esas interfaces puede actuar como un modifier.
Para preguntas y comentarios sobre cómo usar Martian, anuncios de funcionalidades o discusiones de diseño, consulta nuestro grupo público de Google en https://groups.google.com/forum/#!forum/martianproxy-users.
Para problemas relacionados con la seguridad, envía un informe detallado a nuestro grupo central privado en [email protected].
Esto no es un producto oficial de Google (experimental o de otro tipo), es solo código que resulta ser propiedad de Google.