
Martian is a library for building custom HTTP/S proxies
Martian Proxy — это программируемый HTTP-прокси, предназначенный для использования в тестировании.
Martian — отличный инструмент, если вы хотите:
Благодаря кросскомпиляции Go, Martian можно развернуть везде, где поддерживается Go.
v3.0.0
Go 1.11
Martian Proxy добавил поддержку Go modules начиная с версии v3.0.0. Если вы используете версию Go, не поддерживающую модули, это нарушит работу. Последняя версия без поддержки Go modules была помечена как v2.1.0.
Martian Proxy можно установить с помощью go install
go get github.com/google/martian/ && \
go install github.com/google/martian/cmd/proxy
Предполагая, что вы установили Martian, запуск прокси выполняется просто:
$GOPATH/bin/proxy
Если вы хотите видеть системные логи во время работы Martian, передайте флаг подробного вывода:
$GOPATH/bin/proxy -v=2
По умолчанию Martian будет работать на порту 8080, а API Martian — на порту 8181. Порт можно задать через флаги:
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
Для логирования запросов и ответов доступен модификатор логирования, а также HAR логи, если используется флаг -har.
Чтобы включить HAR логирование в Martian, вызовите бинарник с флагом -har:
$GOPATH/bin/proxy -har
Если флаг -har включён, будут доступны две конечные точки, связанные с HAR:
GET http://martian.proxy/logs
Возвращает HAR-лог всех запросов и ответов, виденных прокси с момента последнего сброса.
DELETE http://martian.proxy/logs/reset
Сбрасывает HAR-лог в памяти. Обратите внимание, что лог будет расти бесконечно, если его периодически не сбрасывать.
После запуска Martian необходимо настроить его поведение. Без настройки Martian просто проксирует, не внося изменений в запросы или ответы. Если логирование включено, оно будет работать без дополнительной настройки.
Martian настраивается с помощью JSON-сообщений, отправляемых по HTTP, которые имеют общий вид:
{
"header.Modifier": {
"scope": ["response"],
"name": "Test-Header",
"value": "true"
}
}
Приведённая выше конфигурация указывает Martian внедрять заголовок с именем "Test-Header" и значением "true" во все ответы.
Разберём части этого сообщения.
[package.Type]: package.Type модификатора, который вы хотите использовать. В данном случае это "header.Modifier" — имя модификатора, устанавливающего заголовки (чтобы узнать больше о header.Modifier, обратитесь к справочнику модификаторов).
[package.Type].scope: Указывает, применять ли модификатор к запросам, ответам или к обоим. Может быть массивом, содержащим "request", "response" или оба.
[package.Type].[key]: Специфичные для модификатора данные. В случае модификатора заголовков нам нужны name и value заголовка.
Это простая конфигурация. Для более сложных конфигураций модификаторы объединяются с группами и фильтрами для составления желаемого поведения.
Чтобы настроить Martian, отправьте POST запрос с JSON на http://martian.proxy/modifiers. Вы можете использовать любой механизм для HTTP-запросов, доступный в вашем языке, но для демонстрации подойдёт curl (предполагая, что ваша конфигурация находится в файле modifier.json).
curl -x localhost:8080 \
-X POST \
-H "Content-Type: application/json" \
-d @modifier.json \
"http://martian.proxy/configure"
Martian поддерживает изменение HTTPS-запросов и ответов, если это настроено.
Для того чтобы Martian мог перехватывать HTTPS-трафик, в браузере должен быть установлен собственный CA-сертификат, чтобы не отображались предупреждения о соединении.
Самый простой способ установить CA-сертификат — запустить прокси с необходимыми флагами для использования собственного CA-сертификата и закрытого ключа с помощью флагов -cert и -key, или заставить прокси сгенерировать их с помощью флага -generate-ca-cert.
После запуска прокси перейдите по адресу http://martian.proxy/authority.cer в браузере, настроенном на использование прокси, и появится запрос на установку сертификата.
В examples/main.go доступно несколько флагов для настройки функциональности MITM:
-key=""
PEM-файл закрытого ключа CA-сертификата, предоставленного в -cert; используется
для подписи сертификатов, генерируемых на лету
-cert=""
PEM-файл CA-сертификата, используемого для генерации сертификатов
-generate-ca-cert=false
генерирует CA-сертификат и закрытый ключ для использования в man-in-the-middle;
большинство пользователей, выбравших эту опцию, сразу посетят
http://martian.proxy/authority.cer в браузере, чей трафик будет
перехватываться, чтобы установить вновь сгенерированный CA-сертификат
-organization="Martian Proxy"
название организации, устанавливаемое в динамически генерируемых сертификатах
во время man-in-the-middle
-validity="1h"
временное окно вокруг времени запроса, в течение которого динамически
генерируемый сертификат действителен; длительность устанавливается так, что общий
срок действия вдвое превышает значение validity (1 час до и 1 час после)
Допустим, вы настроили Martian проверять наличие определённого заголовка в ответах на определённый URL.
Вот конфигурация для проверки, что все запросы к example.com возвращают ответы с 200 OK.
{
"url.Filter": {
"scope": ["request", "response"],
"host" : "example.com",
"modifier" : {
"status.Verifier": {
"scope" : ["response"],
"statusCode": 200
}
}
}
}
После того как Martian запущен, настроен и выполнены запросы и соответствующие ответы, которые вы хотите проверить, вы можете убедиться, что получили только ответы 200 OK.
Для проверки выполните
GET http://martian.proxy/verify
Невыполненные ожидания отслеживаются как ошибки, и список ошибок можно получить, выполнив GET запрос к host:port/martian/verify, который вернёт список ошибок:
{
"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"
}
]
}
Ошибки верификации хранятся в памяти до тех пор, пока они не будут явно очищены с помощью
POST http://martian.proxy/verify/reset
Martian также может быть включён в любую программу на Go и использоваться как библиотека.
Система модификации запросов и ответов Martian спроектирована как общая и расширяемая. Цель дизайна — предоставить отдельные поведения модификаторов, которые можно комбинировать для построения практически любого желаемого изменения.
При работе с Martian для составления поведения вам потребуется ознакомиться с различными типами взаимодействий:
Модификаторы, фильтры и группы реализуют RequestModifier, ResponseModifier или RequestResponseModifier (определены в martian.go).
ModifyRequest(req *http.Request) error
ModifyResponse(res *http.Response) error
В коде (и в этой документации) вы увидите слово "модификатор", используемое как термин, охватывающий модификаторы, группы и фильтры. Хотя группа не изменяет запрос или ответ, мы всё равно называем её "модификатором".
Мы называем модификатором всё, что реализует интерфейс modifier.
Каждый модификатор должен зарегистрировать свой собственный парсер в Martian. Парсер отвечает за разбор JSON-сообщения в структуру Go, реализующую интерфейс модификатора.
Martian хранит парсеры модификаторов в виде карты строк в функции, которая строится во время выполнения. Каждый модификатор отвечает за регистрацию своего парсера вызовом parse.Register в init().
Сигнатура parse.Register:
Register(name string, parseFunc func(b []byte) (interface{}, error))
Register принимает ключ в виде строки в формате package.Type. Например, cookie_modifier регистрирует себя с ключом cookie.Modifier, а query_string_filter регистрируется как querystring.Filter. Эта строка совпадает со значением name в JSON-конфигурации.
В следующем сообщении конфигурации header.Modifier — это то, как модификатор заголовков регистрируется в init() в header_modifier.go.
{
"header.Modifier": {
"scope": ["response"],
"name" : "Test-Header",
"value" : "true"
}
}
Пример регистрации парсера из header_modifier.go:
func init() {
parse.Register("header.Modifier", modifierFromJSON)
}
func modifierFromJSON(b []byte) (interface{}, error) {
...
}
Если у вас есть вариант использования, для которого у нас нет разработанных модификаторов, фильтров или верификаторов, вы можете легко расширить Martian под свои специфические нужды.
У модификатора есть 2 обязательных части:
Любая структура Go, реализующая эти интерфейсы, может выступать в качестве modifier.
По вопросам и комментариям по использованию Martian, анонсам функций или обсуждениям дизайна присоединяйтесь к нашему открытому Google Group: https://groups.google.com/forum/#!forum/martianproxy-users.
По вопросам безопасности, пожалуйста, отправьте подробный отчёт в нашу частную основную группу: [email protected].
Это не официальный продукт Google (экспериментальный или иной), это просто код, который оказался принадлежащим Google.