-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.ts
65 lines (51 loc) · 1.8 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import * as dnsPacket from 'dns-packet'
import { Buffer } from 'buffer'
const DOH_ADDRESS = "cloudflare-dns.com/dns-query"
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url)
const { pathname, search } = url
if (pathname == "/") {
return new Response(`200 OK`, { status: 200 })
}
if (request.method !== "GET" && request.method !== "POST") {
return new Response(`Method ${request.method} not allowed.`, { status: 405 })
}
// Get the client's IP address from the request headers
const clientIp = request.headers.get('CF-Connecting-IP')
if (!clientIp) {
throw new Error('Client IP not found in request headers')
}
// Determine the source prefix length based on the IP address type
const sourcePrefixLength = clientIp.includes(':') ? 48 : 24
// Parse the DNS packet from the request body
const body = await request.clone().arrayBuffer()
const dnsMsg = dnsPacket.decode(Buffer.from(body))
// Create an EDNS Client Subnet option
const ecsOption = {
code: 'CLIENT_SUBNET',
ip: clientIp,
sourcePrefixLength: sourcePrefixLength,
scopePrefixLength: 0
}
// Add the EDNS option to the DNS packet
dnsMsg.additionals.push({
type: 'OPT',
name: '.',
udpPayloadSize: 4096,
options: [ecsOption]
})
// Enable DNSSEC by setting the DO flag
dnsMsg.flags |= (1 << 15)
// Encode the modified DNS packet back into the request body
const modifiedBody = dnsPacket.encode(dnsMsg)
const newURL = `https://${DOH_ADDRESS}`
const newRequest = new Request(newURL, {
body: modifiedBody,
headers: request.headers,
method: request.method,
redirect: request.redirect
})
return await fetch(newRequest)
},
}