schwabe / ics-openvpn

OpenVPN for Android
3.37k stars 1.2k forks source link

DNS issue with CM12.1/Lollipop #377

Closed sevenrock closed 9 years ago

sevenrock commented 9 years ago

Hi,

I am trying to solve a weird problem with the TomTom GPS-Navigation Traffic app. On my new phone with CM12.1 installed it does not provide live traffic data when connected through the cellular network and a VPN tunnel. The same tunnel works with my private wifi setup, also connecting with TomTom through the cellular network and without a VPN tunnel works.

This is a regression compared to CM 11.0 where connecting by VPN@cellular worked, to summarize:

               CM11.0    CM12.1
wifi+vpn       works     works
cellular       works     works
cellular+vpn   works     broken

I tracked down the regression to DNS handling in Lollipop and could fix the problem using setprop net.dns1, but first the comparison done with ngrep:

Kitkat

U 192.168.4.252:38656 -> 192.168.4.253:53
  A ...........t.tt1.nl.....
#
U 192.168.4.253:53 -> 192.168.4.252:38656
  A ...........t.tt1.nl..............J..UZLf
####
T 192.168.4.252:40400 -> 85.90.76.102:80 [AP]
  GET /services/directory.php HTTP/1.1..Host: t.tt1.nl..Accept-Encoding: gzip, deflate....
##
T 85.90.76.102:80 -> 192.168.4.252:40400 [AP]
  HTTP/1.1 200 OK..Date: Mon, 27 Jul 2015 18:15:35 GMT..Content-Type: text/plain;charset=us-ascii..Content-Length: 19....http://h2.tt1.nl/h1

The phone (192.168.4.252) is connected by VPN tunnel to the VPN server daemon (192.168.4.253), issues a DNS query for t.tt1.nl, gets an answer from my DNS server and connects to the TomTom live traffic data service, everything is ok.

Lollipop

U 192.168.4.252:34575 -> 10.74.210.210:53
  .Z...........t.tt1.nl.....
#
U 192.168.4.252:44113 -> 10.74.210.211:53
  .Z...........t.tt1.nl.....
#
U 192.168.4.252:34575 -> 10.74.210.210:53
  .Z...........t.tt1.nl.....
#
U 192.168.4.252:44113 -> 10.74.210.211:53
  .Z...........t.tt1.nl.....

The phone (192.168.4.252) is connected by VPN tunnel to my local VPN server, I can use internal services like my mail server and so on, all traffic is routed through the VPN tunnel, including DNS queries done by other apps like Firefox, Google Play, nslookup... The only exception is the TomTom app which still queries the DNS server of the cellular provider 10.74.210.210/1 (Congstar in my case). Here are the getprop dns settings after connecting to the cellular network:

$ adb shell getprop | grep dns
[net.change]: [net.dns2]
[net.dns1]: [10.74.210.210]
[net.dns2]: [10.74.210.211]
[net.rmnet0.dns1]: [10.74.210.210]
[net.rmnet0.dns2]: [10.74.210.211]

and now after establishing the VPN tunnel:

$ adb shell getprop | grep dns
[net.change]: [net.dns2]
[net.dns1]: [10.74.210.210]
[net.dns2]: [10.74.210.211]
[net.rmnet0.dns1]: [10.74.210.210]
[net.rmnet0.dns2]: [10.74.210.211]

As you can see, no changes occured. Now the ngrep log of "adb shell nslookup www.github.com"

U 192.168.4.252:45362 -> 192.168.4.253:53
  M............www.github.com.....
#
U 192.168.4.253:53 -> 192.168.4.252:45362
  M............www.github.com............................<.5.ns1.p16.dynect.net..hostmaster..U.b........X..:....<

As you can see my local DNS server is used. Now I start TomTom:

U 192.168.4.252:33871 -> 10.74.210.211:53
  .a...........t.tt1.nl.....
U 192.168.4.252:33871 -> 10.74.210.211:53
  .a...........t.tt1.nl.....
#######
U 192.168.4.252:42478 -> 10.74.210.210:53
  .a...........t.tt1.nl.....

and it tries to resolve its server using the wrong DNS server... No changes to the phones DNS servers:

$ adb shell getprop | grep dns
[net.change]: [net.dns2]
[net.dns1]: [10.74.210.210]
[net.dns2]: [10.74.210.211]
[net.rmnet0.dns1]: [10.74.210.210]
[net.rmnet0.dns2]: [10.74.210.211]

