Skip to content

Commit

Permalink
feat: 新增支持 MITM 配置,支持部分的启用 https 拦截以改善 w2 代理性能
Browse files Browse the repository at this point in the history
  • Loading branch information
renxia committed Mar 3, 2024
1 parent 8cad5da commit 98d3cd7
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ if [ ! -e w2.x-scripts.config.js ]; then
cp /usr/local/lib/node_modules/@lzwme/whistle.x-scripts/w2.x-scripts.config.sample.js w2.x-scripts.config.js
fi

w2 start -M capture
w2 start # -M capture
```

2. 进入 `/ql/data/scripts/whistle` 目录(若为 docker 方式安装,则进入对应映射目录下),参考 [w2.x-scripts.config.sample.js](./w2.x-scripts.config.sample.js) 新建/修改配置文件 `w2.x-scripts.config.js`
Expand Down
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
* @Description: 一个 whistle 插件, 用于自动抓取 cookie 并保存
*/

exports.server = require('./dist/server.js').default;
exports.rulesServer = require('./dist/rulesServer.js').rulesServer;
module.exports = require('./dist/index');

// exports.server = require('./dist/server.js').default;
// exports.rulesServer = require('./dist/rulesServer.js').rulesServer;
// exports.reqRead = require('./dist/reqRead').default;
// exports.reqWrite = require('./dist/reqWrite').default;
// exports.resRead = require('./dist/resRead').default;
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as server } from './server';
export { rulesServer } from './rulesServer';
export { tunnelRulesServer } from './tunnelRulesServer';
8 changes: 8 additions & 0 deletions src/lib/rulesManage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ function ruleFormat(rule: RuleItem) {

if (!rule.desc) rule.desc = `${rule.ruleId}_${rule.url || rule.method}`;

if (rule.mitm) {
if (!Array.isArray(rule.mitm)) rule.mitm = [rule.mitm];
rule.mitm = rule.mitm.filter(Boolean).map(d => {
if (typeof d === 'string' && d.includes('*')) return new RegExp(d.replace(/\*+/g, '([a-z:]+)'));
return d;
});
}

return rule;
}

Expand Down
27 changes: 24 additions & 3 deletions src/tunnelRulesServer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
export default (server: Whistle.PluginServer, options: Whistle.PluginOptions) => {
import { getConfig } from './lib/getConfig';
import { rulesManage } from './lib/rulesManage';

function mitmMatch(req: Whistle.PluginRequest) {
if (rulesManage.rules['res-body'].size === 0) return;

const host = (req.headers.host || new URL(req.originalReq.fullUrl).host).split(':')[0];
const resBodyRules = rulesManage.rules['res-body'].values();

for (const item of resBodyRules) {
if (item.mitm) {
const isMatch = (item.mitm as (string | RegExp)[]).some(d => (d instanceof RegExp ? d.test(host) : d === host));
if (isMatch) return host;
}
}
}

export function tunnelRulesServer(server: Whistle.PluginServer, _options: Whistle.PluginOptions) {
server.on('request', (req: Whistle.PluginRequest, res: Whistle.PluginResponse) => {
res.end();
const { isSNI, enableCapture } = req.originalReq;
if (enableCapture || !isSNI || getConfig().enableMITM === false) return res.end();

const host = mitmMatch(req);
host ? res.end(`${host} enable://intercept`) : res.end();
});
};
}
2 changes: 1 addition & 1 deletion tsconfig.cjs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"target": "ES2021"
},
"extends": "./tsconfig.json",
"include": ["src/server.ts", "src/rulesServer.ts", "src/init.ts", "typings"]
"include": ["src/index.ts", "src/init.ts", "typings"]
}
4 changes: 4 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export interface W2XScriptsConfig {
throttleTime?: number;
/** 缓存数据有效时长。单位秒。默认为 12 小时(12 * 60 * 60) */
cacheDuration?: number;
/** 是否启用 rule.mitm 配置。默认为 true。当无法在某些环境下安装 CA 证书时,可设置为 false 以禁用由 mitm 开启的 https 拦截 */
enableMITM?: boolean;
/** 自定义脚本规则 */
rules?: RuleItem[];
/** 指定规则集文件路径或所在目录,尝试从该列表加载自定义的规则集 */
Expand Down Expand Up @@ -93,6 +95,8 @@ export interface RuleItem {
on?: RuleRunOnType;
/** 禁用该规则 */
disabled?: boolean;
/** MITM 域名匹配配置。当 res-body 类型的规则命中时会启用 https 解析拦截(即使 whistle 默认没有启用 https 拦截)。推荐配置该项以选择性的启用 https 拦截,可提升代理性能与效率 */
mitm?: string | RegExp | (string | RegExp)[];
/** url 匹配规则 */
url?: string | RegExp | ((url: string, method: string, headers: IncomingHttpHeaders) => boolean);
/** 方法匹配。可选: post、get、put 等。设置为空或 ** 表示全部匹配。若不设置,默认为 post */
Expand Down

0 comments on commit 98d3cd7

Please sign in to comment.