Skip to content

Commit 897056c

Browse files
feat: 代理请求支持IPv6了
1 parent a8d36d1 commit 897056c

8 files changed

Lines changed: 76 additions & 38 deletions

File tree

packages/mitmproxy/src/lib/dns/base.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,7 @@ module.exports = class BaseDNS {
5353
}
5454
}
5555

56-
async lookup (hostname, options) {
57-
if (!options) {
58-
options = {
59-
ipChecker: undefined,
60-
family: 4,
61-
}
62-
}
63-
56+
async lookup (hostname, options = {}) {
6457
try {
6558
let ipCache = this.cache.get(hostname)
6659
if (ipCache) {

packages/mitmproxy/src/lib/dns/index.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,35 @@ module.exports = {
8989

9090
return dnsMap
9191
},
92-
getDNS (dnsConfig, hostname) {
93-
// 先匹配 预设IP配置
94-
const hostnamePreSetIpList = matchUtil.matchHostname(dnsConfig.preSetIpList, hostname, 'matched preSetIpList(getDNS)')
92+
getDNSAndFamily (dnsConfig, hostname) {
93+
// 1. 匹配 预设IP配置
94+
const hostnamePreSetIpList = matchUtil.matchHostname(dnsConfig.preSetIpList, hostname, 'matched preSetIpList(getDNSAndFamily)')
9595
if (hostnamePreSetIpList) {
96-
return dnsConfig.dnsMap.PreSet
96+
return {
97+
dns: dnsConfig.dnsMap.PreSet,
98+
}
9799
}
98100

99-
// 再匹配 DNS映射配置
100-
const providerName = matchUtil.matchHostname(dnsConfig.mapping, hostname, 'get dns providerName')
101+
// 2. 读取域名对应的DNS配置
102+
const dnsData = matchUtil.matchHostname(dnsConfig.mapping, hostname, 'get dns data')
103+
if (!dnsData) {
104+
return null
105+
}
101106

102107
// 由于DNS中的usa已重命名为cloudflare,所以做以下处理,为了向下兼容
103-
if (providerName === 'usa' && dnsConfig.dnsMap.usa == null && dnsConfig.dnsMap.cloudflare != null) {
104-
return dnsConfig.dnsMap.cloudflare
108+
let dns
109+
if (dnsData.dnsName === 'usa' && dnsConfig.dnsMap.usa == null && dnsConfig.dnsMap.cloudflare != null) {
110+
dns = dnsConfig.dnsMap.cloudflare
111+
} else {
112+
dns = dnsConfig.dnsMap[dnsData.dnsName]
113+
if (!dns) {
114+
return null
115+
}
105116
}
106117

107-
if (providerName) {
108-
return dnsConfig.dnsMap[providerName]
118+
return {
119+
dns,
120+
family: dnsData.family,
109121
}
110122
},
111123
}

packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ function connect (req, cltSocket, head, hostname, port, dnsConfig = null, isDire
112112
connectTimeout: 10000,
113113
}
114114
if (dnsConfig && dnsConfig.dnsMap) {
115-
const dns = DnsUtil.getDNS(dnsConfig, hostname)
116-
if (dns) {
117-
options.lookup = dnsLookup.createLookupFunc(null, dns, 'connect', hostport, port, isDnsIntercept)
115+
const dnsFamily = DnsUtil.getDNSAndFamily(dnsConfig, hostname)
116+
if (dnsFamily) {
117+
options.lookup = dnsLookup.createLookupFunc(null, dnsFamily, 'connect', hostport, port, isDnsIntercept)
118118
}
119119
}
120120
// 代理连接事件监听

packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,23 @@ module.exports = function createRequestHandler (createIntercepts, middlewares, e
114114

115115
const isDnsIntercept = {}
116116
if (dnsConfig && dnsConfig.dnsMap) {
117-
let dns = DnsUtil.getDNS(dnsConfig, rOptions.hostname)
118-
if (!dns && rOptions.servername) {
119-
dns = dnsConfig.dnsMap.ForSNI
117+
let dnsFamily = DnsUtil.getDNSAndFamily(dnsConfig, rOptions.hostname)
118+
if (!dnsFamily && rOptions.servername) {
119+
const dns = dnsConfig.dnsMap.ForSNI
120120
if (dns) {
121-
log.info(`域名 ${rOptions.hostname} 在dns中未配置,但使用了 sni: ${rOptions.servername}, 必须使用dns,现默认使用 '${dns.dnsName}' DNS.`)
121+
dnsFamily = { dns }
122+
log.info(`域名 ${rOptions.hostname} 在dns中未配置,但使用了 sni: ${rOptions.servername}, 必须使用dns,现默认使用 '${dnsFamily.dnsName}' DNS.`)
122123
} else {
123-
log.warn(`域名 ${rOptions.hostname} 在dns中未配置,但使用了 sni: ${rOptions.servername}且DNS服务管理中,也未指定SNI默认使用的DNS。`)
124+
log.warn(`域名 ${rOptions.hostname} 在dns中未配置,但使用了 sni: ${rOptions.servername}然而DNS服务管理中,并未指定SNI默认使用的DNS。`)
124125
}
125126
}
126-
if (dns) {
127-
rOptions.lookup = dnsLookup.createLookupFunc(res, dns, 'request url', url, rOptions.port, isDnsIntercept)
128-
log.debug(`域名 ${rOptions.hostname} DNS: ${dns.dnsName}`)
129-
res.setHeader('DS-DNS', dns.dnsName)
127+
if (dnsFamily) {
128+
rOptions.lookup = dnsLookup.createLookupFunc(res, dnsFamily, 'request url', url, rOptions.port, isDnsIntercept)
129+
if (dnsFamily.family === 6) {
130+
rOptions.family = dnsFamily.family
131+
}
132+
log.debug(`域名 ${rOptions.hostname} DNS: ${dnsFamily.dns.dnsName}`)
133+
res.setHeader('DS-DNS', dnsFamily.dns.dnsName)
130134
} else {
131135
log.info(`域名 ${rOptions.hostname} 在DNS中未配置`)
132136
}

packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ function createIpChecker (tester) {
2626
}
2727

2828
module.exports = {
29-
createLookupFunc (res, dns, action, target, port, isDnsIntercept) {
29+
createLookupFunc (res, dnsFamily, action, target, port, isDnsIntercept) {
3030
target = target ? (`, target: ${target}`) : ''
3131

32+
const dns = dnsFamily.dns
33+
const family = dnsFamily.family || 4
34+
3235
return (hostname, options, callback) => {
3336
const tester = speedTest.getSpeedTester(hostname, port)
3437
if (tester) {
@@ -38,7 +41,6 @@ module.exports = {
3841
if (res) {
3942
res.setHeader('DS-DNS-Lookup', `IpTester: ${aliveIpObj.host} ${aliveIpObj.dns === '预设IP' ? 'PreSet' : aliveIpObj.dns}`)
4043
}
41-
const family = aliveIpObj.host.includes(':') ? 6 : 4
4244
callback(null, aliveIpObj.host, family)
4345
return
4446
} else {
@@ -48,19 +50,22 @@ module.exports = {
4850

4951
const ipChecker = createIpChecker(tester)
5052

51-
dns.lookup(hostname, { ipChecker }).then((ip) => {
53+
// TODO: 临时打印下日志
54+
if (hostname.includes('googlevideo.com') || hostname.includes('gvt1.com')) {
55+
log.debug(`[${hostname}] 使用的lookup参数:dns: ${dns.dnsName}, family: ${family}`)
56+
}
57+
dns.lookup(hostname, { ipChecker, family }).then((ip) => {
5258
if (isDnsIntercept) {
5359
isDnsIntercept.dns = dns
5460
isDnsIntercept.hostname = hostname
5561
isDnsIntercept.ip = ip
5662
}
5763

5864
if (ip !== hostname) {
59-
log.info(`----- ${action}: ${hostname}, use ip from dns '${dns.dnsName}': ${ip}${target} -----`)
65+
log.info(`----- ${action}: ${hostname}, use ip from dns '${dns.dnsName}': ${ip}(family: ${family})${target} -----`)
6066
if (res) {
6167
res.setHeader('DS-DNS-Lookup', `DNS: ${ip} ${dns.dnsName === '预设IP' ? 'PreSet' : dns.dnsName}`)
6268
}
63-
const family = ip.includes(':') ? 6 : 4
6469
callback(null, ip, family)
6570
} else {
6671
// 使用默认dns

packages/mitmproxy/src/lib/speed/SpeedTester.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class SpeedTester {
9494
}
9595

9696
async getFromOneDns (dns) {
97+
// TODO: 临时判断一下
9798
const family = (this.hostname.includes('googlevideo.com') || this.hostname.includes('gvt1.com')) ? 6 : 4
9899
return await dns._lookupWithPreSetIpList(this.hostname, { family })
99100
}

packages/mitmproxy/src/options.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,35 @@ function getExclusionArray (exclusions) {
3535
return ret
3636
}
3737

38+
function handleDnsMapping (dnsMapping) {
39+
// 循环读取所有key value
40+
for (const hostname in dnsMapping) {
41+
const value = dnsMapping[hostname]
42+
if (value == null) {
43+
delete dnsMapping[hostname]
44+
continue
45+
}
46+
47+
if (typeof value === 'string') {
48+
dnsMapping[hostname] = {
49+
dnsName: value,
50+
family: hostname.includes('googlevideo.com') || hostname.includes('gvt1.com') ? 6 : null, // TODO: 暂时指定 googlevideo.com 使用IPv6
51+
}
52+
} else if (value.dnsName == null) {
53+
log.warn(`域名 ${hostname} 的DNS配置有误,未配置dnsName,配置值:`, value)
54+
delete dnsMapping[hostname]
55+
}
56+
}
57+
58+
return dnsMapping
59+
}
60+
3861
module.exports = (serverConfig) => {
3962
const intercepts = matchUtil.domainMapRegexply(buildIntercepts(serverConfig.intercepts))
4063
const whiteList = matchUtil.domainMapRegexply(serverConfig.whiteList)
4164
const timeoutMapping = matchUtil.domainMapRegexply(serverConfig.setting.timeoutMapping)
4265

43-
const dnsMapping = serverConfig.dns.mapping
66+
const dnsMapping = handleDnsMapping(serverConfig.dns.mapping)
4467
const setting = serverConfig.setting
4568

4669
if (!setting.script.dirAbsolutePath) {

packages/mitmproxy/test/ipv6-test.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const dnsProviders = dns.initDNS({
1111

1212
// tls
1313
aliyunTLS: {
14-
server: 'tls://223.5.5.5:853',
14+
server: 'tls://dns.alidns.com',
1515
cacheSize: 1000,
1616
},
1717

@@ -28,7 +28,7 @@ const dnsProviders = dns.initDNS({
2828
},
2929
}, null)
3030

31-
const hostname = 'rr5---sn-4g5e6nzl.gvt1.com'
31+
const hostname = 'rr4---sn-npoe7nek.gvt1.com'
3232
// const hostname = 'rr5---sn-4g5e6nzl.googlevideo.com'
3333
// const hostname = 'www.youtube.com'
3434

0 commit comments

Comments
 (0)