2

The device can't ping www.google.com but ping 8.8.8.8 is okay. My OS is Android 6.0.1, the kernel is 4.1.15

I've tried the resolv.conf and /etc/hosts. But these methods seem can not work on Android.

And I couldn't figure out what the exact problem is.

eth0      Link encap:Ethernet  HWaddr EE:DE:17:79:BB:42
          inet addr:192.168.1.10  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ecde:17ff:fe79:bb42/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:600 TX bytes:1166

eth1      Link encap:Ethernet  HWaddr 00:0E:C6:81:79:01
          inet addr:192.168.120.57  Bcast:192.168.121.255  Mask:255.255.254.0
          inet6 addr: fe80::20e:c6ff:fe81:7901/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:41709 errors:0 dropped:0 overruns:0 frame:0
          TX packets:113 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2738793 TX bytes:8354

I closed the netd service so that it is able to configure eth0 and eth1 respectively.

Here is my IP rule

0:      from all lookup local
9998:   from all to 192.168.120.0/23 lookup 4
9999:   from all to 192.168.1.0/24 lookup 3
10000:  from all fwmark 0xc0000/0xd0000 lookup legacy_system
13000:  from all fwmark 0x10063/0x1ffff lookup local_network
15000:  from all fwmark 0x0/0x10000 lookup legacy_system
16000:  from all fwmark 0x0/0x10000 lookup legacy_network
17000:  from all fwmark 0x0/0x10000 lookup local_network
23000:  from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000:  from all unreachable

Here is a result of ping IP, you can see the response is fine.

root# ping 192.168.120.1
PING 192.168.120.1 (192.168.120.1) 56(84) bytes of data.
64 bytes from 192.168.120.1: icmp_seq=1 ttl=64 time=1.08 ms
64 bytes from 192.168.120.1: icmp_seq=2 ttl=64 time=0.986 ms
64 bytes from 192.168.120.1: icmp_seq=3 ttl=64 time=1.00 ms

root# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=0.718 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=0.420 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=255 time=0.403 ms

But ping google always returns unknown.

ping: unknown host www.google.com

I expect I could ping IP and URL in my case.

BTW, the DNS from eth0 192.168.1.245 and the DNS from eth1 is 8.8.8.8

0

I'll try to explain my understanding of DNS on Android. It will help you troubleshoot related problems and serve me as future notes.

Most part is not applicable to non-root users.

DNS:
Domain Name Resolver has traditionally been a part of OS's C library (commonly called libc). GNU libc (which is most common on Linux distros) implements a complicated name resolution mechanism named NSS which can prioritize in what order database services like LDAP / NIS, local files (/etc/hosts) and DNS have to be used in order to resolve host / domain names. DNS resolver then reads /etc/resolv.conf to get the name server address which is to be queried.

Unlike GNU libc, Android's Bionic libc (which depends on netd for DNS) doesn't regard /etc/resolv.conf unless ANDROID_CHANGES build variable is defined (only when libc++ is built as static library?). However /etc/hosts entries are valued by Android's resolver when resolving names.
But if you are using a statically compiled / linked binary with some other - such as musl or uC or diet - libc, that must be reading /etc/resolv.conf to get Domain Name Server's IP address. Busybox ping could be a common example. Also apps may sometimes bypass Android's name resolution mechanism trying directly reach out to some nameserver, I have observed WhatsApp.

ANDROID'S DNS:
Within Android's Java runtime environment, either a DHCP provided or hard coded DNS server is used. Properties net.dns1 and net.dns2 are set with values of DNS servers received from DHCP server (on Wi-Fi or Mobile Data) by ConnectivityService and then forwarded to netd. These values are also changeable from IP Settings of a connected Wi-Fi. Starting with Android Oreo, these properties are no longer available through Android APIs, but only readable as root or shell - once removed then re-added. Also there were some other DNS related properties set in good old days of dhcpcd which was the DHCP client up to Lollipop.

DNS queries are cached on Android as NSCD does on Linux distros to speed up name resolution. Android has a commandline tool ndc that can be used to clear DNS cache:

~# ndc resolver clearnetdns eth0

* Repeat same for other interfaces (ndc interface list)
* Commands syntax is a bit different on older versions

Previously different methods used to change default Domain Name Servers on Android don't seem to work now.
Changing properties net.dns* using setprop only affects the programs (running with UID 0 or 2000) that explicitly read these properties. One such example I can recall is meefik's busybox.
Similarly setting name servers through ndc resolver setnetdns makes no difference at all ( though ndc tether dns set works for dnsmasq). The only certain working option is iptables DNAT:

~# iptables -t nat -I OUTPUT -p udp --dport 53 -j DNAT --to 1.1.1.1:53

DNS servers can also be configured in Settings for Wi-Fi network. Non-root solution which works for both Wi-Fi and Mobile data is to use a VPN app like Virtual Hosts which intercepts DNS traffic and makes queries to configured upstream DNS server.

TESTING:
To test what name server is being used by connectivity and netd services in Java runtime:

~# dumpsys connectivity | grep CONNECTED | grep -o 'DnsAddresses: \[[^ ]*'
~# dumpsys netd | grep -A2 'DNS servers:'

And those used by tethering forwarding DNS server:

~# ndc tether dns list
~# logcat -d -s TetherController,dnsmasq | grep -E 'update_dns|nameserver'

To see where the DNS queries are going, you may capture traffic destined for port 53:

~# iptables -I OUTPUT -m udp -p udp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
~# iptables -I OUTPUT -m tcp -p tcp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
~# dmesg -w | grep 'DNS_QUERIES'

Or

~# tcpdump -n -i any port 53

* On Android Pie+, you need to set Private DNS off because by default DNS over TLS (DoT) sends encrypted DNS queries on port 853 as standardized in RFC7858

If the queries are not going to desired destination, there is some trouble with your DNS configuration, particularly if you use VPN. Dynamic nature of RPDB and routing tables (rt_tables keeps on changing, main table is not used) accompanied by fwmark (SO_MARK) make things complicated for manual control.

So there's nothing much you can do to fix DNS issues on Android devices. A Factory Reset or re-flashing of ROM may resolve the problem.

Additionally, if a local DNS server is provided by DHCP (server on Wi-Fi router), you may check if that's really listening on port 53:

~# nmap -e eth0 -sUT -p53 --script=dns-recursion 192.168.1.245

RELATED:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.