Now the fix:

$ adb shell
$ su
# setprop net.dns1 192.168.4.253
# getprop | grep dns                                          
[net.change]: [net.dns1]
[net.dns1]: [192.168.4.253]
[net.dns2]: [10.74.210.211]
[net.rmnet0.dns1]: [10.74.210.210]
[net.rmnet0.dns2]: [10.74.210.211]

and TomTom connects to its live traffic data service:

U 192.168.4.252:45914 -> 192.168.4.253:53
  mR...........t.tt1.nl.....
#
U 192.168.4.253:53 -> 192.168.4.252:45914
  mR...........t.tt1.nl..............U..UZLf
####
T 192.168.4.252:32787 -> 85.90.76.102:80 [AP]
  GET /services/directory.php HTTP/1.1..Host: t.tt1.nl..Accept-Encoding: gzip, deflate....
##
T 85.90.76.102:80 -> 192.168.4.252:32787 [AP]
  HTTP/1.1 200 OK..Date: Mon, 27 Jul 2015 20:23:22 GMT..Content-Type: text/plain;charset=us-ascii..Content-Length: 19....http://h2.tt1.nl/h8

Here is my openvpn client config, which works unchanged using CM 11.0:

# Enables connection to GUI
management /data/data/de.blinkt.openvpn/cache/mgmtsocket unix
management-client
management-query-passwords
management-hold

setenv IV_GUI_VER "de.blinkt.openvpn 0.6.30"
machine-readable-output
ifconfig-nowarn
verb 4
connect-retry-max 5
connect-retry 5
resolv-retry 60
dev tun
remote my.vpn.server 1234 udp
comp-lzo
<secret>
__some_key__
</secret>
dhcp-option DNS 192.168.4.253
dhcp-option DOMAIN lan.local
float
persist-tun
# persist-tun also enables pre resolving to avoid DNS resolve problem
preresolve
# Custom configuration options
# You are on your on own here :)
mssfix
fragment 1300
route-gateway 192.168.4.253
redirect-gateway
ifconfig 192.168.4.252 192.168.4.253
route 192.168.1.0 255.255.255.0

Do I need to make changes to my config are is it a bug somewhere?

schwabe commented 9 years ago

That is probably a bug in TomTom. The dns properties are deprecated and should never have been used by apps. Also if other apps are working fine the VPN app has set the DNS properties right. You just don't see the DNS in getprop

sevenrock commented 9 years ago

Could you please point me to some docs saying that net.dnsX are deprecated so I can quote it when opening a ticket at TomTom support?

Btw: I found this commit in CM12.1 where net.dnsX was re-added in 2014: https://github.com/CyanogenMod/android_frameworks_base/commit/d5648dcf6a477a350c281c769bae07b8cbe982a3 ported from Google: https://android.googlesource.com/platform/frameworks/base/+/d5648dc%5E!/

There are also two more android issues related to my problem: http://code.google.com/p/android/issues/detail?id=169761 http://code.google.com/p/android/issues/detail?id=177536

schwabe commented 9 years ago

Sorry. I have no link at hand. I remember seeing somewhere in the sources of VpnService/netd or the google android bugtracker but with quick googling I could not find it :/

sevenrock commented 9 years ago

I circumvented the problem by adding a DNAT rule to the prerouting chain on my vpn server for the two offending IPs and TomTom works like a charm now:

DNAT tcp -- android.lan 10.74.210.210 tcp dpt:dns /* 192.168.4.252 10.74.210.210:53 DNAT:192.168.4.253:53 / to:192.168.4.253:53 DNAT udp -- android.lan 10.74.210.210 udp dpt:dns / 192.168.4.252 10.74.210.210:53 DNAT:192.168.4.253:53 / to:192.168.4.253:53 DNAT tcp -- android.lan 10.74.210.211 tcp dpt:dns / 192.168.4.252 10.74.210.211:53 DNAT:192.168.4.253:53 / to:192.168.4.253:53 DNAT udp -- android.lan 10.74.210.211 udp dpt:dns / 192.168.4.252 10.74.210.211:53 DNAT:192.168.4.253:53 */ to:192.168.4.253:53

schwabe commented 9 years ago

This is a bug in either TomTom (more likely) or Android itself.