Skip to content

Instantly share code, notes, and snippets.

@lzlrd
Last active March 29, 2021 14:17
Show Gist options
  • Select an option

  • Save lzlrd/90024c8cc38e3d6cf5483fc233d8a2b4 to your computer and use it in GitHub Desktop.

Select an option

Save lzlrd/90024c8cc38e3d6cf5483fc233d8a2b4 to your computer and use it in GitHub Desktop.
Cloudflare Worker DoH Proxy for AdGuard, with an Override for YouTube Restrictions
const skipCache = true
/* START OF {DE,EN}CODERS */
async function b64urlDecode(data) {
return atob((data + '==='.slice((data.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/'))
}
async function b64urlEncode(data) {
return btoa(data)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '')
}
async function hexEncode(data) {
return unescape(encodeURIComponent(data))
.split('').map(function (v) {
return v.charCodeAt(0).toString(16).padStart(2, '0')
}).join('')
}
/* END OF {DE,EN}CODERS */
async function badRequest() {
return new Response(null, {
status: 400
})
}
async function dnsWireHostname(wire) {
return wire.substr(25).substr(0, (wire.length - 35))
}
async function handleRequest(request) {
const url = new URL(request.url)
if (url.pathname == "/family") {
var backendDNS = "https://dns-family.adguard.com/dns-query"
} else if (url.pathname == "/plain") {
var backendDNS = "https://dns.adguard.com/dns-query"
} else {
return await badRequest()
}
if (request.method == "GET") {
const urlParamTest = new URLSearchParams(url.search)
const dnsReq = await hexEncode(await b64urlDecode(urlParamTest.get("dns")))
if (((await dnsWireHostname(dnsReq)) == "7796f757475626503636f6d") ||
((await dnsWireHostname(dnsReq)) == "377777707796f757475626503636f6d")) {
backendDNS = "https://dns.adguard.com/dns-query"
}
}
if (request.method == "GET") {
const urlParam = new URLSearchParams(url.search)
if (urlParam.has("dns")) {
var cachedValue = await DNS_CACHE.get(urlParam.get("dns"))
if (cachedValue === null || skipCache) {
const dnsQuery = backendDNS + "?dns=" + urlParam.get("dns")
var resp = await fetch(dnsQuery, {
headers: request.headers
})
if (cachedValue === null && !skipCache) {
await DNS_CACHE.put(urlParam.get("dns"), resp.body,
{ expirationTtl: 300 })
}
return resp
} else {
return new Response(cachedValue, {
headers: {
"content-length": cachedValue.length,
"content-type": "application/dns-message",
"date": (new Date()).toUTCString()
}
})
}
} else {
return await badRequest()
}
} else if (request.method == "POST") {
const encodedReq = await b64urlEncode(request.body)
var cachedValue = await DNS_CACHE.get(encodedReq)
if (cachedValue === null || skipCache) {
var resp = await fetch(backendDNS, {
method: "POST",
headers: request.headers,
body: request.body
});
if (cachedValue === null && !skipCache) {
await DNS_CACHE.put(encodedReq, resp.body,
{ expirationTtl: 300 })
}
return resp
} else {
return new Response(cachedValue, {
headers: {
"content-length": cachedValue.length,
"content-type": "application/dns-message",
"date": (new Date()).toUTCString()
}
})
}
} else {
return await badRequest()
}
}
addEventListener("fetch", event => {
return event.respondWith(handleRequest(event.request))
})
@lzlrd

lzlrd commented Mar 29, 2021

Copy link
Copy Markdown
Author

TODO

  • Implement the ability to override for POST requests.
  • Fix overrides working outside of dnslib tests.
  • Investigate CNAME redirection issues.
  • Investigate why caching cases HTTP 500 responses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment