
Martian은 사용자 지정 HTTP/S 프록시를 구축하기 위한 라이브러리입니다.
Martian Proxy는 테스트용으로 설계된 프로그래밍 가능한 HTTP 프록시입니다.
Martian은 다음과 같은 상황에서 사용하기 좋은 도구입니다:
Go의 크로스 컴파일 기능을 활용하여, Martian은 Go가 대상으로 하는 모든 곳에 배포할 수 있습니다.
v3.0.0
Go 1.11
Martian Proxy는 v3.0.0부터 Go 모듈을 지원합니다. 모듈을 지원하지 않는 Go 버전을 사용하는 경우 문제가 발생할 수 있습니다. Go 모듈을 지원하지 않는 최신 버전은 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 포트에서 실행되며, Martian API는 8181 포트에서 실행됩니다. 포트는 플래그를 통해 지정할 수 있습니다.
$GOPATH/bin/proxy -addr=:9999 -api-addr=:9898
요청 및 응답 로깅을 위해 로깅 수정자를 사용하거나, -har 플래그를 사용하면 HAR 로그를 사용할 수 있습니다.
Martian에서 HAR 로깅을 활성화하려면 -har 플래그와 함께 바이너리를 호출하세요.
$GOPATH/bin/proxy -har
-har 플래그가 활성화되면 두 개의 HAR 관련 엔드포인트를 사용할 수 있습니다.
GET http://martian.proxy/logs
마지막 초기화 이후 프록시에서 본 모든 요청 및 응답의 HAR 로그를 검색합니다.
DELETE http://martian.proxy/logs/reset
메모리 내 HAR 로그를 초기화합니다. 로그는 주기적으로 초기화하지 않으면 무한정 커집니다.
Martian이 실행되면 동작을 구성해야 합니다. 구성이 없으면 Martian은 요청이나 응답에 아무 작업도 하지 않고 프록시 역할만 합니다. 로깅이 활성화된 경우 추가 구성 없이 로깅이 수행됩니다.
Martian은 HTTP를 통해 전송되는 JSON 메시지로 구성되며, 일반적인 형식은 다음과 같습니다.
{
"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을 구성하려면 JSON을 http://martian.proxy/modifiers로 POST하세요. 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 인증서를 설치하는 가장 쉬운 방법은 -cert 및 -key 플래그를 사용하여 사용자 정의 CA 인증서와 개인 키를 사용하도록 프록시를 시작하거나, -generate-ca-cert 플래그를 사용하여 프록시가 인증서를 생성하도록 하는 것입니다.
프록시가 시작된 후, 프록시를 사용하도록 구성된 브라우저에서 http://martian.proxy/authority.cer를 방문하면 인증서 설치 프롬프트가 표시됩니다.
examples/main.go에는 MITM 기능을 구성하는 데 도움이 되는 여러 플래그가 있습니다.
-key=""
-cert에 제공된 CA 인증서의 PEM 인코딩 개인 키 파일; 즉석에서 생성되는 인증서 서명에 사용됨
-cert=""
인증서 생성에 사용되는 PEM 인코딩 CA 인증서 파일
-generate-ca-cert=false
중간자 공격에 사용할 CA 인증서 및 개인 키를 생성함; 이 옵션을 선택한 대부분의 사용자는 트래픽을 가로챌 브라우저에서 즉시 http://martian.proxy/authority.cer를 방문하여 새로 생성된 CA 인증서를 설치함
-organization="Martian Proxy"
중간자 공격 중 동적으로 생성된 인증서에 설정되는 조직 이름
-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 인터페이스를 구현하는 모든 것을 수정자(Modifier)라고 합니다.
각 수정자는 Martian에 자체 파서를 등록해야 합니다. 파서는 JSON 메시지를 구문 분석하여 수정자 인터페이스를 구현하는 Go 구조체로 변환합니다.
Martian은 런타임에 구축되는 문자열에서 함수로의 맵으로 수정자 파서를 보관합니다. 각 수정자는 init()에서 parse.Register를 호출하여 파서를 등록해야 합니다.
parse.Register의 시그니처:
Register(name string, parseFunc func(b []byte) (interface{}, error)) error
Register는 package.Type 형태의 키를 문자열로 받습니다. 예를 들어, cookie_modifier는 cookie.Modifier 키로 등록되고, query_string_filter는 querystring.Filter로 등록됩니다. 이 문자열은 JSON 구성 메시지에서 name 값과 동일합니다.
다음 구성 메시지에서 header.Modifier는 header_modifier.go의 init()에서 헤더 수정자가 등록된 방식입니다.
{
"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을 특정 요구에 맞게 쉽게 확장할 수 있습니다.
수정자에는 두 가지 필수 부분이 있습니다.
해당 인터페이스를 구현하는 모든 Go 구조체는 수정자(modifier) 역할을 할 수 있습니다.
Martian 사용 방법, 기능 공지 또는 설계 토론에 대한 질문과 의견은 공개 Google 그룹스 (https://groups.google.com/forum/#!forum/martianproxy-users)를 확인하세요.
보안 관련 문제는 비공개 핵심 그룹 ([email protected])으로 자세한 보고서를 보내주세요.
이것은 공식 Google 제품이 아닙니다 (실험적이거나 그 외의 경우). Google이 소유한 코드일 뿐입니다.