AnyProxy

+
+

本文档的适用范围是AnyProxy 4.0,此版本当前正在beta中,欢迎提供反馈

+
+

AnyProxy是一个开放式的HTTP代理服务器。

+

Github主页:https://github.com/alibaba/anyproxy/tree/4.x

+

主要特性包括:

+ +

相比3.x版本,AnyProxy 4.0的主要变化:

+ +

+

快速上手

+

安装

+
npm install -g anyproxy@beta #本文档对应的AnyProxy为4.0Beta版

启动

+ +
anyproxy
+

其他命令

+ +
anyproxy --port 1080

代理https请求

+ +
+

解析https请求的原理是中间人攻击(man-in-the-middle),用户必须信任AnyProxy生成的CA证书,才能进行后续流程

+
+ +
anyproxy-ca #生成rootCA证书,生成后需要手动信任
+anyproxy --intercept #启动AnyProxy,并解析所有https请求
+

规则模块(Rule)

+

AnyProxy提供了二次开发的能力,你可以用js编写自己的规则模块(rule),来自定义网络请求的处理逻辑。

+
+

注意:引用规则前,请务必确保文件来源可靠,以免发生安全问题

+
+

规则模块的能力范围包括:

+ +

开发示例

+ +

处理流程

+ +

+

如何引用

+

如下几种方案都可以用来引用规则模块:

+ +

接口详解

+

规则模块应该符合cmd规范,一个典型的规则模块代码结构如下

+
module.exports = {
+  summary() { return 'my customized rule for AnyProxy'; },
+  *beforeSendRequest(requestDetail) { /* ... */ },
+  *beforeSendResponse(requestDetail, responseDetail) { /* ... */ },
+  *beforeDealHttpsRequest(requestDetail) { /* ... */ }
+};

summary()

+ +

beforeSendRequest(requestDetail)

+ +

beforeSendResponse(requestDetail, responseDetail)

+ +

beforeDealHttpsRequest(requestDetail)

+ +

FAQ

+ +

规则模块样例

+ +

使用本地数据

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_use_local_response.js
/* 
+  sample: 
+    intercept all requests toward httpbin.org, use a local response
+  start proyx:
+    anyproxy --rule sample_use_local_response.js
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    const localResponse = {
+      statusCode: 200,
+      header: { 'Content-Type': 'application/json' },
+      body: '{"hello": "this is local response"}'
+    };
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      return {
+        response: localResponse
+      };
+    }
+  },
+};

修改请求头

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_header.js
/* 
+  sample: 
+    modify the user-agent in requests toward httpbin.org
+  start proyx:
+    anyproxy --rule sample_modify_request_header.js
+  test:
+    curl http://httpbin.org/user-agent --proxy http://127.0.0.1:8001
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers['User-Agent'] = 'AnyProxy/0.0.0';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

修改请求数据

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_data.js
/* 
+  sample: 
+    modify the post data towards http://httpbin.org/post
+  start proyx:
+    anyproxy --rule sample_modify_request_data.js
+  test:
+    curl http://httpbin.org/ --proxy http://127.0.0.1:8001
+  expected response:
+    { "data": "i-am-anyproxy-modified-post-data" }
+
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.headers['User-Agent'] = 'AnyProxy/0.0.0';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

修改请求的目标地址

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_path.js
/* 
+  sample: 
+    redirect all httpbin.org requests to http://httpbin.org/user-agent
+  start proyx:
+    anyproxy --rule sample_modify_request_path.js
+  test:
+    curl http://httpbin.org/any-path --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newRequestOptions = requestDetail.requestOptions;
+      newRequestOptions.path = '/user-agent';
+      newRequestOptions.method = 'GET';
+      return {
+        requestOptions: newRequestOptions
+      };
+    }
+  },
+};

修改请求协议

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_request_protocol.js
/* 
+  sample: 
+    redirect all http requests of httpbin.org to https
+  start proyx:
+    anyproxy --rule sample_modify_request_protocol.js
+  test:
+    curl 'http://httpbin.org/get?show_env=1' --proxy http://127.0.0.1:8001
+  expected response:
+    { "X-Forwarded-Protocol": "https" }
+*/
+module.exports = {
+  *beforeSendRequest(requestDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newOption = requestDetail.requestOptions;
+      newOption.port = 443;
+      return {
+        protocol: 'https',
+        requestOptions: newOption
+      };
+    }
+  }
+};

修改返回状态码

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_statuscode.js
/* 
+  sample: 
+    modify all status code of http://httpbin.org/ to 404
+  start proyx:
+    anyproxy --rule sample_modify_response_statuscode.js
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    HTTP/1.1 404 Not Found
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.statusCode = 404;
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

修改返回头

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_header.js
/* 
+  sample: 
+    modify response header of http://httpbin.org/user-agent
+  start proyx:
+    anyproxy --rule sample_modify_response_header.js
+  test:
+    curl -I 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    X-Proxy-By: AnyProxy
+*/
+module.exports = {
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url.indexOf('http://httpbin.org/user-agent') === 0) {
+      const newResponse = responseDetail.response;
+      newResponse.header['X-Proxy-By'] = 'AnyProxy';
+      return {
+        response: newResponse
+      };
+    }
+  }
+};

修改返回内容并延迟

+ +
anyproxy --rule https://raw.githubusercontent.com/alibaba/anyproxy/4.x/rule_sample/sample_modify_response_data.js
/* 
+  sample: 
+    modify response data of http://httpbin.org/user-agent
+  start proyx:
+    anyproxy --rule sample.js
+  test:
+    curl 'http://httpbin.org/user-agent' --proxy http://127.0.0.1:8001
+  expected response:
+    { "user-agent": "curl/7.43.0" } -- AnyProxy Hacked! --
+*/
+
+module.exports = {
+  summary() { return 'a rule to modify response'; },
+  *beforeSendResponse(requestDetail, responseDetail) {
+    if (requestDetail.url === 'http://httpbin.org/user-agent') {
+      const newResponse = responseDetail.response;
+      newResponse.body += '-- AnyProxy Hacked! --';
+      return new Promise((resolve, reject) => {
+        setTimeout(() => { // delay the response for 5s
+          resolve({ response: newResponse });
+        }, 5000);
+      });
+    }
+  },
+};

作为npm模块使用

+

AnyProxy可以作为一个npm模块使用,整合进其他工具。 +注意:如要启用https解析,请在代理服务器启动前自行调用AnyProxy.utils.certMgr相关方法生成证书,并引导用户信任安装。

+ +
npm i anyproxy --save
+
const AnyProxy = require('anyproxy');
+const options = {
+  port: 8001,
+  rule: require('myRuleModule'),
+  webInterface: {
+    enable: true,
+    webPort: 8002,
+    wsPort: 8003,
+  },
+  throttle: 10000,
+  forceProxyHttps: false,
+  silent: false
+};
+const proxyServer = new AnyProxy.ProxyServer(options);
+
+proxyServer.on('ready', () => { /* */ });
+proxyServer.on('error', (e) => { /* */ });
+proxyServer.start();
+
+//when finished
+proxyServer.close();
+

关于AnyProxy

+ +

配置帮助

+

OSX系统信任CA证书

+ +

+
+

警告:CA证书和系统安全息息相关,建议亲自生成,并妥善保管

+
+

安装CA:

+ +

+ +

+

Windows系统信任CA证书

+

+

配置OSX系统代理

+ +

+

配置浏览器HTTP代理

+ +

+

配置iOS/Android系统代理

+ +

+ +

+