console.error('error when generating rootCA', error);
}
});
}
```
# Proxy Https
* AnyProxy does NOT intercept https requests by default. To view decrypted info, you have to config the CA certificate.
> Under the hood, AnyProxy decryptes https requests by man-in-the-middle attack. Users have to trust the CA cert in advance. Otherwise, client side will issue errors about unsecure network.
* generate certifycates and intercept
```bash
anyproxy-ca #generate root CA. manually trust it after that.
anyproxy --intercept #launch anyproxy and intercept all https traffic
```
* [Appendix:how to trust CA](#config-certification)
# Rule Introduction
AnyProxy provides the ability to load your own rules written in javascript. With rule module, you could customize the logic to handle requests.
> Make sure your rule file is got from a trusted source. Otherwise, you may face some unknown security risk.
Rule module could do the following stuff:
* intercept and modify the request which is being sent
* editable fields include request header, body, target address
* intercept and modify the response from server
* editable fields include response status code, header, body
* intercept https requests, modify request and response
### sample
* Target
* write a rule module to append some text to the response of GET http://httpbin.org/user-agent, and delay the response for 5 seconds
* When got an http request, the entire process of proxy server is
* AnyProxy collects all the quest info, include method, header, body
* AnyProxy calls `beforeSendRequest` of the rule module. Rule module deal the request, return new request param or response content
* If `beforeSendRequest` returns the response content, AnyProxy will send the response to client without sending to target server. The process ends here.
* Send request to target server, collect response
* Call `beforeSendResponse` of the rule module. Rule module deal the response data
* Send response to client
* When AnyProxy get https request, it could replace the certificate and decrypt the request data
* AnyProxy calls `beforeDealHttpsRequest` of the rule module
* If the function returns `true`, AnyProxy will do the man-in-the-middle attack to it. Otherwise, the request will not be dealed.
### how to load rule module
* use local file
```bash
anyproxy --rule ./rule.js
```
* use an online rule file
```bash
anyproxy --rule https://sample.com/rule.js
```
* use an npm module
* AnyProxy uses `require()` to load rule module. You could either load a local npm module or a global-installed one.
```bash
anyproxy --rule ./myRulePkg/ #local module
npm i -g myRulePkg && anyproxy --rule myRulePkg #global-installed module
```
# Rule module interface
A typical rule module is as follows. All the functions are optional, just write the part you are interested in.
> All functions in your rule file, except summary, are all driven by [co](https://www.npmjs.com/package/co) . They should be yieldable, i.e. return a promise or be a generator function.
### summary
#### summary
* Introduction of this rule file. AnyProxy will read this field and give some tip to user.
### beforeSendRequest
#### beforeSendRequest(requestDetail)
* Before sending request to server, AnyProxy will call `beforeSendRequest` with param `requestDetail`
*`requestDetail`
*`protocol` {string} the protocol to use, http or https
*`requestOptions` {object} the options of the request-to-go, a param of require('http').request . ref: https://nodejs.org/api/http.html#http_http_request_options_callback
*`requestData` {object} request body
*`url` {string} request url
*`_req` {object} the native node.js request object
* e.g. When requesting *anyproxy.io*, `requestDetail` is something like the following
```js
{
protocol: 'http',
url: 'http://anyproxy.io/',
requestOptions: {
hostname: 'anyproxy.io',
port: 80,
path: '/',
method: 'GET',
headers: {
Host: 'anyproxy.io',
'Proxy-Connection': 'keep-alive',
'User-Agent': '...'
}
},
requestData: '...',
_req: { /* ... */}
}
```
* Any of these return values are valid
* do nothing, and return null
```js
return null;
```
* modify the request protocol,i.e. force use https
```js
return {
protocol: 'https'
};
```
* modify request param
```js
var newOption = Object.assign({}, requestDetail.requestOptions);
newOption.path = '/redirect/to/another/path';
return {
requestOptions: newOption
};
```
* modify request body
```js
return {
requestData: 'my new request data'
// requestOptions can also be used here
};
```
* give response to the client, not sending request any longer. `statusCode``headers`are required is this situation.
* Besides installing root CA, you have to "turn on" the certificate for web manually in *settings - general - about - Certificate Trust Settings*. Otherwire, safari will not trust the root CA generated by AnyProxy.
First of all, you need to download the root CA by clicking *Root CA* in web ui, and then scan the QR code.
Installing CA in Android could be different based on the system, we list some common steps as below, but you can find the right way in you system with similar menu path.
* The downloaded CA file can be directly installed by clicking, this is the easist way
* You need to install the CA file from other menu, such as:
* Settings -> Security & Location > Encryption & credentials -> Install from storage, and find your CA file to install
* Settings -> Security -> Install from SD card, and find you CA file to install
* A: Any of these options could be used to change the way AnyProxy deall https requests
1. config `--intercept` when luanching AnyProxy via cli, or use `forceProxyHttps` when using as an npm module
2. place a `beforeDealHttpsRequest` function in your rule file and determine which request to intercept by your own.
### Q: get an error says *function is not yieldable*
* A: Rule module is driven by [co](https://www.npmjs.com/package/co). The functions inside should be yieldable, i.e. return a promise or be a generator function.
### Q: The connection is not private
AnyProxy will propmt this message when the certification of the site you're visiting is not issued by a common known CA. This happens when the certification is self-signed. If you know and trust it, you can ignore the error as below.
- If you run AnyProxy by command line
Pass in the option `--ignore-unauthorized-ssl` to ignore the certification errors, please mind that the option will be active for all connections.
```bash
anyproxy -i --ignore-unauthorized-ssl
```
- If you run AnyProxy by Nodejs
Pass in the option `dangerouslyIgnoreUnauthorized:true`, like this:
```js
const options = {
...,
dangerouslyIgnoreUnauthorized: true
};
const anyproxyIns = new AnyProxy.ProxyCore(options);
anyproxyIns.start();
```
*This is also a global option, all certification errors will be ignored*
- With the help of AnyProxy Rule
You can change the request with rule of course. For this scenario, all you need is to pass in an option to Nodejs `Http.rquest`, as we do in AnyProxy. A simple demo below:
```js
module.exports = {
*beforeSendRequest(requestDetail) {
if (requestDetail.url.indexOf('https://the-site-you-know.com') === 0) {