
Martian è una libreria per costruire proxy HTTP/S personalizzati.
Martian Proxy è un proxy HTTP programmabile progettato per essere utilizzato nei test.
Martian è un ottimo strumento da usare se vuoi:
Grazie alla cross-compilazione di Go, Martian può essere distribuito ovunque Go possa essere eseguito.
v3.0.0
Go 1.11
Martian Proxy ha aggiunto il supporto per i Go modules dalla v3.0.0. Se usi una versione di Go che non supporta i moduli, questo ti causerà problemi. L'ultima versione senza supporto per i Go modules è stata taggata v2.1.0.
Martian Proxy può essere installato usando go install:
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
Supponendo che tu abbia installato Martian, eseguire il proxy è semplice come:
$GOPATH/bin/proxy
Se vuoi vedere i log di sistema mentre Martian è in esecuzione, passa il flag di verbosità:
$GOPATH/bin/proxy -v=2
Per impostazione predefinita, Martian verrà eseguito sulla porta 8080 e l'API di Martian sarà in esecuzione sulla 8181 . La porta può essere specificata tramite flag:
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
Per il logging di richieste e risposte è disponibile un modifier di
logging
oppure sono disponibili i log HAR
se viene utilizzato il flag -har.
Per abilitare i log HAR in Martian, esegui il binario con il flag -har:
$GOPATH/bin/proxy -har
Se il flag -har è stato abilitato, saranno disponibili due endpoint correlati a HAR:
GET http://martian.proxy/logs
Recupera il log HAR di tutte le richieste e risposte viste dal proxy dall'ultimo reset.
DELETE http://martian.proxy/logs/reset
Reimposta il log HAR in memoria. Nota che il log crescerà senza limiti a meno che non venga reimpostato periodicamente.
Una volta che Martian è in esecuzione, devi configurare il suo comportamento. Senza configurazione, Martian si limita a fare da proxy senza fare nulla alle richieste o alle risposte. Se abilitato, il logging avverrà senza ulteriori configurazioni.
Martian viene configurato tramite messaggi JSON inviati su HTTP che assumono la forma generale di:
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
La configurazione sopra indica a Martian di iniettare un header con il nome "Test-Header" e il valore "true" su tutte le risposte.
Analizziamo le parti di questo messaggio.
[package.Type]: Il package.Type del modifier che vuoi utilizzare. In
questo caso, è "header.Modifier", che è il nome del modifier che
imposta gli header (per saperne di più sul header.Modifier,
consulta il riferimento dei modifier).
[package.Type].scope: Indica se applicare il modifier alle
richieste, alle risposte o a entrambe. Può essere un array contenente "request",
"response", o entrambi.
[package.Type].[key]: Dati specifici del modifier. Nel caso del modifier
header, abbiamo bisogno del name e del value dell'header.
Questa è una configurazione semplice; per configurazioni più complesse, i modifier vengono combinati con gruppi e filtri per comporre il comportamento desiderato.
Per configurare Martian, fai POST del JSON a http://martian.proxy/modifiers. Dovrai
usare il meccanismo che il tuo linguaggio preferito ti fornisce per effettuare
richieste HTTP, ma a scopo dimostrativo, curl funziona (supponendo che la tua
configurazione sia in un file chiamato modifier.json).
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
Martian supporta la modifica di richieste e risposte HTTPS se configurato per farlo.
Affinché Martian possa intercettare il traffico HTTPS, un certificato CA personalizzato deve essere installato nel browser in modo che gli avvisi di connessione non vengano mostrati.
Il modo più semplice per installare il certificato CA è avviare il proxy con i
flag necessari per utilizzare un certificato CA personalizzato e una chiave privata
usando i flag -cert e -key, oppure fare in modo che il proxy ne generi uno
usando il flag -generate-ca-cert.
Dopo che il proxy è stato avviato, visita http://martian.proxy/authority.cer nel browser configurato per usare il proxy e verrà visualizzato un prompt per installare il certificato.
Diversi flag sono disponibili in examples/main.go per aiutare a configurare la
funzionalità 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)
Supponiamo che tu abbia configurato Martian per verificare la presenza di un header specifico nelle risposte a un URL specifico.
Ecco una configurazione per verificare che tutte le richieste a example.com
restituiscano risposte con un 200 OK.
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
Una volta che Martian è in esecuzione, configurato e le richieste e le risposte
risultanti che desideri verificare sono avvenute, puoi verificare la tua aspettativa
di aver ricevuto solo risposte 200 OK.
Per controllare le verifiche, esegui:
GET http://martian.proxy/verify
Le aspettative non soddisfatte vengono tracciate come errori e l'elenco degli errori
viene recuperato effettuando una richiesta GET a host:port/martian/verify,
che restituirà un elenco di errori:
{
"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"
}
]
}
Gli errori di verifica vengono mantenuti in memoria finché non vengono esplicitamente cancellati tramite:
POST http://martian.proxy/verify/reset
Martian può anche essere incluso in qualsiasi programma Go e usato come libreria.
Il sistema di modifica di richieste e risposte di Martian è progettato per essere generale ed estensibile. L'obiettivo di progettazione è fornire comportamenti di modifier individuali che possono essere combinati per realizzare quasi qualsiasi modifica desiderata.
Quando lavori con Martian per comporre comportamenti, dovrai avere familiarità con questi diversi tipi di interazione:
Modifier, filtri e gruppi implementano tutti RequestModifier,
ResponseModifier o RequestResponseModifier (definiti in
martian.go).
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
In tutto il codice (e in questa documentazione) vedrai la parola "modifier" usata come termine che comprende modifier, gruppi e filtri. Anche se un gruppo non modifica una richiesta o una risposta, ci riferiamo comunque a esso come a un "modifier".
Ci riferiamo a qualsiasi cosa implementi l'interfaccia modifier come a un Modifier.
Ogni modifier deve registrare il proprio parser con Martian. Il parser è responsabile dell'analisi di un messaggio JSON in una struct Go che implementa un'interfaccia di modifier.
Martian conserva i parser dei modifier come una mappa di stringhe verso funzioni
che viene costruita al momento dell'esecuzione. Ogni modifier è responsabile della
registrazione del proprio parser con una chiamata a parse.Register in init().
Firma di parse.Register:
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register accetta la chiave come stringa nella forma package.Type. Per
esempio, cookie_modifier si registra con la chiave cookie.Modifier e
query_string_filter si registra come querystring.Filter. Questa stringa è
la stessa del valore di name nel messaggio di configurazione JSON.
Nel seguente messaggio di configurazione, header.Modifier è il modo in cui il
modifier header viene registrato nell'init() di header_modifier.go.
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
Esempio di registrazione del parser da header_modifier.go:
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
Se hai in mente un caso d'uso per il quale non abbiamo sviluppato modifier, filtri o verifier, puoi facilmente estendere Martian alle tue esigenze molto specifiche.
Ci sono 2 parti obbligatorie di un modifier:
Qualsiasi struct Go che implementa queste interfacce può agire come un modifier.
Per domande e commenti su come usare Martian, annunci di funzionalità o discussioni di progettazione, dai un'occhiata al nostro Google Group pubblico su https://groups.google.com/forum/#!forum/martianproxy-users.
Per problemi relativi alla sicurezza, invia una segnalazione dettagliata al nostro gruppo core privato all'indirizzo [email protected].
Questo non è un prodotto Google ufficiale (sperimentale o altro), è solo codice che risulta essere di proprietà di Google.