Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DoH returns 502 Bad Gateway #13

Open
domingo13 opened this issue Dec 20, 2021 · 7 comments
Open

DoH returns 502 Bad Gateway #13

domingo13 opened this issue Dec 20, 2021 · 7 comments

Comments

@domingo13
Copy link

domingo13 commented Dec 20, 2021

I'm using the provide example file "nginx-doh-and-dot-to-dns.conf" on a vanilla Ubuntu 20.04 server and all DoH request returns something like this:

 curl -k "https://localhost/dns-query?name=dr.dk&type=A" 
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.21.4</center>
</body>
</html>

cat /var/log/nginx/doh-access.log
127.0.0.1 - - [20/Dec/2021:15:36:57 +0100] "GET /dns-query?name=dr.dk&type=A HTTP/2.0" [ 1640011017.583, 2.144, 2.144 . ] 502 157 "-" - - - - - MISS
127.0.0.1 - - [20/Dec/2021:15:50:43 +0100] "GET /dns-query?name=dr.dk&type=A HTTP/2.0" [ 1640011843.444, 2.158, 2.159 . ] 502 157 "-" - - - - - MISS
127.0.0.1 - - [20/Dec/2021:15:54:25 +0100] "GET /dns-query?name=dr.dk&type=A HTTP/2.0" [ 1640012065.675, 2.293, 2.293 . ] 502 157 "-" - - - - - MISS

cat /var/log/nginx/error.log
2021/12/20 15:54:23 [warn] 997#997: *7 js: process_doh_request: QS Params: name=dr.dk,type=A
2021/12/20 15:54:23 [warn] 997#997: *7 js: process_doh_request: DNS Req: GET /dns-query?name=dr.dk&type=A HTTP/1.1
2021/12/20 15:54:25 [error] 997#997: *5 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: , request: "GET /dns-query?name=dr.dk&type=A HTTP/2.0", upstream: "http://127.0.0.1:8053/dns-query?name=dr.dk&type=A", host: "localhost"

I can see that it makes a connection to 8.8.8.8:
tcpdump -nn port 53
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
16:12:39.503706 IP 10.234.143.248.48290 > 8.8.8.8.53: Flags [S], seq 3079223311, win 64240, options [mss 1460,sackOK,TS val 3428279322 ecr 0,nop,wscale 7], length 0
16:12:39.533797 IP 8.8.8.8.53 > 10.234.143.248.48290: Flags [S.], seq 3540410280, ack 3079223312, win 65535, options [mss 1430,sackOK,TS val 1093201396 ecr 3428279322,nop,wscale 8], length 0
16:12:39.533860 IP 10.234.143.248.48290 > 8.8.8.8.53: Flags [.], ack 1, win 502, options [nop,nop,TS val 3428279352 ecr 1093201396], length 0
16:12:41.810625 IP 8.8.8.8.53 > 10.234.143.248.48290: Flags [F.], seq 1, ack 1, win 256, options [nop,nop,TS val 1093203419 ecr 3428279352], length 0
16:12:41.810626 IP 8.8.8.8.53 > 10.234.143.248.48290: Flags [F.], seq 1, ack 1, win 256, options [nop,nop,TS val 1093203650 ecr 3428279352], length 0
16:12:41.810699 IP 10.234.143.248.48290 > 8.8.8.8.53: Flags [.], ack 2, win 502, options [nop,nop,TS val 3428281629 ecr 1093203650,nop,nop,sack 1 {1:2}], length 0
16:12:41.810970 IP 10.234.143.248.48290 > 8.8.8.8.53: Flags [F.], seq 1, ack 2, win 502, options [nop,nop,TS val 3428281629 ecr 1093203650], length 0
16:12:41.835986 IP 8.8.8.8.53 > 10.234.143.248.48290: Flags [.], ack 2, win 256, options [nop,nop,TS val 1093203698 ecr 3428281629], length 0

but nothing is transmitted.

