
Martian é uma biblioteca para construir proxies HTTP/S personalizados.
Martian Proxy é um proxy HTTP programável projetado para ser usado em testes.
Martian é uma ótima ferramenta para usar se você quiser:
Aproveitando a compilação cruzada do Go, o Martian pode ser implantado em qualquer lugar que o Go possa segmentar.
v3.0.0
Go 1.11
O Martian Proxy adicionou suporte a Go Modules desde a v3.0.0. Se você usa uma versão do Go que não suporta módulos, isso vai quebrar. A última versão sem suporte a Go Modules foi a v2.1.0.
O Martian Proxy pode ser instalado usando go install
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
Supondo que você tenha instalado o Martian, executar o proxy é tão simples quanto
$GOPATH/bin/proxy
Se você quiser ver logs do sistema enquanto o Martian está em execução, passe a flag de verbosidade:
$GOPATH/bin/proxy -v=2
Por padrão, o Martian será executado na porta 8080, e a API do Martian será executada na 8181. A porta pode ser especificada via flags:
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
Para registro de requisições e respostas, um modifier de logging está disponível ou logs HAR estão disponíveis se a flag -har for usada.
Para habilitar o registro HAR no Martian, chame o binário com a flag -har:
$GOPATH/bin/proxy -har
Se a flag -har foi habilitada, dois endpoints relacionados a HAR estarão disponíveis:
GET http://martian.proxy/logs
Irá recuperar o log HAR de todas as requisições e respostas vistas pelo proxy desde o último reset.
DELETE http://martian.proxy/logs/reset
Irá redefinir o log HAR em memória. Observe que o log crescerá indefinidamente a menos que seja reiniciado periodicamente.
Uma vez que o Martian está em execução, você precisa configurar seu comportamento. Sem configuração, o Martian apenas faz proxy sem fazer nada nas requisições ou respostas. Se habilitado, o registro ocorrerá sem configuração adicional.
O Martian é configurado por mensagens JSON enviadas via HTTP que assumem a forma geral de:
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
A configuração acima diz ao Martian para injetar um cabeçalho com o nome "Test-Header" e o valor "true" em todas as respostas.
Vamos detalhar as partes desta mensagem.
[package.Type]: O package.Type do modificador que você deseja usar. Neste caso, é "header.Modifier", que é o nome do modificador que define cabeçalhos (para saber mais sobre o header.Modifier, consulte a referência de modificadores).[package.Type].scope: Indica se deve aplicar o modificador a requisições, respostas ou ambos. Pode ser um array contendo "request", "response" ou ambos.[package.Type].[key]: Dados específicos do modificador. No caso do modificador de cabeçalho, precisamos do name e value do cabeçalho.Esta é uma configuração simples, para configurações mais complexas, modificadores são combinados com grupos e filtros para compor o comportamento desejado.
Para configurar o Martian, faça um POST do JSON para http://martian.proxy/modifiers. Você vai querer usar o mecanismo que sua linguagem de escolha fornece para fazer requisições HTTP, mas para fins de demonstração, curl funciona (assumindo que sua configuração está em um arquivo chamado modifier.json).
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
O Martian suporta modificar requisições e respostas HTTPS se configurado para isso.
Para que o Martian intercepte tráfego HTTPS, um certificado CA personalizado deve ser instalado no navegador para que avisos de conexão não sejam exibidos.
A maneira mais fácil de instalar o certificado CA é iniciar o proxy com as flags necessárias para usar um certificado CA personalizado e chave privada usando as flags -cert e -key, ou fazer o proxy gerar um usando a flag -generate-ca-cert.
Após o proxy ter iniciado, visite http://martian.proxy/authority.cer no navegador configurado para usar o proxy e um prompt será exibido para instalar o certificado.
Várias flags estão disponíveis em examples/main.go para ajudar a configurar a funcionalidade MITM:
-key=""
Arquivo de chave privada codificada em PEM do certificado CA fornecido em -cert; usado
para assinar certificados que são gerados dinamicamente
-cert=""
Arquivo de certificado CA codificado em PEM usado para gerar certificados
-generate-ca-cert=false
Gera um certificado CA e chave privada para usar em man-in-the-middle;
a maioria dos usuários que escolherem esta opção visitará imediatamente
http://martian.proxy/authority.cer no navegador cujo tráfego será interceptado
para instalar o certificado CA recém-gerado
-organization="Martian Proxy"
Nome da organização definido nos certificados gerados dinamicamente durante
o man-in-the-middle
-validity="1h"
Janela de tempo ao redor do momento da requisição em que o certificado gerado
dinamicamente é válido; a duração é definida de forma que o período total válido
seja o dobro do valor de validade (1h antes & 1h depois)
Vamos supor que você configurou o Martian para verificar a presença de um cabeçalho específico em respostas para uma URL específica.
Aqui está uma configuração para verificar se todas as requisições para example.com retornam respostas com 200 OK.
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
Uma vez que o Martian está em execução, configurado e as requisições e respostas resultantes que você deseja verificar ocorreram, você pode verificar sua expectativa de que recebeu apenas respostas 200 OK.
Para verificar as verificações, execute
GET http://martian.proxy/verify
As expectativas falhas são rastreadas como erros, e a lista de erros é recuperada fazendo uma requisição GET para host:port/martian/verify, que retornará uma lista de erros:
{
"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"
}
]
}
Os erros de verificação são mantidos em memória até que sejam explicitamente limpos por
POST http://martian.proxy/verify/reset
O Martian também pode ser incluído em qualquer programa Go e usado como biblioteca.
O sistema de modificação de requisições e respostas do Martian é projetado para ser geral e extensível. O objetivo do design é fornecer comportamentos individuais de modificadores que podem ser organizados para construir quase qualquer modificação desejada.
Ao trabalhar com o Martian para compor comportamentos, você precisará estar familiarizado com estes diferentes tipos de interações:
Modificadores, filtros e grupos todos implementam RequestModifier, ResponseModifier ou RequestResponseModifier (definidos em martian.go).
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
Ao longo do código (e desta documentação) você verá a palavra "modifier" usada como um termo que abrange modificadores, grupos e filtros. Mesmo que um grupo não modifique uma requisição ou resposta, ainda nos referimos a ele como um "modifier".
Nos referimos a qualquer coisa que implemente a interface modifier como um Modifier.
Cada modificador deve registrar seu próprio parser no Martian. O parser é responsável por analisar uma mensagem JSON em uma struct Go que implementa uma interface de modificador.
O Martian mantém os parsers de modificadores como um mapa de strings para funções que é construído em tempo de execução. Cada modificador é responsável por registrar seu parser com uma chamada a parse.Register em init().
Assinatura do parse.Register:
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register recebe a chave como uma string no formato package.Type. Por exemplo, cookie_modifier se registra com a chave cookie.Modifier e query_string_filter se registra como querystring.Filter. Esta string é a mesma que o valor de name na mensagem de configuração JSON.
Na seguinte mensagem de configuração, header.Modifier é como o modificador de cabeçalho é registrado no init() de header_modifier.go.
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
Exemplo de registro de parser de header_modifier.go:
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
Se você tem um caso de uso em mente para o qual não desenvolvemos modificadores, filtros ou verificadores, você pode estender facilmente o Martian para suas necessidades muito específicas.
Há 2 partes obrigatórias de um modificador:
Qualquer struct Go que implemente essas interfaces pode atuar como um modifier.
Para perguntas e comentários sobre como usar o Martian, anúncios de funcionalidades ou discussões de design, confira nosso Grupo Público do Google em https://groups.google.com/forum/#!forum/martianproxy-users.
Para questões relacionadas à segurança, envie um relatório detalhado para nosso grupo central privado em [email protected].
Este não é um produto oficial do Google (experimental ou não), é apenas um código que pertence ao Google.