
Martian est une bibliothèque pour construire des proxys HTTP/S personnalisés.
Martian Proxy est un proxy HTTP programmable conçu pour être utilisé lors de tests.
Martian est un excellent outil à utiliser si vous souhaitez :
En tirant parti de la compilation croisée de Go, Martian peut être déployé partout où Go peut cibler.
v3.0.0
Go 1.11
Martian Proxy a ajouté la prise en charge des modules Go depuis la v3.0.0. Si vous utilisez une version de Go qui ne prend pas en charge les modules, cela ne fonctionnera plus. La dernière version sans prise en charge des modules Go est la v2.1.0.
Martian Proxy peut être installé à l'aide de go install
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
En supposant que vous ayez installé Martian, exécuter le proxy est aussi simple que
$GOPATH/bin/proxy
Si vous souhaitez voir les journaux système pendant que Martian s'exécute, ajoutez le drapeau de verbosité :
$GOPATH/bin/proxy -v=2
Par défaut, Martian s'exécutera sur le port 8080 et l'API Martian s'exécutera sur le port 8181 . Le port peut être spécifié via des drapeaux :
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
Pour la journalisation des requêtes et réponses, un modificateur de journalisation est disponible ou des journaux HAR sont disponibles si le drapeau -har est utilisé.
Pour activer la journalisation HAR dans Martian, appelez le binaire avec le drapeau -har :
$GOPATH/bin/proxy -har
Si le drapeau -har a été activé, deux points de terminaison liés à HAR seront disponibles :
GET http://martian.proxy/logs
Récupère le journal HAR de toutes les requêtes et réponses vues par le proxy depuis la dernière réinitialisation.
DELETE http://martian.proxy/logs/reset
Réinitialise le journal HAR en mémoire. Notez que le journal grandira sans limite sauf s'il est périodiquement réinitialisé.
Une fois Martian en cours d'exécution, vous devez configurer son comportement. Sans configuration, Martian se contente de faire office de proxy sans modifier les requêtes ou les réponses. Si elle est activée, la journalisation aura lieu sans configuration supplémentaire.
Martian est configuré par des messages JSON envoyés via HTTP qui prennent la forme générale de :
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
La configuration ci-dessus indique à Martian d'injecter un en-tête nommé "Test-Header" avec la valeur "true" sur toutes les réponses.
Décomposons les parties de ce message.
[package.Type]: Le package.Type du modificateur que vous souhaitez utiliser. Dans ce cas, c'est "header.Modifier", qui est le nom du modificateur qui définit les en-têtes (pour en savoir plus sur le header.Modifier, veuillez vous référer à la référence des modificateurs).
[package.Type].scope: Indique si le modificateur doit être appliqué aux requêtes, aux réponses ou aux deux. Cela peut être un tableau contenant "request", "response" ou les deux.
[package.Type].[key]: Données spécifiques au modificateur. Dans le cas du modificateur d'en-tête, nous avons besoin du name et du value de l'en-tête.
Ceci est une configuration simple ; pour des configurations plus complexes, les modificateurs sont combinés avec des groupes et des filtres pour composer le comportement souhaité.
Pour configurer Martian, faites un POST du JSON vers http://martian.proxy/modifiers. Vous souhaiterez utiliser le mécanisme que votre langage de prédilection vous offre pour effectuer des requêtes HTTP, mais à des fins de démonstration, curl fonctionne (en supposant que votre configuration se trouve dans un fichier nommé modifier.json).
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
Martian prend en charge la modification des requêtes et réponses HTTPS s'il est configuré pour cela.
Pour que Martian puisse intercepter le trafic HTTPS, un certificat CA personnalisé doit être installé dans le navigateur afin que les avertissements de connexion ne soient pas affichés.
Le moyen le plus simple d'installer le certificat CA est de démarrer le proxy avec les drapeaux nécessaires pour utiliser un certificat CA et une clé privée personnalisés via les drapeaux -cert et -key, ou de demander au proxy d'en générer un à l'aide du drapeau -generate-ca-cert.
Une fois le proxy démarré, visitez http://martian.proxy/authority.cer dans le navigateur configuré pour utiliser le proxy et une invite s'affichera pour installer le certificat.
Plusieurs drapeaux sont disponibles dans examples/main.go pour aider à configurer la fonctionnalité 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)
Supposons que vous avez configuré Martian pour vérifier la présence d'un en-tête spécifique dans les réponses à une URL spécifique.
Voici une configuration pour vérifier que toutes les requêtes vers example.com renvoient des réponses avec un 200 OK.
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
Une fois Martian en cours d'exécution, configuré, et une fois que les requêtes et les réponses résultantes que vous souhaitez vérifier ont eu lieu, vous pouvez vérifier votre attente de n'avoir reçu que des réponses 200 OK.
Pour contrôler les vérifications, effectuez
GET http://martian.proxy/verify
Les attentes non satisfaites sont enregistrées comme erreurs, et la liste des erreurs est récupérée en effectuant une requête GET vers host:port/martian/verify, qui renverra une liste d'erreurs :
{
"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"
}
]
}
Les erreurs de vérification sont conservées en mémoire jusqu'à ce qu'elles soient explicitement effacées par
POST http://martian.proxy/verify/reset
Martian peut également être inclus dans n'importe quel programme Go et utilisé comme bibliothèque.
Le système de modification des requêtes et réponses de Martian est conçu pour être général et extensible. L'objectif de conception est de fournir des comportements de modificateurs individuels qui peuvent être arrangés pour construire presque n'importe quelle modification souhaitée.
Lorsque vous travaillez avec Martian pour composer des comportements, vous devez vous familiariser avec ces différents types d'interactions :
Les modificateurs, filtres et groupes implémentent tous RequestModifier, ResponseModifier ou RequestResponseModifier (définis dans martian.go).
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
Dans tout le code (et cette documentation), vous verrez le mot « modificateur » utilisé comme terme qui englobe les modificateurs, les groupes et les filtres. Même si un groupe ne modifie pas une requête ou une réponse, nous le désignons toujours comme un « modificateur ».
Nous désignons toute chose qui implémente l'interface modifier comme un Modificateur.
Chaque modificateur doit enregistrer son propre parseur auprès de Martian. Le parseur est responsable de l'analyse d'un message JSON dans une structure Go qui implémente une interface de modificateur.
Martian conserve les parseurs de modificateurs comme une map de chaînes vers des fonctions qui est construite au moment de l'exécution. Chaque modificateur est responsable de l'enregistrement de son parseur avec un appel à parse.Register dans init().
Signature de parse.Register :
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register prend la clé sous forme de chaîne dans le format package.Type. Par exemple, cookie_modifier s'enregistre avec la clé cookie.Modifier et query_string_filter s'enregistre sous querystring.Filter. Cette chaîne est la même que la valeur de name dans le message de configuration JSON.
Dans le message de configuration suivant, header.Modifier est la manière dont le modificateur d'en-tête est enregistré dans le init() de header_modifier.go.
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
Exemple d'enregistrement de parseur depuis header_modifier.go :
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
Si vous avez un cas d'utilisation en tête pour lequel nous n'avons pas développé de modificateurs, de filtres ou de vérificateurs, vous pouvez facilement étendre Martian à vos besoins très spécifiques.
Il y a 2 parties obligatoires dans un modificateur :
Toute structure Go qui implémente ces interfaces peut agir comme un modifier.
Pour les questions et commentaires sur la façon d'utiliser Martian, les annonces de fonctionnalités ou les discussions de conception, consultez notre groupe Google public à l'adresse https://groups.google.com/forum/#!forum/martianproxy-users.
Pour les problèmes liés à la sécurité, veuillez envoyer un rapport détaillé à notre groupe principal privé à [email protected].
Ce n'est pas un produit officiel de Google (expérimental ou autre), c'est simplement du code qui se trouve appartenir à Google.