Merge remote-tracking branch 'origin/master'
commit
9a47914c57
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,5 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"lerna": "^3.22.1"
|
"lerna": "^3.22.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,9 @@ module.exports = {
|
||||||
'pay.weixin.qq.com': true,
|
'pay.weixin.qq.com': true,
|
||||||
'www.baidu.com': true
|
'www.baidu.com': true
|
||||||
},
|
},
|
||||||
|
// sniList: {
|
||||||
|
// 'github.com': 'abaidu.com'
|
||||||
|
// },
|
||||||
dns: {
|
dns: {
|
||||||
providers: {
|
providers: {
|
||||||
aliyun: {
|
aliyun: {
|
||||||
|
@ -212,7 +215,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
speedTest: {
|
speedTest: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
interval: 60000,
|
interval: 160000,
|
||||||
hostnameList: ['github.com'],
|
hostnameList: ['github.com'],
|
||||||
dnsProviders: ['usa', 'quad9', 'rubyfish']
|
dnsProviders: ['usa', 'quad9', 'rubyfish']
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,26 @@ const executor = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async linux (exec, params) {
|
async linux (exec, params) {
|
||||||
throw Error('暂未实现此功能')
|
if (params != null) {
|
||||||
|
const { ip, port } = params
|
||||||
|
// const local = 'localhost, 127.0.0.0/8, ::1'
|
||||||
|
|
||||||
|
const setProxyCmd = [
|
||||||
|
'gsettings set org.gnome.system.proxy mode manual',
|
||||||
|
`gsettings set org.gnome.system.proxy.https port ${port}`,
|
||||||
|
`gsettings set org.gnome.system.proxy.https host ${ip}`,
|
||||||
|
`gsettings set org.gnome.system.proxy.http port ${port}`,
|
||||||
|
`gsettings set org.gnome.system.proxy.http host ${ip}`
|
||||||
|
// `gsettings set org.gnome.system.proxy ignore-hosts "${local}"`
|
||||||
|
]
|
||||||
|
|
||||||
|
await exec(setProxyCmd)
|
||||||
|
} else {
|
||||||
|
const setProxyCmd = [
|
||||||
|
'gsettings set org.gnome.system.proxy mode none'
|
||||||
|
]
|
||||||
|
await exec(setProxyCmd)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async mac (exec, params) {
|
async mac (exec, params) {
|
||||||
// exec = _exec
|
// exec = _exec
|
||||||
|
|
|
@ -8,9 +8,9 @@ const executor = {
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
async linux (exec, { certPath }) {
|
async linux (exec, { certPath }) {
|
||||||
const cmds = ['open "' + certPath + '"']
|
const cmds = [`sudo cp ${certPath} /usr/local/share/ca-certificates`, 'sudo update-ca-certificates ']
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const ret = await exec(cmds, { type: 'cmd' })
|
const ret = await exec(cmds)
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
async mac (exec, { certPath }) {
|
async mac (exec, { certPath }) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ class LinuxSystemShell extends SystemShell {
|
||||||
cmds = [cmds]
|
cmds = [cmds]
|
||||||
}
|
}
|
||||||
for (const cmd of cmds) {
|
for (const cmd of cmds) {
|
||||||
await childExec(cmd)
|
await _childExec(cmd, { shell: '/bin/bash' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class DarwinSystemShell extends SystemShell {
|
||||||
}
|
}
|
||||||
let ret
|
let ret
|
||||||
for (const cmd of cmds) {
|
for (const cmd of cmds) {
|
||||||
ret = await childExec(cmd)
|
ret = await _childExec(cmd)
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -76,13 +76,31 @@ class WindowsSystemShell extends SystemShell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _childExec (composeCmds, options = {}) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const childProcess = require('child_process')
|
||||||
|
log.info('shell:', composeCmds)
|
||||||
|
childProcess.exec(composeCmds, options, function (error, stdout, stderr) {
|
||||||
|
if (error) {
|
||||||
|
log.error('cmd 命令执行错误:', composeCmds, stderr)
|
||||||
|
reject(new Error(stderr))
|
||||||
|
} else {
|
||||||
|
// log.info('cmd 命令完成:', stdout)
|
||||||
|
resolve(stdout)
|
||||||
|
}
|
||||||
|
// log.info('关闭 cmd')
|
||||||
|
// ps.kill('SIGINT')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function childExec (composeCmds) {
|
function childExec (composeCmds) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
var encoding = 'cp936'
|
var encoding = 'cp936'
|
||||||
var binaryEncoding = 'binary'
|
var binaryEncoding = 'binary'
|
||||||
|
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('child_process')
|
||||||
|
log.info('shell:', composeCmds)
|
||||||
childProcess.exec(composeCmds, { encoding: binaryEncoding }, function (error, stdout, stderr) {
|
childProcess.exec(composeCmds, { encoding: binaryEncoding }, function (error, stdout, stderr) {
|
||||||
if (error) {
|
if (error) {
|
||||||
// console.log('------', decoder.decode(stderr))
|
// console.log('------', decoder.decode(stderr))
|
||||||
|
@ -120,6 +138,7 @@ function getSystemPlatform () {
|
||||||
case 'linux':
|
case 'linux':
|
||||||
return 'linux'
|
return 'linux'
|
||||||
case 'win32':
|
case 'win32':
|
||||||
|
return 'windows'
|
||||||
case 'win64':
|
case 'win64':
|
||||||
return 'windows'
|
return 'windows'
|
||||||
case 'unknown os':
|
case 'unknown os':
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const server = require('@docmirror/mitmproxy')
|
const server = require('@docmirror/mitmproxy')
|
||||||
const JSON5 = require('json5')
|
const JSON5 = require('json5')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const home = process.env.HOME
|
const home = process.env.USER_HOME || process.env.HOME || 'C:/Users/xiaoj/'
|
||||||
let configPath = path.join(home, '.dev-sidecar/running.json')
|
let configPath = path.join(home, '.dev-sidecar/running.json')
|
||||||
if (process.argv && process.argv.length > 3) {
|
if (process.argv && process.argv.length > 3) {
|
||||||
configPath = process.argv[2]
|
configPath = process.argv[2]
|
||||||
|
@ -11,9 +11,9 @@ if (process.argv && process.argv.length > 3) {
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const configJson = fs.readFileSync(configPath)
|
const configJson = fs.readFileSync(configPath)
|
||||||
const config = JSON5.parse(configJson)
|
const config = JSON5.parse(configJson)
|
||||||
const scriptDir = '../../gui/extra/scripts/'
|
// const scriptDir = '../../gui/extra/scripts/'
|
||||||
config.setting.script.defaultDir = path.join(__dirname, scriptDir)
|
// config.setting.script.defaultDir = path.join(__dirname, scriptDir)
|
||||||
const pacFilePath = '../../gui/extra/pac/pac.txt'
|
// const pacFilePath = '../../gui/extra/pac/pac.txt'
|
||||||
config.plugin.overwall.pac.customPacFilePath = path.join(__dirname, pacFilePath)
|
// config.plugin.overwall.pac.customPacFilePath = path.join(__dirname, pacFilePath)
|
||||||
|
config.setting.rootDir = path.join(__dirname, '../../gui/')
|
||||||
server.start(config)
|
server.start(config)
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
{
|
{
|
||||||
server: {
|
app: {
|
||||||
intercepts: {
|
autoStart: {
|
||||||
'github1.githubassets.com': {
|
enabled: true,
|
||||||
'.*': {
|
|
||||||
redirect: 'assets.fastgit.org',
|
|
||||||
test: 'https://github.githubassets.com/favicons/favicon.svg',
|
|
||||||
desc: '静态资源加速'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'github.githubassets.com': null,
|
|
||||||
'notify3.note.youdao.com': {
|
|
||||||
'/pushserver3/.*': {
|
|
||||||
abort: true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
mode: 'safe',
|
||||||
},
|
},
|
||||||
plugin: {
|
plugin: {
|
||||||
node: {
|
node: {
|
||||||
enabled: true
|
setting: {
|
||||||
}
|
yarnRegistry: null,
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
git: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
overwall: {
|
||||||
|
targets: {
|
||||||
|
'*yonsz.net': true,
|
||||||
|
'*bootstrapcdn.com': true,
|
||||||
|
'*cloudflare.com': true,
|
||||||
|
'help.yonsz.net': true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
intercept: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
|
@ -93,10 +93,10 @@
|
||||||
lodash "^4.17.19"
|
lodash "^4.17.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@docmirror/mitmproxy@^1.5.0":
|
"@docmirror/mitmproxy@^1.5.1":
|
||||||
version "1.5.0"
|
version "1.5.1"
|
||||||
resolved "https://registry.npmjs.org/@docmirror/mitmproxy/-/mitmproxy-1.5.0.tgz#16b9a956542a56f9889cd0c69c08a33d06d77ab8"
|
resolved "https://registry.nlark.com/@docmirror/mitmproxy/download/@docmirror/mitmproxy-1.5.1.tgz#357142a41b89266491c3519a7528b9b83dc30c85"
|
||||||
integrity sha512-H17TAqKmvzCMSTO6VGTC6kKQskjk1gEJZYsU2ijziZU0XEC96ObG0TWOnsdKh2PhmwDLwxS9cUyb1hpYilLreQ==
|
integrity sha1-NXFCpBuJJmSRw1GadSi5uD3DDIU=
|
||||||
dependencies:
|
dependencies:
|
||||||
agentkeepalive "^2.1.1"
|
agentkeepalive "^2.1.1"
|
||||||
axios "^0.21.1"
|
axios "^0.21.1"
|
||||||
|
|
|
@ -40,22 +40,23 @@
|
||||||
"vue-router": "^3.4.8"
|
"vue-router": "^3.4.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~4.5.0",
|
|
||||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
|
||||||
"@vue/cli-service": "~4.5.0",
|
|
||||||
"@vue/eslint-config-standard": "^5.1.2",
|
"@vue/eslint-config-standard": "^5.1.2",
|
||||||
"babel-eslint": "^10.1.0",
|
|
||||||
"electron": "10.4.2",
|
|
||||||
"electron-devtools-installer": "^3.1.0",
|
|
||||||
"electron-icon-builder": "^1.0.2",
|
"electron-icon-builder": "^1.0.2",
|
||||||
"eslint": "^6.7.2",
|
|
||||||
"eslint-plugin-import": "^2.20.2",
|
"eslint-plugin-import": "^2.20.2",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^4.2.1",
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
|
||||||
"json5-loader": "^4.0.1",
|
"json5-loader": "^4.0.1",
|
||||||
"vue-cli-plugin-electron-builder": "^2.0.0-rc.4",
|
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"electron": "^13.0.0",
|
||||||
|
"electron-devtools-installer": "^3.1.0",
|
||||||
|
"eslint": "^6.7.2",
|
||||||
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
|
"vue-cli-plugin-electron-builder": "~2.1.1",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"vue-template-compiler": "^2.6.11"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 212 KiB |
|
@ -75,6 +75,21 @@ function setTray (app) {
|
||||||
return appTray
|
return appTray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isLinux () {
|
||||||
|
const platform = DevSidecar.api.shell.getSystemPlatform()
|
||||||
|
return platform === 'linux'
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideWin () {
|
||||||
|
if (win) {
|
||||||
|
if (isLinux()) {
|
||||||
|
win.minimize()
|
||||||
|
} else {
|
||||||
|
win.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
|
|
||||||
|
@ -92,6 +107,7 @@ function createWindow () {
|
||||||
title: 'DevSidecar',
|
title: 'DevSidecar',
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
enableRemoteModule: true,
|
enableRemoteModule: true,
|
||||||
|
contextIsolation: false,
|
||||||
// preload: path.join(__dirname, 'preload.js'),
|
// preload: path.join(__dirname, 'preload.js'),
|
||||||
// Use pluginOptions.nodeIntegration, leave this alone
|
// Use pluginOptions.nodeIntegration, leave this alone
|
||||||
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
|
||||||
|
@ -113,7 +129,7 @@ function createWindow () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startHideWindow) {
|
if (startHideWindow) {
|
||||||
win.hide()
|
hideWin()
|
||||||
}
|
}
|
||||||
|
|
||||||
win.on('closed', async (e) => {
|
win.on('closed', async (e) => {
|
||||||
|
@ -124,7 +140,7 @@ function createWindow () {
|
||||||
win.on('close', (e) => {
|
win.on('close', (e) => {
|
||||||
if (!forceClose) {
|
if (!forceClose) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
win.hide()
|
hideWin()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,16 @@
|
||||||
2、然后按如下图步骤将随机生成的根证书设置为始终信任<br/>
|
2、然后按如下图步骤将随机生成的根证书设置为始终信任<br/>
|
||||||
3、可能需要重新启动应用和浏览器才能生效<br/>
|
3、可能需要重新启动应用和浏览器才能生效<br/>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="this.systemPlatform === 'linux'">
|
||||||
|
1、点击右上角“点此去安装按钮”,将自动安装到系统证书库中<br/>
|
||||||
|
2、火狐、chrome等浏览器不走系统证书,需要手动安装(下图以chrome为例安装根证书)<br/>
|
||||||
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
1、点击右上角“点此去安装按钮”,打开证书<br/>
|
1、点击右上角“点此去安装按钮”,打开证书<br/>
|
||||||
2、然后按如下图步骤将根证书添加到<b>信任的根证书颁发机构</b><br/>
|
2、然后按如下图步骤将根证书添加到<b>信任的根证书颁发机构</b><br/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<img width="100%" :src="setupImage" />
|
<img width="100%" :src="setupImage" />
|
||||||
|
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -59,6 +62,8 @@ export default {
|
||||||
setupImage () {
|
setupImage () {
|
||||||
if (this.systemPlatform === 'mac') {
|
if (this.systemPlatform === 'mac') {
|
||||||
return '/setup-mac.png'
|
return '/setup-mac.png'
|
||||||
|
} else if (this.systemPlatform === 'linux') {
|
||||||
|
return '/setup-linux.png'
|
||||||
} else {
|
} else {
|
||||||
return '/setup.png'
|
return '/setup.png'
|
||||||
}
|
}
|
||||||
|
@ -75,6 +80,9 @@ export default {
|
||||||
},
|
},
|
||||||
async doSetup () {
|
async doSetup () {
|
||||||
this.$emit('setup')
|
this.$emit('setup')
|
||||||
|
if (this.systemPlatform === 'linux') {
|
||||||
|
this.$message.success('根证书已成功安装到系统证书库(注意:浏览器仍然需要手动安装)')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,9 @@
|
||||||
<a-button v-if="item.value!==false" type="danger" icon="minus" @click="deleteWhiteList(item,index)"/>
|
<a-button v-if="item.value!==false" type="danger" icon="minus" @click="deleteWhiteList(item,index)"/>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane tab="DNS设置" key="4">
|
<a-tab-pane tab="DNS设置" key="4">
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<a-row style="margin-top:10px">
|
<a-row style="margin-top:10px">
|
||||||
<a-col span="19">
|
<a-col span="19">
|
||||||
<div>这里配置哪些域名需要通过国外DNS服务器获取IP进行访问</div>
|
<div>这里配置哪些域名需要通过国外DNS服务器获取IP进行访问</div>
|
||||||
|
@ -110,10 +108,31 @@
|
||||||
@click="restoreDefDnsMapping(item,index)"></a-button>
|
@click="restoreDefDnsMapping(item,index)"></a-button>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane tab="IP测速" key="5">
|
<!-- <a-tab-pane tab="SNI" key="5">-->
|
||||||
|
<!-- <a-row style="margin-top:10px">-->
|
||||||
|
<!-- <a-col span="19">-->
|
||||||
|
<!-- <div>这里配置哪些域名要修改sni</div>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- <a-col span="3">-->
|
||||||
|
<!-- <a-button style="margin-left:8px" type="primary" icon="plus" @click="addSniList()"/>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- </a-row>-->
|
||||||
|
<!-- <a-row :gutter="10" style="margin-top: 10px" v-for="(item,index) of sniList" :key='index'>-->
|
||||||
|
<!-- <a-col :span="14">-->
|
||||||
|
<!-- <a-input v-model="item.key"></a-input>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- <a-col :span="5">-->
|
||||||
|
<!-- <a-input v-model="item.value"></a-input>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- <a-col :span="3">-->
|
||||||
|
<!-- <a-button type="danger" icon="minus" @click="deleteSniList(item,index)"/>-->
|
||||||
|
<!-- </a-col>-->
|
||||||
|
<!-- </a-row>-->
|
||||||
|
|
||||||
|
<!-- </a-tab-pane>-->
|
||||||
|
<a-tab-pane tab="IP测速" key="6">
|
||||||
<div>
|
<div>
|
||||||
<a-alert type="info" message="对从dns获取到的ip进行测速,使用速度最快的ip进行访问。(对使用增强功能的域名没啥用)"></a-alert>
|
<a-alert type="info" message="对从dns获取到的ip进行测速,使用速度最快的ip进行访问。(对使用增强功能的域名没啥用)"></a-alert>
|
||||||
<a-form-item label="开启dns测速" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form-item label="开启dns测速" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
|
@ -207,7 +226,8 @@ export default {
|
||||||
wrapperCol: { span: 20 },
|
wrapperCol: { span: 20 },
|
||||||
dnsMappings: [],
|
dnsMappings: [],
|
||||||
speedTestList: [],
|
speedTestList: [],
|
||||||
whiteList: []
|
whiteList: [],
|
||||||
|
sniList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
@ -249,6 +269,7 @@ export default {
|
||||||
ready () {
|
ready () {
|
||||||
this.initDnsMapping()
|
this.initDnsMapping()
|
||||||
this.initWhiteList()
|
this.initWhiteList()
|
||||||
|
this.initSniList()
|
||||||
if (this.config.server.dns.speedTest.dnsProviders) {
|
if (this.config.server.dns.speedTest.dnsProviders) {
|
||||||
this.speedDns = this.config.server.dns.speedTest.dnsProviders
|
this.speedDns = this.config.server.dns.speedTest.dnsProviders
|
||||||
}
|
}
|
||||||
|
@ -256,6 +277,7 @@ export default {
|
||||||
async applyBefore () {
|
async applyBefore () {
|
||||||
this.submitDnsMapping()
|
this.submitDnsMapping()
|
||||||
this.submitWhiteList()
|
this.submitWhiteList()
|
||||||
|
this.submitSniList()
|
||||||
},
|
},
|
||||||
async applyAfter () {
|
async applyAfter () {
|
||||||
if (this.status.server.enabled) {
|
if (this.status.server.enabled) {
|
||||||
|
@ -320,6 +342,35 @@ export default {
|
||||||
this.whiteList.unshift({ key: '', value: true })
|
this.whiteList.unshift({ key: '', value: true })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// sniList
|
||||||
|
initSniList () {
|
||||||
|
this.sniList = []
|
||||||
|
for (const key in this.config.server.sniList) {
|
||||||
|
const value = this.config.server.sniList[key]
|
||||||
|
this.sniList.push({
|
||||||
|
key, value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submitSniList () {
|
||||||
|
const sniList = {}
|
||||||
|
for (const item of this.sniList) {
|
||||||
|
if (item.key) {
|
||||||
|
sniList[item.key] = item.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.config.server.sniList = sniList
|
||||||
|
},
|
||||||
|
deleteSniList (item, index) {
|
||||||
|
this.sniList.splice(index, 1)
|
||||||
|
},
|
||||||
|
restoreDefSniList (item, index) {
|
||||||
|
|
||||||
|
},
|
||||||
|
addSniList () {
|
||||||
|
this.sniList.unshift({ key: '', value: true })
|
||||||
|
},
|
||||||
|
|
||||||
async openLog () {
|
async openLog () {
|
||||||
const dir = await this.$api.info.getConfigDir()
|
const dir = await this.$api.info.getConfigDir()
|
||||||
this.$api.ipc.openPath(dir + '/logs/')
|
this.$api.ipc.openPath(dir + '/logs/')
|
||||||
|
|
|
@ -1507,10 +1507,10 @@
|
||||||
resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-14.11.8.tgz"
|
resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-14.11.8.tgz"
|
||||||
integrity sha1-/iAS8jVeTOCLykSus6u7Ic+I0z8=
|
integrity sha1-/iAS8jVeTOCLykSus6u7Ic+I0z8=
|
||||||
|
|
||||||
"@types/node@^12.0.12":
|
"@types/node@^14.6.2":
|
||||||
version "12.20.6"
|
version "14.17.9"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-12.20.6.tgz"
|
resolved "https://registry.nlark.com/@types/node/download/@types/node-14.17.9.tgz#b97c057e6138adb7b720df2bd0264b03c9f504fd"
|
||||||
integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA==
|
integrity sha1-uXwFfmE4rbe3IN8r0CZLA8n1BP0=
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.0":
|
"@types/normalize-package-data@^2.4.0":
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
|
@ -1823,6 +1823,24 @@
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vue-loader-v16 "npm:vue-loader@^16.0.0-beta.7"
|
vue-loader-v16 "npm:vue-loader@^16.0.0-beta.7"
|
||||||
|
|
||||||
|
"@vue/cli-shared-utils@^4.5.6":
|
||||||
|
version "4.5.13"
|
||||||
|
resolved "https://registry.nlark.com/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.13.tgz?cache=0&sync_timestamp=1628579241293&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.5.13.tgz#acd40f31b4790f1634292bdaa5fca95dc1e0ff50"
|
||||||
|
integrity sha1-rNQPMbR5DxY0KSvapfypXcHg/1A=
|
||||||
|
dependencies:
|
||||||
|
"@hapi/joi" "^15.0.1"
|
||||||
|
chalk "^2.4.2"
|
||||||
|
execa "^1.0.0"
|
||||||
|
launch-editor "^2.2.1"
|
||||||
|
lru-cache "^5.1.1"
|
||||||
|
node-ipc "^9.1.1"
|
||||||
|
open "^6.3.0"
|
||||||
|
ora "^3.4.0"
|
||||||
|
read-pkg "^5.1.1"
|
||||||
|
request "^2.88.2"
|
||||||
|
semver "^6.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
"@vue/cli-shared-utils@^4.5.7":
|
"@vue/cli-shared-utils@^4.5.7":
|
||||||
version "4.5.7"
|
version "4.5.7"
|
||||||
resolved "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.7.tgz?cache=0&sync_timestamp=1602060136132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.5.7.tgz"
|
resolved "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.7.tgz?cache=0&sync_timestamp=1602060136132&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.5.7.tgz"
|
||||||
|
@ -3876,7 +3894,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||||
shebang-command "^1.2.0"
|
shebang-command "^1.2.0"
|
||||||
which "^1.2.9"
|
which "^1.2.9"
|
||||||
|
|
||||||
cross-spawn@^7.0.0:
|
cross-spawn@^7.0.0, cross-spawn@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz"
|
resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz"
|
||||||
integrity sha1-9zqFudXUHQRVUcF34ogtSshXKKY=
|
integrity sha1-9zqFudXUHQRVUcF34ogtSshXKKY=
|
||||||
|
@ -4651,13 +4669,13 @@ electron-updater@^4.3.5:
|
||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
|
|
||||||
electron@10.4.2:
|
electron@^13.0.0:
|
||||||
version "10.4.2"
|
version "13.1.9"
|
||||||
resolved "https://registry.nlark.com/electron/download/electron-10.4.2.tgz?cache=0&sync_timestamp=1620442447118&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felectron%2Fdownload%2Felectron-10.4.2.tgz#2322a72f1e653e023250be91f3dd8d27662e3805"
|
resolved "https://registry.nlark.com/electron/download/electron-13.1.9.tgz#668e2632b81e9fa21edfd32876282d3e2ff7fd76"
|
||||||
integrity sha1-IyKnLx5lPgIyUL6R892NJ2YuOAU=
|
integrity sha1-Zo4mMrgen6Ie39ModigtPi/3/XY=
|
||||||
dependencies:
|
dependencies:
|
||||||
"@electron/get" "^1.0.1"
|
"@electron/get" "^1.0.1"
|
||||||
"@types/node" "^12.0.12"
|
"@types/node" "^14.6.2"
|
||||||
extract-zip "^1.0.3"
|
extract-zip "^1.0.3"
|
||||||
|
|
||||||
elliptic@^6.5.3:
|
elliptic@^6.5.3:
|
||||||
|
@ -5160,19 +5178,19 @@ execa@^3.3.0:
|
||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.2"
|
||||||
strip-final-newline "^2.0.0"
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
execa@^4.0.0:
|
execa@^5.0.0:
|
||||||
version "4.0.3"
|
version "5.1.1"
|
||||||
resolved "https://registry.npm.taobao.org/execa/download/execa-4.0.3.tgz"
|
resolved "https://registry.nlark.com/execa/download/execa-5.1.1.tgz?cache=0&sync_timestamp=1622825396605&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fexeca%2Fdownload%2Fexeca-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||||
integrity sha1-CjTau61tZhAL1vLFdshmlAPzF/I=
|
integrity sha1-+ArZy/Qpj3vR1MlVXCHpN0HEEd0=
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn "^7.0.0"
|
cross-spawn "^7.0.3"
|
||||||
get-stream "^5.0.0"
|
get-stream "^6.0.0"
|
||||||
human-signals "^1.1.1"
|
human-signals "^2.1.0"
|
||||||
is-stream "^2.0.0"
|
is-stream "^2.0.0"
|
||||||
merge-stream "^2.0.0"
|
merge-stream "^2.0.0"
|
||||||
npm-run-path "^4.0.0"
|
npm-run-path "^4.0.1"
|
||||||
onetime "^5.1.0"
|
onetime "^5.1.2"
|
||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.3"
|
||||||
strip-final-newline "^2.0.0"
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
exif-parser@^0.1.12:
|
exif-parser@^0.1.12:
|
||||||
|
@ -5752,6 +5770,11 @@ get-stream@^5.0.0, get-stream@^5.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
|
|
||||||
|
get-stream@^6.0.0:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||||
|
integrity sha1-omLY7vZ6ztV8KFKtYWdSakPL97c=
|
||||||
|
|
||||||
get-value@^2.0.3, get-value@^2.0.6:
|
get-value@^2.0.3, get-value@^2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz"
|
resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz"
|
||||||
|
@ -6252,6 +6275,11 @@ human-signals@^1.1.1:
|
||||||
resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz"
|
resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz"
|
||||||
integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M=
|
integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M=
|
||||||
|
|
||||||
|
human-signals@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.nlark.com/human-signals/download/human-signals-2.1.0.tgz?cache=0&sync_timestamp=1624364695595&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhuman-signals%2Fdownload%2Fhuman-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
|
integrity sha1-3JH8ukLk0G5Kuu0zs+ejwC9RTqA=
|
||||||
|
|
||||||
icon-gen@^2.0.0:
|
icon-gen@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/icon-gen/-/icon-gen-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/icon-gen/-/icon-gen-2.0.0.tgz"
|
||||||
|
@ -8028,7 +8056,7 @@ npm-run-path@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key "^2.0.0"
|
path-key "^2.0.0"
|
||||||
|
|
||||||
npm-run-path@^4.0.0:
|
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz"
|
resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz"
|
||||||
integrity sha1-t+zR5e1T2o43pV4cImnguX7XSOo=
|
integrity sha1-t+zR5e1T2o43pV4cImnguX7XSOo=
|
||||||
|
@ -8179,7 +8207,7 @@ onetime@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^1.0.0"
|
mimic-fn "^1.0.0"
|
||||||
|
|
||||||
onetime@^5.1.0:
|
onetime@^5.1.0, onetime@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz?cache=0&sync_timestamp=1597005345612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fonetime%2Fdownload%2Fonetime-5.1.2.tgz"
|
resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz?cache=0&sync_timestamp=1597005345612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fonetime%2Fdownload%2Fonetime-5.1.2.tgz"
|
||||||
integrity sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=
|
integrity sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=
|
||||||
|
@ -10001,7 +10029,7 @@ shortid@^2.2.14:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid "^2.1.0"
|
nanoid "^2.1.0"
|
||||||
|
|
||||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz"
|
resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz"
|
||||||
integrity sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw=
|
integrity sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw=
|
||||||
|
@ -11267,14 +11295,15 @@ vm-browserify@^1.0.1:
|
||||||
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1589682787766&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz"
|
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1589682787766&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz"
|
||||||
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
|
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
|
||||||
|
|
||||||
vue-cli-plugin-electron-builder@^2.0.0-rc.4:
|
vue-cli-plugin-electron-builder@~2.1.1:
|
||||||
version "2.0.0-rc.4"
|
version "2.1.1"
|
||||||
resolved "https://registry.npm.taobao.org/vue-cli-plugin-electron-builder/download/vue-cli-plugin-electron-builder-2.0.0-rc.4.tgz"
|
resolved "https://registry.nlark.com/vue-cli-plugin-electron-builder/download/vue-cli-plugin-electron-builder-2.1.1.tgz#de8bed25b32e73e28dd08061dd2a3c6bfff73227"
|
||||||
integrity sha1-yBknngD+Z3GRL18EaO4m8nl1Cls=
|
integrity sha1-3ovtJbMuc+KN0IBh3So8a//3Mic=
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@vue/cli-shared-utils" "^4.5.6"
|
||||||
chokidar "^3.0.2"
|
chokidar "^3.0.2"
|
||||||
electron-builder "^22.2.0"
|
electron-builder "^22.2.0"
|
||||||
execa "^4.0.0"
|
execa "^5.0.0"
|
||||||
friendly-errors-webpack-plugin "^1.7.0"
|
friendly-errors-webpack-plugin "^1.7.0"
|
||||||
fs-extra "^9.0.1"
|
fs-extra "^9.0.1"
|
||||||
lodash.merge "^4.6.1"
|
lodash.merge "^4.6.1"
|
||||||
|
|
|
@ -34,6 +34,10 @@ function registerProcessListener () {
|
||||||
log.info('Unhandled Rejection at: Promise', p, 'err:', err)
|
log.info('Unhandled Rejection at: Promise', p, 'err:', err)
|
||||||
// application specific logging, throwing an error, or other logic here
|
// application specific logging, throwing an error, or other logic here
|
||||||
})
|
})
|
||||||
|
|
||||||
|
process.on('exit', function (code) {
|
||||||
|
log.info('代理服务进程被关闭:', code)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = {
|
const api = {
|
||||||
|
|
|
@ -5,9 +5,9 @@ const log = require('../../../utils/util.log')
|
||||||
const DnsUtil = require('../../dns/index')
|
const DnsUtil = require('../../dns/index')
|
||||||
const localIP = '127.0.0.1'
|
const localIP = '127.0.0.1'
|
||||||
const defaultDns = require('dns')
|
const defaultDns = require('dns')
|
||||||
|
const matchUtil = require('../../../utils/util.match')
|
||||||
const speedTest = require('../../speed/index.js')
|
const speedTest = require('../../speed/index.js')
|
||||||
|
const sniExtract = require('../tls/sniUtil.js')
|
||||||
function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
|
function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
|
||||||
for (const intercept of sslConnectInterceptors) {
|
for (const intercept of sslConnectInterceptors) {
|
||||||
const ret = intercept(req, cltSocket, head)
|
const ret = intercept(req, cltSocket, head)
|
||||||
|
@ -19,7 +19,7 @@ function isSslConnect (sslConnectInterceptors, req, cltSocket, head) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create connectHandler function
|
// create connectHandler function
|
||||||
module.exports = function createConnectHandler (sslConnectInterceptor, middlewares, fakeServerCenter, dnsConfig) {
|
module.exports = function createConnectHandler (sslConnectInterceptor, middlewares, fakeServerCenter, dnsConfig, sniConfig) {
|
||||||
// return
|
// return
|
||||||
const sslConnectInterceptors = []
|
const sslConnectInterceptors = []
|
||||||
sslConnectInterceptors.push(sslConnectInterceptor)
|
sslConnectInterceptors.push(sslConnectInterceptor)
|
||||||
|
@ -28,6 +28,9 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
|
||||||
sslConnectInterceptors.push(middleware.sslConnectInterceptor)
|
sslConnectInterceptors.push(middleware.sslConnectInterceptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('sni config', sniConfig)
|
||||||
|
const sniRegexpMap = matchUtil.domainMapRegexply(sniConfig)
|
||||||
return function connectHandler (req, cltSocket, head) {
|
return function connectHandler (req, cltSocket, head) {
|
||||||
// eslint-disable-next-line node/no-deprecated-api
|
// eslint-disable-next-line node/no-deprecated-api
|
||||||
const srvUrl = url.parse(`https://${req.url}`)
|
const srvUrl = url.parse(`https://${req.url}`)
|
||||||
|
@ -40,16 +43,17 @@ module.exports = function createConnectHandler (sslConnectInterceptor, middlewar
|
||||||
log.error('getServerPromise', e)
|
log.error('getServerPromise', e)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig)
|
connect(req, cltSocket, head, hostname, srvUrl.port, dnsConfig, sniRegexpMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function connect (req, cltSocket, head, hostname, port, dnsConfig) {
|
function connect (req, cltSocket, head, hostname, port, dnsConfig, sniRegexpMap) {
|
||||||
// tunneling https
|
// tunneling https
|
||||||
// log.info('connect:', hostname, port)
|
// log.info('connect:', hostname, port)
|
||||||
const start = new Date().getTime()
|
const start = new Date().getTime()
|
||||||
let isDnsIntercept = null
|
let isDnsIntercept = null
|
||||||
|
const replaceSni = matchUtil.matchHostname(sniRegexpMap, hostname)
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
port,
|
port,
|
||||||
|
@ -90,6 +94,33 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig) {
|
||||||
proxySocket.pipe(cltSocket)
|
proxySocket.pipe(cltSocket)
|
||||||
|
|
||||||
cltSocket.pipe(proxySocket)
|
cltSocket.pipe(proxySocket)
|
||||||
|
// let sniReplaced = false
|
||||||
|
// cltSocket.on('data', (chunk) => {
|
||||||
|
// // if (replaceSni && sniReplaced === false) {
|
||||||
|
// // const sniPackage = sniExtract(chunk)
|
||||||
|
// // if (sniPackage != null) {
|
||||||
|
// // sniReplaced = true
|
||||||
|
// // const bytes = Buffer.from(replaceSni)
|
||||||
|
// // const start = sniPackage.start
|
||||||
|
// // const length = sniPackage.length
|
||||||
|
// // for (let i = 0; i < length; i++) {
|
||||||
|
// // let char = 97 // a 的ascii
|
||||||
|
// // if (bytes.length > i) {
|
||||||
|
// // char = bytes[i]
|
||||||
|
// // }
|
||||||
|
// // chunk[start + i] = char
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// if (sniReplaced === false) {
|
||||||
|
// sniReplaced = true
|
||||||
|
// chunk[chunk.length - 1] = 1
|
||||||
|
// }
|
||||||
|
// proxySocket.write(chunk)
|
||||||
|
// })
|
||||||
|
// cltSocket.on('end', () => {
|
||||||
|
// proxySocket.end()
|
||||||
|
// })
|
||||||
})
|
})
|
||||||
|
|
||||||
cltSocket.on('error', (e) => {
|
cltSocket.on('error', (e) => {
|
||||||
|
|
|
@ -21,7 +21,8 @@ module.exports = {
|
||||||
middlewares = [],
|
middlewares = [],
|
||||||
externalProxy,
|
externalProxy,
|
||||||
dnsConfig,
|
dnsConfig,
|
||||||
setting
|
setting,
|
||||||
|
sniConfig
|
||||||
}, callback) {
|
}, callback) {
|
||||||
// Don't reject unauthorized
|
// Don't reject unauthorized
|
||||||
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||||
|
@ -39,25 +40,6 @@ module.exports = {
|
||||||
log.info(`CA private key saved in: ${caKeyPath}`)
|
log.info(`CA private key saved in: ${caKeyPath}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// function lookup (hostname, options, callback) {
|
|
||||||
// const dns = DnsUtil.hasDnsLookup(dnsConfig, hostname)
|
|
||||||
// if (dns) {
|
|
||||||
// dns.lookup(hostname).then(ip => {
|
|
||||||
// // isDnsIntercept = { dns, hostname, ip }
|
|
||||||
// if (ip !== hostname) {
|
|
||||||
// log.info(`-----${hostname} use ip:${ip}-----`)
|
|
||||||
// callback(null, ip, 4)
|
|
||||||
// } else {
|
|
||||||
// defaultDns.lookup(hostname, options, callback)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// defaultDns.lookup(hostname, options, callback)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// https.globalAgent.lookup = lookup
|
|
||||||
|
|
||||||
port = ~~port
|
port = ~~port
|
||||||
|
|
||||||
const speedTestConfig = dnsConfig.speedTest
|
const speedTestConfig = dnsConfig.speedTest
|
||||||
|
@ -95,7 +77,8 @@ module.exports = {
|
||||||
sslConnectInterceptor,
|
sslConnectInterceptor,
|
||||||
middlewares,
|
middlewares,
|
||||||
fakeServersCenter,
|
fakeServersCenter,
|
||||||
dnsConfig
|
dnsConfig,
|
||||||
|
sniConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
const server = new http.Server()
|
const server = new http.Server()
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
module.exports = function extractSNI (data) {
|
||||||
|
/*
|
||||||
|
From https://tools.ietf.org/html/rfc5246:
|
||||||
|
enum {
|
||||||
|
hello_request(0), client_hello(1), server_hello(2),
|
||||||
|
certificate(11), server_key_exchange (12),
|
||||||
|
certificate_request(13), server_hello_done(14),
|
||||||
|
certificate_verify(15), client_key_exchange(16),
|
||||||
|
finished(20)
|
||||||
|
(255)
|
||||||
|
} HandshakeType;
|
||||||
|
struct {
|
||||||
|
HandshakeType msg_type;
|
||||||
|
uint24 length;
|
||||||
|
select (HandshakeType) {
|
||||||
|
case hello_request: HelloRequest;
|
||||||
|
case client_hello: ClientHello;
|
||||||
|
case server_hello: ServerHello;
|
||||||
|
case certificate: Certificate;
|
||||||
|
case server_key_exchange: ServerKeyExchange;
|
||||||
|
case certificate_request: CertificateRequest;
|
||||||
|
case server_hello_done: ServerHelloDone;
|
||||||
|
case certificate_verify: CertificateVerify;
|
||||||
|
case client_key_exchange: ClientKeyExchange;
|
||||||
|
case finished: Finished;
|
||||||
|
} body;
|
||||||
|
} Handshake;
|
||||||
|
struct {
|
||||||
|
uint8 major;
|
||||||
|
uint8 minor;
|
||||||
|
} ProtocolVersion;
|
||||||
|
struct {
|
||||||
|
uint32 gmt_unix_time;
|
||||||
|
opaque random_bytes[28];
|
||||||
|
} Random;
|
||||||
|
opaque SessionID<0..32>;
|
||||||
|
uint8 CipherSuite[2];
|
||||||
|
enum { null(0), (255) } CompressionMethod;
|
||||||
|
struct {
|
||||||
|
ProtocolVersion client_version;
|
||||||
|
Random random;
|
||||||
|
SessionID session_id;
|
||||||
|
CipherSuite cipher_suites<2..2^16-2>;
|
||||||
|
CompressionMethod compression_methods<1..2^8-1>;
|
||||||
|
select (extensions_present) {
|
||||||
|
case false:
|
||||||
|
struct {};
|
||||||
|
case true:
|
||||||
|
Extension extensions<0..2^16-1>;
|
||||||
|
};
|
||||||
|
} ClientHello;
|
||||||
|
*/
|
||||||
|
|
||||||
|
var end = data.length
|
||||||
|
|
||||||
|
// skip the record header
|
||||||
|
var pos = 5
|
||||||
|
|
||||||
|
// skip HandshakeType (you should already have verified this)
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
// skip handshake length
|
||||||
|
pos += 3
|
||||||
|
|
||||||
|
// skip protocol version (you should already have verified this)
|
||||||
|
pos += 2
|
||||||
|
|
||||||
|
// skip Random
|
||||||
|
pos += 32
|
||||||
|
|
||||||
|
// skip SessionID
|
||||||
|
if (pos > end - 1) return null
|
||||||
|
var sessionIdLength = data[pos]
|
||||||
|
pos += 1 + sessionIdLength
|
||||||
|
|
||||||
|
// skip CipherSuite
|
||||||
|
if (pos > end - 2) return null
|
||||||
|
var cipherSuiteLength = data[pos] << 8 | data[pos + 1]
|
||||||
|
pos += 2 + cipherSuiteLength
|
||||||
|
|
||||||
|
// skip CompressionMethod
|
||||||
|
if (pos > end - 1) return null
|
||||||
|
var compressionMethodLength = data[pos]
|
||||||
|
pos += 1 + compressionMethodLength
|
||||||
|
|
||||||
|
// verify extensions exist
|
||||||
|
if (pos > end - 2) return null
|
||||||
|
var extensionsLength = data[pos] << 8 | data[pos + 1]
|
||||||
|
pos += 2
|
||||||
|
|
||||||
|
// verify the extensions fit
|
||||||
|
var extensionsEnd = pos + extensionsLength
|
||||||
|
if (extensionsEnd > end) return null
|
||||||
|
end = extensionsEnd
|
||||||
|
|
||||||
|
/*
|
||||||
|
From https://tools.ietf.org/html/rfc5246
|
||||||
|
and http://tools.ietf.org/html/rfc6066:
|
||||||
|
struct {
|
||||||
|
ExtensionType extension_type;
|
||||||
|
opaque extension_data<0..2^16-1>;
|
||||||
|
} Extension;
|
||||||
|
enum {
|
||||||
|
signature_algorithms(13), (65535)
|
||||||
|
} ExtensionType;
|
||||||
|
enum {
|
||||||
|
server_name(0), max_fragment_length(1),
|
||||||
|
client_certificate_url(2), trusted_ca_keys(3),
|
||||||
|
truncated_hmac(4), status_request(5), (65535)
|
||||||
|
} ExtensionType;
|
||||||
|
struct {
|
||||||
|
NameType name_type;
|
||||||
|
select (name_type) {
|
||||||
|
case host_name: HostName;
|
||||||
|
} name;
|
||||||
|
} ServerName;
|
||||||
|
enum {
|
||||||
|
host_name(0), (255)
|
||||||
|
} NameType;
|
||||||
|
opaque HostName<1..2^16-1>;
|
||||||
|
struct {
|
||||||
|
ServerName server_name_list<1..2^16-1>
|
||||||
|
} ServerNameList;
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (pos <= end - 4) {
|
||||||
|
var extensionType = data[pos] << 8 | data[pos + 1]
|
||||||
|
var extensionSize = data[pos + 2] << 8 | data[pos + 3]
|
||||||
|
pos += 4
|
||||||
|
if (extensionType === 0) { // ExtensionType was server_name(0)
|
||||||
|
// read ServerNameList length
|
||||||
|
if (pos > end - 2) return null
|
||||||
|
var nameListLength = data[pos] << 8 | data[pos + 1]
|
||||||
|
pos += 2
|
||||||
|
|
||||||
|
// verify we have enough bytes and loop over SeverNameList
|
||||||
|
var n = pos
|
||||||
|
pos += nameListLength
|
||||||
|
if (pos > end) return null
|
||||||
|
while (n < pos - 3) {
|
||||||
|
var nameType = data[n]
|
||||||
|
var nameLength = data[n + 1] << 8 | data[n + 2]
|
||||||
|
n += 3
|
||||||
|
|
||||||
|
// check if NameType is host_name(0)
|
||||||
|
if (nameType === 0) {
|
||||||
|
// verify we have enough bytes
|
||||||
|
if (n > end - nameLength) return null
|
||||||
|
|
||||||
|
// decode as ascii and return
|
||||||
|
|
||||||
|
const sniName = data.toString('ascii', n, n + nameLength)
|
||||||
|
return {
|
||||||
|
sniName,
|
||||||
|
start: n,
|
||||||
|
end: n + nameLength,
|
||||||
|
length: nameLength
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n += nameLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // ExtensionType was something we are not interested in
|
||||||
|
pos += extensionSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
|
@ -51,11 +51,13 @@ utils.createCA = function (CN) {
|
||||||
name: 'basicConstraints',
|
name: 'basicConstraints',
|
||||||
critical: true,
|
critical: true,
|
||||||
cA: true
|
cA: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: 'keyUsage',
|
name: 'keyUsage',
|
||||||
critical: true,
|
critical: true,
|
||||||
keyCertSign: true
|
keyCertSign: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: 'subjectKeyIdentifier'
|
name: 'subjectKeyIdentifier'
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
@ -111,19 +113,19 @@ utils.createFakeCertificateByDomain = function (caKey, caCert, domain) {
|
||||||
critical: true,
|
critical: true,
|
||||||
cA: false
|
cA: false
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
name: 'keyUsage',
|
// name: 'keyUsage',
|
||||||
critical: true,
|
// critical: true,
|
||||||
digitalSignature: true,
|
// digitalSignature: true,
|
||||||
contentCommitment: true,
|
// contentCommitment: true,
|
||||||
keyEncipherment: true,
|
// keyEncipherment: true,
|
||||||
dataEncipherment: true,
|
// dataEncipherment: true,
|
||||||
keyAgreement: true,
|
// keyAgreement: true,
|
||||||
keyCertSign: true,
|
// keyCertSign: true,
|
||||||
cRLSign: true,
|
// cRLSign: true,
|
||||||
encipherOnly: true,
|
// encipherOnly: true,
|
||||||
decipherOnly: true
|
// decipherOnly: true
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
name: 'subjectAltName',
|
name: 'subjectAltName',
|
||||||
altNames: [{
|
altNames: [{
|
||||||
|
|
|
@ -13,10 +13,14 @@ module.exports = (config) => {
|
||||||
const serverConfig = config
|
const serverConfig = config
|
||||||
const setting = serverConfig.setting
|
const setting = serverConfig.setting
|
||||||
|
|
||||||
|
if (!setting.script.dirAbsolutePath) {
|
||||||
setting.script.dirAbsolutePath = path.join(setting.rootDir, setting.script.defaultDir)
|
setting.script.dirAbsolutePath = path.join(setting.rootDir, setting.script.defaultDir)
|
||||||
|
}
|
||||||
|
|
||||||
const overwallConfig = serverConfig.plugin.overwall
|
const overwallConfig = serverConfig.plugin.overwall
|
||||||
|
if (!overwallConfig.pac.pacFileAbsolutePath) {
|
||||||
overwallConfig.pac.pacFileAbsolutePath = path.join(setting.rootDir, overwallConfig.pac.pacFilePath)
|
overwallConfig.pac.pacFileAbsolutePath = path.join(setting.rootDir, overwallConfig.pac.pacFilePath)
|
||||||
|
}
|
||||||
const overwallMiddleware = createOverwallMiddleware(overwallConfig)
|
const overwallMiddleware = createOverwallMiddleware(overwallConfig)
|
||||||
const middlewares = []
|
const middlewares = []
|
||||||
if (overwallMiddleware) {
|
if (overwallMiddleware) {
|
||||||
|
@ -30,6 +34,7 @@ module.exports = (config) => {
|
||||||
speedTest: config.dns.speedTest
|
speedTest: config.dns.speedTest
|
||||||
},
|
},
|
||||||
setting,
|
setting,
|
||||||
|
sniConfig: serverConfig.sniList,
|
||||||
middlewares,
|
middlewares,
|
||||||
sslConnectInterceptor: (req, cltSocket, head) => {
|
sslConnectInterceptor: (req, cltSocket, head) => {
|
||||||
const hostname = req.url.split(':')[0]
|
const hostname = req.url.split(':')[0]
|
||||||
|
|
|
@ -24,6 +24,9 @@ function domainMapRegexply (hostMap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchHostname (hostMap, hostname) {
|
function matchHostname (hostMap, hostname) {
|
||||||
|
if (hostMap == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
const value = hostMap[hostname]
|
const value = hostMap[hostname]
|
||||||
if (value) {
|
if (value) {
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -1,33 +1,25 @@
|
||||||
Arguments:
|
Arguments:
|
||||||
/usr/local/bin/node /usr/local/bin/yarn install
|
/usr/bin/node /usr/local/bin/yarn install
|
||||||
|
|
||||||
PATH:
|
PATH:
|
||||||
/usr/local/lib/ruby/gems/3.0.0/bin:/usr/local/opt/ruby/bin:/usr/local/opt/openssl@1.1/bin:/usr/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/Users/daiboning/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/daiboning/Desktop/codes/dev-sidecar/node_modules/.bin
|
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
|
||||||
|
|
||||||
Yarn version:
|
Yarn version:
|
||||||
1.22.10
|
1.22.11
|
||||||
|
|
||||||
Node version:
|
Node version:
|
||||||
14.15.4
|
14.17.5
|
||||||
|
|
||||||
Platform:
|
Platform:
|
||||||
darwin x64
|
linux x64
|
||||||
|
|
||||||
Trace:
|
Trace:
|
||||||
Error: https://registry.npm.taobao.org/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz?cache=0&sync_timestamp=1603219618123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimend%2Fdownload%2Fstring.prototype.trimend-1.0.2.tgz: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:1181
|
Error: ENOENT: no such file or directory, copyfile '/home/xiaojunnuo/.cache/yarn/v6/npm-webpack-4.44.2-6bfe2b0af055c8b2d1e90ed2cd9363f841266b72-integrity/node_modules/webpack/declarations/plugins/BannerPlugin.d.ts' -> '/home/xiaojunnuo/Codes/dev-sidecar/packages/mitmproxy/node_modules/webpack/declarations/plugins/BannerPlugin.d.ts'
|
||||||
at ClientRequest.onError (/usr/local/lib/node_modules/yarn/lib/cli.js:152235:17)
|
|
||||||
at Object.onceWrapper (events.js:422:26)
|
|
||||||
at ClientRequest.emit (events.js:315:20)
|
|
||||||
at Socket.socketErrorListener (_http_client.js:469:9)
|
|
||||||
at Socket.emit (events.js:315:20)
|
|
||||||
at emitErrorNT (internal/streams/destroy.js:106:8)
|
|
||||||
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
|
|
||||||
at processTicksAndRejections (internal/process/task_queues.js:80:21)
|
|
||||||
|
|
||||||
npm manifest:
|
npm manifest:
|
||||||
{
|
{
|
||||||
"name": "@docmirror/mitmproxy",
|
"name": "@docmirror/mitmproxy",
|
||||||
"version": "1.4.0",
|
"version": "1.5.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -56,6 +48,7 @@ npm manifest:
|
||||||
"node-cmd": "^3.0.0",
|
"node-cmd": "^3.0.0",
|
||||||
"node-forge": "^0.8.2",
|
"node-forge": "^0.8.2",
|
||||||
"require-context": "^1.1.0",
|
"require-context": "^1.1.0",
|
||||||
|
"stream-throttle": "^0.1.3",
|
||||||
"through2": "^2.0.1",
|
"through2": "^2.0.1",
|
||||||
"tunnel-agent": "^0.4.3",
|
"tunnel-agent": "^0.4.3",
|
||||||
"util": "^0.12.3",
|
"util": "^0.12.3",
|
||||||
|
@ -92,7 +85,7 @@ npm manifest:
|
||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not dead"
|
"not dead"
|
||||||
],
|
],
|
||||||
"gitHead": "660c77e4279c1499f771270941526614f927bdf1"
|
"gitHead": "3566cd6d33cbe782d91e408d6f174dd826b2790f"
|
||||||
}
|
}
|
||||||
|
|
||||||
yarn manifest:
|
yarn manifest:
|
||||||
|
@ -2104,7 +2097,7 @@ Lockfile:
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
commander@^2.20.0, commander@^2.9.0:
|
commander@^2.2.0, commander@^2.20.0, commander@^2.9.0:
|
||||||
version "2.20.3"
|
version "2.20.3"
|
||||||
resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1603599636161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1603599636161&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||||
integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=
|
integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=
|
||||||
|
@ -3898,6 +3891,11 @@ Lockfile:
|
||||||
prelude-ls "~1.1.2"
|
prelude-ls "~1.1.2"
|
||||||
type-check "~0.3.2"
|
type-check "~0.3.2"
|
||||||
|
|
||||||
|
limiter@^1.0.5:
|
||||||
|
version "1.1.5"
|
||||||
|
resolved "https://registry.npm.taobao.org/limiter/download/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2"
|
||||||
|
integrity sha1-j5KiWzsWxhMSk6DMg0tKg4oqp8I=
|
||||||
|
|
||||||
lines-and-columns@^1.1.6:
|
lines-and-columns@^1.1.6:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||||
|
@ -5387,6 +5385,14 @@ Lockfile:
|
||||||
resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||||
integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0=
|
integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0=
|
||||||
|
|
||||||
|
stream-throttle@^0.1.3:
|
||||||
|
version "0.1.3"
|
||||||
|
resolved "https://registry.npm.taobao.org/stream-throttle/download/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3"
|
||||||
|
integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=
|
||||||
|
dependencies:
|
||||||
|
commander "^2.2.0"
|
||||||
|
limiter "^1.0.5"
|
||||||
|
|
||||||
streamroller@^2.2.4:
|
streamroller@^2.2.4:
|
||||||
version "2.2.4"
|
version "2.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53"
|
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53"
|
||||||
|
|
Loading…
Reference in New Issue