为什么无法将 Google DNS 地址分配给 Android VPN 服务(仅本地 DNS 服务器)?

问题描述 投票:0回答:1

-在此方法中,我尝试将 google dns 服务器添加到 vpn 接口,但它根本不起作用。它 仅适用于本地 dns,这是 gsm 的默认 dns 服务器。
@覆盖 公共int onStartCommand(Intent意图,int标志,int startId){ localAddress = CommonMethods.ipStringToInt(ipAddress);

    packet = new byte[20000];
    ipHeader = new IPHeader(packet, 0);
    tcpHeader = new TCPHeader(packet, 20);
    udpHeader = new UDPHeader(packet, 20);
    dnsBuffer = ((ByteBuffer) ByteBuffer.wrap(packet).position(28)).slice();

    proxy = new Proxy(this, 0);
    proxy.start();
    dnsProxy = new DnsProxy(this);
    dnsProxy.start();

    vpnThread = new Thread(new Runnable(){
        @Override
        public void run(){
            mInterface = builder.setSession("VPNtoSocket")
                    .addAddress(ipAddress,32)
                    .addRoute("0.0.0.0", 0)
                    .addDnsServer("8.8.8.8");
                    //.addRoute("194.163.43.216", 32)
                    .establish();

            FileInputStream vpnin = new FileInputStream(mInterface.getFileDescriptor());
            vpnout = new FileOutputStream(mInterface.getFileDescriptor());

            onStatusChanged(true);

            try{
                int size = 0;
                while(size != -1 && !vpnThread.isInterrupted()){
                    while((size = vpnin.read(packet)) > 0 && !vpnThread.isInterrupted()){
                        if(dnsProxy.isInterrupted() || proxy.isInterrupted()){ //KILL SWITCH
                            vpnin.close();
                            throw new Exception("Server stopped.");
                        }
                        onIPPacketReceived(ipHeader, size);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                try{
                    vpnin.close();
                    vpnout.close();
                    if(mInterface != null){
                        mInterface.close();
                        mInterface = null;
                    }

                    kill();
                }catch(Exception e){
                }
            }
        }

    }, "VPNtoSocket");
    vpnThread.start();

    return super.onStartCommand(intent, flags, startId);//START_STICKY;
}
java android vpn google-cloud-dns
1个回答
0
投票

我知道答案太晚了,但我最近遇到了这个问题。 将此答案留给稍后看到此内容的人。

因此,由于某种原因,Android 并不总是根据“活动”网络的 DNS 服务器来解析 DNS。 这在我身上发生过两种情况:

  • Wi-fi 网络但没有互联网 - Android 只是忽略此网络并尝试使用默认 DNS 解析器而不是使用 Wi-fi 提供的 DNS 服务器来解析 DNS。这是一个问题,因为我的路由器中有一个端点,其名称只能使用路由器的 DNS 进行解析。
  • VPN - Android 仍然使用默认的 DNS 解析器,尽管所有流量都应该由 VPN 捕获,但它似乎是在 VPN 之外进行的。就我而言,我的 VPN 是本地 VPN,设备没有任何类型的互联网连接(Wi-Fi 或手机),而是将流量转发到其他具有互联网的设备。

最奇怪的事情是,在这个 VPN 场景中,我在不同的 Android 设备和版本上的行为不一致。有些使用正确的 VPN DNS 服务器,有些使用默认的 Android DNS 解析器..

长话短说:对我来说解决此问题并确保使用来自 VPN(或其他网络)的 DNS 解析器而不是默认解析器的唯一方法是将进程绑定到网络,在这种情况下, VPN 网络。

具体操作方法如下: 启动 VPN 之前:

val builder = NetworkRequest.Builder()
        builder.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
val request = builder.build()
connectivityManager.requestNetwork(request, object : NetworkCallback() {
        override fun onAvailable(network: Network) {
            super.onAvailable(network)
            Log.i(TAG,"Binding to VPN Network!")
            val bindResult = connectivityManager.bindProcessToNetwork(network)
            Log.i(TAG,"Bind to VPN result = $bindResult")
        }
    })

如果下面的代码在启动VPN时没有触发回调,你也可以从activeNetwork中获取网络对象:

val activeNetwork = connectivityManager.activeNetwork
    

if (activeNetwork != null) {
        val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
        val isVpn = networkCapabilities?.hasTransport(
            NetworkCapabilities.TRANSPORT_VPN
        ) ?: false
        if (isVpn) {
            Log.i(TAG,"Binding to VPN Network!")
            val bindResult = connectivityManager.bindProcessToNetwork(activeNetwork)
            Log.i(TAG,"Bind to VPN result = $bindResult")
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.