What I'm I missing?

@TuxInvader
Copy link
Owner

TuxInvader commented Jan 4, 2022

Hi @domingo13 ,

The dns query should be in this format: https://datatracker.ietf.org/doc/html/rfc8484#section-4.1.1

The url in your example should be "http://127.0.0.1:8053/dns-query?dns=<< base64 encoded DNS packet >>. It looks like you are tyring to use the JSON API for DoH as mentioned here: https://developers.google.com/speed/public-dns/docs/doh/json, but this project doesn't support that at this time.

@own3mall
Copy link

own3mall commented Jul 9, 2022

@TuxInvader what all would be needed to be done to support the JSON API? That would be extremely useful!

@mallory98e
Copy link

I'm sorry but how on earth that example even makes sense.

What he suggest is:

echo AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB|base64 -d
wwwexamplecom

So without the dots how could it separate the tags of a domain name, it can be test.company.de or whatever.

Is there a proper implementation of this whole DoH thingy which works with Android 13 and other clients?

The reason I asking is because newer android phones go for DoT by default if they can instead of using plain old DNS on port 53, but in the future they might even default to DoH. I assume they would use the JSON interface for it.

@TuxInvader
Copy link
Owner

TuxInvader commented May 15, 2023

I'm sorry but how on earth that example even makes sense.

What he suggest is:

echo AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB|base64 -d wwwexamplecom

So without the dots how could it separate the tags of a domain name, it can be test.company.de or whatever.

Is there a proper implementation of this whole DoH thingy which works with Android 13 and other clients?

The reason I asking is because newer android phones go for DoT by default if they can instead of using plain old DNS on port 53, but in the future they might even default to DoH. I assume they would use the JSON interface for it.

The base64 string is an encoded DNS packet, your terminal is only displaying the ASCII characters. If you pipe the decoded data to od then you'll see more detail: echo AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB | base64 -d | od -ax

To answer your question, each record is prefixed with a length, so the dots are unnecessary. The "www" record is encoded as 7703 7777 hex - the 03 is the field length and the 77s are ASCII 'w'.

@mallory98e
Copy link

I'm sorry but how on earth that example even makes sense.
What he suggest is:
echo AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB|base64 -d wwwexamplecom
So without the dots how could it separate the tags of a domain name, it can be test.company.de or whatever.
Is there a proper implementation of this whole DoH thingy which works with Android 13 and other clients?
The reason I asking is because newer android phones go for DoT by default if they can instead of using plain old DNS on port 53, but in the future they might even default to DoH. I assume they would use the JSON interface for it.

The base64 string is an encoded DNS packet, your terminal is only displaying the ASCII characters. If you pipe the decoded data to od then you'll see more detail: echo AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB | base64 -d | od -ax

To answer your question, each record is prefixed with a length, so the dots are unnecessary. The "www" record is encoded as 7703 7777 hex - the 03 is the field length and the 77s are ASCII 'w'.

Whose idea was this :/
Yeah I see that it makes sense for domain names like domaaaaaaaaaaaaaaaaaaaaaaaain.com to save some space.

Anyway. Is there any tool (preferably in the base os not some python/perl) which can create such weird base64 output from input data?

@TuxInvader
Copy link
Owner

If you want to generate the string, then you could use netcat with dig, something like this should work:

nc -undl 5553 -w 1 |  base64 > dns.txt &
dig -p 5553 @localhost www.google.com +tries=1 +qid=0 +timeout=1 
cat dns.txt

But dig can generate DoH requests for you too using +https or +http-plain. Eg:

dig -p 8080 @localhost www.google.com +tries=1 +qid=0 +timeout=1 +https

@mallory98e
Copy link

@TuxInvader what all would be needed to be done to support the JSON API? That would be extremely useful!

I closed this thread with this:

https://github.com/satishweb/docker-doh

I found a project which does support both and works out of the box with a single docker image. Hope it helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants