My laptop connects to the internet through Android wifi tethering (hotspot).
Some websites cannot be connected because my Android DNS server returns 127.0.0.1
.
I can browse the sites on my Android phone, but not through the hotspot due to this strange DNS behavior.
For example, I can't connect to tools.ietf.org to read RFC documentations. The DNS server just returns 127.0.0.1
.
Info about my Android device:
Redmi note 5 global/pro (whyred), running MIUI 11
, Android 9
.
The DNS server is dnsmasq
, according to this question, and I've checked it by netstat
.
It is listening on 127.0.0.1:53
& 192.168.43.1:53
.
sudo getprop | grep dns
:
[init.svc.mdnsd]: [running]
[net.dns1]: [172.24.x.x] # this DNS server returns correct IP
[net.dns2]: [10.x.x.x] # this returns 127.0.0.1 for some sites
[net.dns3]: [xxxx:xxxx:xxxx::xxxx]
[net.dns4]: [8.8.8.8] # the always working 8.8.8.8
[ro.boottime.mdnsd]: [147300891920]
dnsmasq
command found by ps auxf
:
/system/bin/dnsmasq
--keep-in-foreground # Do NOT fork into the background, do NOT run in debug mode.
--no-resolv # Do NOT read resolv.conf.
--dhcp-ignore-names # Ignore hostnames provided by DHCP clients.
--no-poll # Do NOT poll /etc/resolv.conf file, reload only on SIGHUP.
--dhcp-authoritative # Assume we are the only DHCP server on the local network.
--dhcp-option-force=43,ANDROID_METERED # DHCP option sent even if the client does not request it.
--pid-file # Specify path of PID file (defaults to /var/run/dnsmasq.pid). Empty here.
--listen-mark 0xf0063 # Socket mark to use for listen sockets.
--user dns_tether # Change to this user after startup. (defaults to nobody).
--dhcp-range=192.168.42.2,192.168.42.254,1h
--dhcp-range=192.168.43.2,192.168.43.254,1h
...
--dhcp-range=192.168.51.2,192.168.51.254,1h
I killed the server launched by my system, and did some experiments.
If I add --all-servers
(Always perform DNS queries to all servers.), dig
's response would be ANSWER: 0
.
Because there's no server set. (Default conf file /etc/dnsmasq.conf
not exists)
If I also add --conf-file=/sdcard/dnsmasq.conf
, with file content server=8.8.8.8
, I'm able to connect to tools.ietf.org.
Question is, what would dnsmasq
do, when there's no config file (dnsmasq.conf
)?
If there's no dns server specified, how does it query upstream DNS?
And why it works for most domains, but not all?
Guess there's something to do with [net.dns2]: [10.x.x.x] # this returns 127.0.0.1 for some sites
?
Update 1 (more info)
After I reboot my phone, the [10.x.x.x] DNS server returns ANSWER: 0
.
My dnsmasq
returns correct answer. I don't know why.
I read & searched more to understand Android DNS more.
Here's more info:
sudo /system/bin/dumpsys netd
:
NetworkController
Default network: 100
Networks:
1 PHYSICAL rmnet_data0
Required permission: SYSTEM
No DNS servers defined
No search domains defined
Private DNS mode: OFF
No Private DNS servers configured
2 PHYSICAL
...
51 DUMMY dummy0
...
99 LOCAL wlan0
...
100 PHYSICAL rmnet_data1
Required permission: NONE
DNS servers: # IP (total, successes, errors, timeouts, internal errors, RTT avg, last sample)
172.24.x.x (64, 64, 0, 0, 0, 61ms, 54s)
10.x.x.x <no data>
No search domains defined
DNS parameters: sample validity = 1800s, success threshold = 25%, samples (min, max) = (8, 64)
Private DNS mode: OFF
No Private DNS servers configured
Interface <-> last network map:
Ifindex: 10 NetId: 100
Ifindex: 9 NetId: 1
Interface addresses:
address: xxxx::xxxx:xxxx:xxxx:xxxx/64 ifindices: [26]
address: 192.168.43.1/24 ifindices: [26]
address: x.x.x.x/30 ifindices: [10]
address: xxxx::xxxx:xxxx:xxxx:xxxx/64 ifindices: [9]
Dns Resolve Records
total records=1000
rec[0]: 13:58:37 3961 10032 s*.com=127.*,
...
rec[999]: 19:50:04 3961 10032 s*.com=127.*,
TrafficController
BPF module status: OFF
So there are 2 DNS servers in rmnet_data1
.
I think these are upstream servers dnsmasq would query.
Maybe it queryed the 10.x.x.x DNS server, which returned 127.0.0.1
, then it cached this wrong result.
A reboot may have cleared this, or it is out of life time now.
I just found there's a --log-queries Log DNS queries.
option in dnsmasq.
So I would be able to see what exactly happens the next time I fail to connect to tools.ietf.org.
So it seems to be my upstream DNS servers' problem, with some probability of happening because there are 2 DNS servers?
So this is my ISP's problem? Not resolving some domains correctly?
Some very nice Q&A here:
- DNS queries are cached permanently, how to reliably clear DNS cache on Android 7+?: explains DNS query in details
- How does Android OS do DNS name resolution?: explains Android DNS resolv in details
Update 2 (guessing reason / answer)
I think this strange behavior (able to connect on phone, but not through hotspot) is because there are 2 DNS cache in Android, one in system & another in Java. (According to this answer)
Chrome & other apps are probably using Java cache. The dnsmasq
native binary is using system cache. I guess this is why.
In the end, though already dug quite deeply, I still didn't find a good way to solve this.
Next time I encounter this problem, I'll still just change my laptop's DNS server to 8.8.8.8
.