From bf84613f51a5b51a95f2c588fa19006420744995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Sun, 29 Sep 2024 13:12:49 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20=E4=BF=AE=E5=A4=8D=E5=9B=A0=20`HttpsA?= =?UTF-8?q?gent`=20=E4=B8=BA=E5=8D=95=E4=BE=8B=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=AF=B7=E6=B1=82=E6=97=B6=E5=9B=A0=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E4=BA=86SSL=E6=A0=A1=E9=AA=8C=E5=AF=BC=E8=87=B4=20pro?= =?UTF-8?q?xy=20=E6=88=96=20sni=20=E8=AF=B7=E6=B1=82=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/lib/interceptor/impl/req/proxy.js | 12 ++++++---- .../src/lib/interceptor/impl/req/sni.js | 13 +++++++---- .../mitmproxy/src/lib/proxy/common/util.js | 23 +++++++++++++++---- .../proxy/mitmproxy/createRequestHandler.js | 6 ----- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/mitmproxy/src/lib/interceptor/impl/req/proxy.js b/packages/mitmproxy/src/lib/interceptor/impl/req/proxy.js index ab8847f47..39d66f032 100644 --- a/packages/mitmproxy/src/lib/interceptor/impl/req/proxy.js +++ b/packages/mitmproxy/src/lib/interceptor/impl/req/proxy.js @@ -116,12 +116,16 @@ module.exports = { } if (interceptOpt.sni != null) { + let unVerifySsl = rOptions.agent.options.rejectUnauthorized === false + rOptions.servername = interceptOpt.sni - if (rOptions.agent && rOptions.agent.options) { - rOptions.agent.options.rejectUnauthorized = false + if (rOptions.agent.options.rejectUnauthorized && rOptions.agent.unVerifySslAgent) { + // rOptions.agent.options.rejectUnauthorized = false // 不能直接在agent上进行修改属性值,因为它采用了单例模式,所有请求共用这个对象的 + rOptions.agent = rOptions.agent.unVerifySslAgent + unVerifySsl = true } - res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}`) - log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername) + res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}, sni: ${interceptOpt.sni}`, (unVerifySsl ? ', unVerifySsl' : '')) + log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget, ', sni replace servername:', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : '')) } else { res.setHeader('DS-Interceptor', `proxy: ${proxyTarget}`) log.info('proxy intercept: hostname:', originHostname, ', target:', proxyTarget) diff --git a/packages/mitmproxy/src/lib/interceptor/impl/req/sni.js b/packages/mitmproxy/src/lib/interceptor/impl/req/sni.js index a60c04f24..0455286b3 100644 --- a/packages/mitmproxy/src/lib/interceptor/impl/req/sni.js +++ b/packages/mitmproxy/src/lib/interceptor/impl/req/sni.js @@ -4,14 +4,17 @@ module.exports = { requestIntercept (context, interceptOpt, req, res, ssl, next) { const { rOptions, log } = context + let unVerifySsl = rOptions.agent.options.rejectUnauthorized === false + rOptions.servername = interceptOpt.sni - if (rOptions.agent && rOptions.agent.options) { - rOptions.agent.options.rejectUnauthorized = false + if (rOptions.agent.options.rejectUnauthorized && rOptions.agent.unVerifySslAgent) { + // rOptions.agent.options.rejectUnauthorized = false // 不能直接在agent上进行修改属性值,因为它采用了单例模式,所有请求共用这个对象的 + rOptions.agent = rOptions.agent.unVerifySslAgent + unVerifySsl = true } + res.setHeader('DS-Interceptor', `sni: ${interceptOpt.sni}`, (unVerifySsl ? ', unVerifySsl' : '')) - res.setHeader('DS-Interceptor', 'sni: ' + interceptOpt.sni) - - log.info('sni intercept: sni replace servername:', rOptions.hostname, '➜', rOptions.servername) + log.info('sni intercept: sni replace servername:', rOptions.hostname, '➜', rOptions.servername, (unVerifySsl ? ', unVerifySsl' : '')) return true }, is (interceptOpt) { diff --git a/packages/mitmproxy/src/lib/proxy/common/util.js b/packages/mitmproxy/src/lib/proxy/common/util.js index a2b185866..3ea87b83e 100644 --- a/packages/mitmproxy/src/lib/proxy/common/util.js +++ b/packages/mitmproxy/src/lib/proxy/common/util.js @@ -24,15 +24,27 @@ function getTimeoutConfig (hostname, serverSetting) { } } -function createHttpsAgent (timeoutConfig) { +function createHttpsAgent (timeoutConfig, verifySsl) { const key = timeoutConfig.timeout + '-' + timeoutConfig.keepAliveTimeout if (!httpsAgentCache[key]) { - httpsAgentCache[key] = new HttpsAgent({ + verifySsl = !!verifySsl + + const agent = new HttpsAgent({ + keepAlive: true, + timeout: timeoutConfig.timeout, + keepAliveTimeout: timeoutConfig.keepAliveTimeout, + rejectUnauthorized: verifySsl + }) + + agent.unVerifySslAgent = new HttpsAgent({ keepAlive: true, timeout: timeoutConfig.timeout, keepAliveTimeout: timeoutConfig.keepAliveTimeout, rejectUnauthorized: false }) + + httpsAgentCache[key] = agent + log.info('创建 HttpsAgent 成功, timeoutConfig:', timeoutConfig, ', verifySsl:', verifySsl) } return httpsAgentCache[key] } @@ -45,13 +57,14 @@ function createHttpAgent (timeoutConfig) { timeout: timeoutConfig.timeout, keepAliveTimeout: timeoutConfig.keepAliveTimeout }) + log.info('创建 HttpsAgent 成功, timeoutConfig:', timeoutConfig) } return httpAgentCache[key] } -function createAgent (protocol, timeoutConfig) { +function createAgent (protocol, timeoutConfig, verifySsl) { return protocol === 'https:' - ? createHttpsAgent(timeoutConfig) + ? createHttpsAgent(timeoutConfig, verifySsl) : createHttpAgent(timeoutConfig) } @@ -110,7 +123,7 @@ util.getOptionsFromRequest = (req, ssl, externalProxy = null, serverSetting) => if (headers.connection !== 'close') { const timeoutConfig = getTimeoutConfig(hostname, serverSetting) // log.info(`get timeoutConfig '${hostname}':`, timeoutConfig) - agent = createAgent(protocol, timeoutConfig) + agent = createAgent(protocol, timeoutConfig, serverSetting.verifySsl) headers.connection = 'keep-alive' } else { agent = false diff --git a/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js b/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js index 56f662d8f..0f31424df 100644 --- a/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js +++ b/packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js @@ -18,12 +18,6 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e const rOptions = commonUtil.getOptionsFromRequest(req, ssl, externalProxy, setting) let url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${rOptions.path}` - if (rOptions.agent) { - rOptions.agent.options.rejectUnauthorized = setting.verifySsl - } else if (rOptions.agent !== false) { - log.error('rOptions.agent 的值有问题:', rOptions) - } - if (rOptions.headers.connection === 'close') { req.socket.setKeepAlive(false) } else if (rOptions.customSocketId != null) { // for NTLM