24

I want to avoid censorship from my local mobile ISP (it blocks imgur, for example, for some unknown reason.

Screenshot
Screenshot (click image for larger variant)

I'm pretty certain that I can circumvent this by changing my DNS to Google DNS or OpenDNS, but I'm not really sure how to accomplish this on KitKat.

Info:
Device: Nexus 5
Android version: 4.4.2
Device status: rooted
18

Ok, first of all full disclosure: I'm the author of an app which is now on the Google Play Store and which makes you able to change DNS for any mobile connection on Android 4.4. The app requires root, costs a couple of bucks and is called Override DNS. I was told, on a now deleted answer, that is fair to link to my app as long as I expose it clearly.

The problem I found with this release of Android (4.4) is that, apparently for caching reasons, the system behaviour has been changed to redirect all DNS queries to a system daemon called netd (here's a link to a presentation related to Android networking before 4.4 which, however, covers part of these topics).

The getprop/setprop method does not work anymore. Those values, when changed, get simply ignored by the netd daemon.

It's necessary to communicate directly to the daemon via the /dev/socket/netd socket. In Android it's now present a tool called ndc which does exactly this job.

The syntax for the DNS related stuff is this:

# ndc resolver flushif <iface>
# ndc resolver flushdefaultif
# ndc resolver setifdns <iface> <domains> <dns1> <dns2>
# ndc resolver setdefaultif <iface>

The app automatically guesses the network device name and applies these commands each time a mobile network gets activated.

  • The correct syntax of setifdns is: ndc resolver setifdns <iface> <domains> <dns1> <dns2> .... Example: ndc resolver setifdns eth0 "" 8.8.8.8 8.8.4.4 – Christian d'Heureuse Jan 10 '15 at 22:14
  • @Christiand'Heureuse you're right, I updated the answer, thank you. – MaxChinni Jan 11 '15 at 0:45
13

I "solved" this problem by using an iptables rule to forward all port 53 connections to an intended DNS server; my experience on Android 4.4.2 with attempting to modify DNS settings while connected to 3G has been exactly as Leo described; ignorance of values in getprop |grep dns[0-9]\]: and dhcpd.conf.

iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 8.8.8.8:53

The reason is as described here: http://forum.xda-developers.com/showpost.php?p=44722857&postcount=6 All apps do DNS lookups through netd via a /dev/socket/dnsproxyd unix socket. This thread also describes why system properties are being ignored.

To undo this, do

iptables -t nat -L OUTPUT -n -v --line-numbers

, find the line number that corresponds to udp dpt:53 to:xxx.xxx.xxx.xxx:53 and do

iptables -t nat -D OUTPUT *linenumber*
  • 2
    Thanks! also, summary of the reason: Google is playing arms race with ad blockers. they tried to disable the current means ad blockers worked, and ad blockers moved to another one, while all users (regardless of using ad blocker or not) will be forever annoyed by that google move. ...I thought everyone knew fighting against ad blockers was a dumb move by now. silly google. (also, opensource app AFWALL is a convenient way to add this custom rule easily) – gcb Jul 15 '14 at 0:22
  • AfWall+ wiki about how to apply custom iptables rule like this – betatester07 Mar 25 '16 at 22:37
1

Sadly, it may be impossible to do as of right now, however, it is possible to try DNS Changer. This may work if you are rooted, but there are no guarantees.

A good DNS service to use would be Google's public DNS service. It tends to work out very well for these type of issues right here.

If none of this works, keep looking for answers. A good site for things like this is XDA Developers. They tend to have many answers on things for Android.

1

I'm on KitKat Cyanogenmod 11, meaning I'm rooted by default. Despite that I can only report failure:

1st method:

When I try the adb shell with

setprop net.rmnet0.dns1 208.67.222.222
setprop net.rmnet0.dns2 208.67.222.222
setprop net.rmnet1.dns1 208.67.222.222
setprop net.rmnet1.dns2 208.67.222.222
setprop net.rmnet2.dns1 208.67.222.222
setprop net.rmnet2.dns2 208.67.222.222
setprop net.dns1 208.67.222.222
setprop net.dns1 208.67.222.222

and then test to which IP hjfdkhfjkyuiwnwetbyebvtwgqwdi.tk resolve's... I get an NXDOMAIN response, meaning it didn't came from the OpenDNS nameserver I've set (which would return an answer with an alternative IP, to serve you adds).

When doing

getprop | grep dns

I would only see what I've configured. However when switching from WiFi to mobile (3G or 4G/LTE) I see IP's that I recognize as being assigned to my mobile carrier. Apps like "DNSwitch" or "DNS Changer" can re-set those resolvers automaticly at network change. However what getprop reports me, is still not what's truly doing the resolving.

2nd method [a]:

Another way I tried, is modifieng /system/etc/dhcpcd/dhcpcd-hooks/20-dns.conf an set things fixed in there (but be aware network names and number of resolvers can differ). Without success.

2nd method [b]:

And in /system/etc/dhcpcd/dhcpcd.conf I removed the parameter to accept resolvers at DHCP negociation. No success either.

3th method:

So far the only thing that would work a little is using a "poor man VPN", using the app "SSH Tunnel", using SOCKS4, but using that I did not exactly got a good result.

Resume:

It seems like either DNS set elsewhere, or all are forwarded (hijacked) as soon the network is mobile.

So, how come? Is it another dirty way to provide carriers with a tool to demolish network neutrality?

In your case your question was because of that. Do you have SSH to try if SSHTunnel is a alternative solution to get around your carriers censoring?

  • I have found a way to circumvent the block, but it's cumbersome and on a case-by-case basis. I'm rooted so I have access to the hosts file. Next, I looked for imgur's direct IP addresses, then I manually input those values to the hosts file. Problem solved for now. – user51893 Mar 11 '14 at 16:48
1

I encountered the same problem today, and thanks to Transfusion. I tried to develop an app "DNS forwarder" to work it out. It does not change dns server on system, but forward dns queries to another server. This workaround works fine for me on Kitkat (Nexus 5/4.4.3 and Moto Razr/CM11). Hope it can help other as well.

  • This actually works, not sure why you got down voted – warsong Nov 30 '14 at 22:46
0

Currently I don't think there's any way to change your DNS on your mobile data. But if your phone is rooted you can use apps like Set DNS.

  • Sadly, that app doesn't seem to support Android 4.3 and above :( Taken from the app's description: "PLEASE DON'T INSTALL ON ANDROID 4.3 FOR THE MOMENT, THERE ARE PROBLEMS WITH THE WAY DNS HANDLING HAS BEEN CHANGED IN THE KERNEL. I'VE PULLED IT FROM THE MARKET FOR 4.3 DEVICES." – user51893 Jan 28 '14 at 4:48
  • Your question says you need it for Android KitKat which is Android 4.4.* whereas Android 4.3 is Jellybean. – Karan Raj Baruah Jan 28 '14 at 4:52
  • I already opened the app's page on play store on my device, and it says right at the very top: "Your device isn't compatible with this version." So I'm sure the problem persists from version 4.3 to KitKat. – user51893 Jan 28 '14 at 5:01
  • Recommending apps isn't really a part of this site according to the FAQ. I answered the question whether Android can do it natively. I recommend to search the Play Store yourself. – Karan Raj Baruah Jan 28 '14 at 7:20
  • Hint: Visiting the apps page on AppBrain lists several alternatives (right-hand top 4). Note, however, that most solutions in that sector require root access. – Izzy Jan 28 '14 at 8:23

protected by Community Dec 25 '14 at 21:25

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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