Using an internal DNS server

After switching to LOS, I have problems using the DNS servers on my internal network. This is needed to be able to connect to internal servers by hostname.

All DNS queries seem to go to g*'s DNS server ( and I confirmed this by using host -v which then reports that is not found on one of those servers.

What is my use case ?

  • Run as much open source as possible :wink:
  • Use internal DNS server when either connected to my own WiFi (but not others) or when I have activated the VPN to tunnel to my internal network from elsewhere.

This worked out of the box on Android 5 FPOOS (haven’t tried 6).

I have been playing around with DNS66 but

  • I can’t seem to figure out how to use it for what I want
  • Will it be able to apply different rules for different settings ?
  • It works by setting up a VPN. Does that work when I set up a second VPN to my home network ?

I also tried AFWall+. That seemed more promising when using the customized scripts. I did create a script that seems to work when running it from ADB. However, using the same script in AFWall seems to confuse it and I regularly get blocked without any DNS service :frowning: .

Is there something wrong with the script ?

Are there other alternatives ? I can think of

  • udev rules to run the mentioned script
  • get a notification on network setting changes and then run the script
  • cron job (shudder, what will that do to battery consumption ?)

Here’s the script:


TRUSTED_DNS_SERVERS='    Chaos Computer Club   Digitalcourse e.V. 1 2  ISC'



net=$(ip -o addr | grep '^[0-9]*:[[:space:]]*tun' | sed 's/.*inet \([0-9./]*\).*/\1/' | fgrep $INTERNAL_NETWORK)
if [[ -n "$net" ]]
  timeout 3 nc -q 2 -w 2 $INTERNAL_SERVER $IN_SRV_PORT >/dev/null 2>&1
  if (( $retval == 142 ))

if [[ $internal_network == 'yes' ]]
  nr_servers=$(echo "$TRUSTED_DNS_SERVERS" | wc -l)
  DNS1=$(echo "$TRUSTED_DNS_SERVERS" | cut -c-16 | sed -n "$(( $RANDOM % $nr_servers + 1 ))p")
  DNS1=$(echo $DNS1) # strip spaces
  DNS2=$(echo "$TRUSTED_DNS_SERVERS" | cut -c-16 | sed -n "$(( $RANDOM % $nr_servers + 1 ))p")
  DNS2=$(echo $DNS2) # strip spaces

$IPTABLES -t nat -A $CHAIN_NAME -p tcp --dport 53 -d -j DNAT --to-destination $DNS1:53
$IPTABLES -t nat -A $CHAIN_NAME -p udp --dport 53 -d -j DNAT --to-destination $DNS1:53
$IPTABLES -t nat -A $CHAIN_NAME -p tcp --dport 53 -d -j DNAT --to-destination $DNS2:53
$IPTABLES -t nat -A $CHAIN_NAME -p udp --dport 53 -d -j DNAT --to-destination $DNS2:53

# disallow any DNS query going to google
$IPTABLES -I $CHAIN_NAME -p tcp --dport 53 -d -j REJECT
$IPTABLES -I $CHAIN_NAME -p udp --dport 53 -d -j REJECT
$IPTABLES -I $CHAIN_NAME -p tcp --dport 53 -d -j REJECT
$IPTABLES -I $CHAIN_NAME -p udp --dport 53 -d -j REJECT


Thanks for any help. This is driving me crazy.

Does your dhcp server give out the DNS?

What does “getprop | grep -i dns” reply?


Mainwhile tried the suggestions on xda.

None of them seem to work, except the firewall one.

The dhcp server gives it out. No problems on Android 5 nor on my laptop.

# getprop | grep -i dns
[net.change]: [net.dns2]
[net.dns1]: []
[net.dns2]: []

That seems fine, but still no ping response.

weird that you have two DNSs on different network segments. Does your dhcp give them out both?

1 Like

what does “route” say?

I guess the second on is still left from my previous tries :wink:
My router only passes out the first one.

Well, if it uses the 2nd one, then no wonder your local addresses are not found.


Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface * U 0 0 0 wlan0

ip route show dev wlan0 proto kernel scope link src

“host -v somelocalname” does not work for me either, you have to pass the DNS as 2nd argument.

host -v localserver

Hmm, it doesn’t seem to use either.

When I go to termux and type host -v it get something like this:

Host not found: 3 (NXDOMAIN)
Received 102 bytes from in 61 ms
Received 102 bytes from in 61 ms

Could I try something else to pinpoint the actually used DNS server ?

host command in adb shell seems to not support the -v option.

I guess that termux uses a different host command than the system one.

Setting a second argument will force host to use that DNS server. I want to know what it uses by default.

Strange, from adb shell as root I sometimes ping using the dns name.

Other times it doesn’t do that :confused:

i would still blame your 2nd DNS entry that is “wrong”. :slight_smile:


Look at adb logcat output. You should see something like:

11-05 12:29:57.621 2314 3751 D ConnectivityService: Setting DNS servers for network 100 to [/myIPV6DNS, /]

Indeed, I see a similar thing.

Doublechecked the WiFi settings -> I see the second DNS is set the the ‘wrong’ one.

Setting it to the same and trying again.

Seems to work OK now. Both for the WiFi connection and via VPN over 4G :slight_smile:

  • Removed AFWall and DNS66 (to have less moving parts).
  • Installed GmsCore as system app (related or not ? Mention for completeness)
  • Put the DNS servers the same for DNS1 & DNS2 on the WiFi

After switching the WiFi connection back to DHCP, it still works !

Not sure what caused the initial problems but it seems fixed now :smiley:

@chrmhoffmann Thanks for the help.

If that problem is solved now: How can i set up that script on my FP2? Just run it as root?
Is the script in your first post already corrected? or still wrong?

Yes, I also just learned this :smile:

The relevant file is /data/data/com.termux/files/usr/etc/resolv.conf