Android VpnService ਵਿੱਚ ਸਪਲਿਟ ਟਨਲਿੰਗ: ਅਸਲ ਵਿੱਚ ਕੀ ਰੂਟ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ
VpnService ਸਿਰਫ਼ ਉਹ ਪੈਕਟ ਭੇਜਦਾ ਹੈ ਜੋ builder ਆਪਣੇ ਡਿਸਕ੍ਰਿਪਟਰ ਨੂੰ ਦਿੰਦਾ ਹੈ। ਸਪਲਿਟ ਟਨਲਿੰਗ ਨੂੰ ਦੋਸ਼ ਦੇਣ ਤੋਂ ਪਹਿਲਾਂ ਪ੍ਰੀਫਿਕਸ, ਪ੍ਰੌਕਸੀ ਪ੍ਰਮਾਣਿਕਤਾ, DNS ਅਤੇ ਐਪ ਸੂਚੀਆਂ ਦੀ ਜਾਂਚ ਕਰੋ।
VpnService ਐਪ ਵਿੱਚ ਸਪਲਿਟ ਟਨਲਿੰਗ ਕੁਝ ਖ਼ਾਸ ਥਾਵਾਂ 'ਤੇ ਟੁੱਟਦੀ ਹੈ, ਅਤੇ ਹਰ ਇੱਕ ਲਈ ਮੁਰੰਮਤ ਵੱਖਰੀ ਹੈ। ਕਲਾਇੰਟ ਸਿਰਫ਼ ਇੱਕ ਅਸਫਲ ਮੰਜ਼ਿਲ ਦਿਖਾਉਂਦਾ ਹੈ, ਇਸ ਲਈ ਪਹਿਲਾ ਕੰਮ ਇਹ ਪਤਾ ਲਗਾਉਣਾ ਹੈ ਕਿ ਤੁਸੀਂ ਕਿਹੜੀ ਹੱਦ 'ਤੇ ਟਕਰਾ ਰਹੇ ਹੋ: builder ਨੂੰ ਮਿਲੇ ਰੂਟ, ਜਿਸ ਪ੍ਰੌਕਸੀ ਦੀ ਪ੍ਰਮਾਣਿਕਤਾ ਨਹੀਂ ਕਰ ਸਕਦੇ, ਜਿਸ resolver ਦਾ ਸਿਰਫ਼ ਐਲਾਨ ਕੀਤਾ, ਜਾਂ ਉਹ ਐਪ ਸੂਚੀ ਜੋ ਪਲੇਟਫਾਰਮ ਹਰ ਵਰਤੋਂਕਾਰ ਲਈ ਲਾਗੂ ਕਰਦਾ ਹੈ। ਇਸੇ ਲਈ ਮੈਂ ਚਾਰ ਪੜਾਵਾਂ ਵਾਲੀ ਜਾਂਚ ਰੱਖਦਾ ਹਾਂ। ਇਹ ਹੇਠਾਂ ਦਿੱਤੇ ਕ੍ਰਮ ਵਿੱਚ ਚੱਲਦੀ ਹੈ ਅਤੇ ਪਹਿਲੀ ਅਸਫਲਤਾ 'ਤੇ ਰੁਕ ਜਾਂਦੀ ਹੈ।
ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ builder ਨੇ ਪਲੇਟਫਾਰਮ ਨੂੰ ਕੀ ਦਿੱਤਾ
VpnService.Builder ਐਲਾਨਾਂ ਦੀ ਸੂਚੀ ਹੈ। establish() ਵਰਚੁਅਲ ਇੰਟਰਫ਼ੇਸ ਲਈ ParcelFileDescriptor ਵਾਪਸ ਕਰਦਾ ਹੈ, ਅਤੇ ਪਲੇਟਫਾਰਮ ਉਸ ਡਿਸਕ੍ਰਿਪਟਰ ਵਿੱਚ ਸਿਰਫ਼ ਉਹ ਟ੍ਰੈਫਿਕ ਭੇਜਦਾ ਹੈ ਜੋ addAddress ਅਤੇ addRoute ਦੇ ਪ੍ਰੀਫਿਕਸ ਨਾਲ ਮੇਲ ਖਾਂਦਾ ਹੈ; addDnsServer ਕਲਾਇੰਟਾਂ ਨੂੰ ਦੱਸਦਾ ਹੈ ਕਿ ਕਿਹੜਾ resolver ਪੁੱਛਣਾ ਹੈ। ਤੁਹਾਡੇ ਜੋੜੇ ਕਿਸੇ ਵੀ ਪ੍ਰੀਫਿਕਸ ਤੋਂ ਬਾਹਰ ਦੀ ਮੰਜ਼ਿਲ ਇੰਟਰਫ਼ੇਸ ਭਾਵੇਂ ਕੁਝ ਵੀ ਵਾਅਦਾ ਕਰੇ, ਤੁਹਾਡੀ ਐਪ ਤੱਕ ਕਦੇ ਨਹੀਂ ਪਹੁੰਚਦੀ। ਇਹ ਇੱਕ ਤੱਥ ਕੋਡ ਬਦਲਣ ਤੋਂ ਪਹਿਲਾਂ ਹੀ ਟੁੱਟੀ ਸਪਲਿਟ ਟਨਲਿੰਗ ਦੀਆਂ ਜ਼ਿਆਦਾਤਰ ਸ਼ਿਕਾਇਤਾਂ ਦੀ ਵਿਆਖਿਆ ਕਰਦਾ ਹੈ।
ਤੁਹਾਡੇ builder ਨੇ ਬਣਾਈਆਂ ਪਤਾ, ਰੂਟ ਅਤੇ DNS ਸੂਚੀਆਂ ਲੌਗ ਕਰੋ, ਫਿਰ ਉਨ੍ਹਾਂ ਦੀ ਤੁਲਨਾ ਅਸਫਲ ਮੰਜ਼ਿਲਾਂ ਨਾਲ ਕਰੋ। ਪ੍ਰਬੰਧਨ ਹੋਸਟ ਲਈ ਗੁੰਮ /32 ਟੁੱਟੀ ਟਨਲ ਨਾਲੋਂ ਕਿਤੇ ਵੱਧ ਆਮ ਹੈ। ਸੂਚੀ ਸਹੀ ਹੋਵੇ ਤਾਂ ਅੱਗੇ ਵਧੋ; ਗਲਤ ਹੋਵੇ ਤਾਂ ਬਾਕੀ ਚੈੱਕਲਿਸਟ ਵਿਅਰਥ ਮਿਹਨਤ ਹੈ।
excludeRoute ਸਿਰਫ਼ API 33 ਤੋਂ ਹੈ
ਮੰਜ਼ਿਲ-ਆਧਾਰਿਤ ਬਾਹਰ ਕੱਢਣਾ ਉਹ ਬੇਨਤੀ ਹੈ ਜੋ ਸਭ ਤੋਂ ਵੱਧ ਸਹਾਇਤਾ ਥ੍ਰੈਡ ਬਣਦੀ ਹੈ। builder.excludeRoute(IpPrefix) API 33 ਵਿੱਚ ਆਇਆ; ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਇੱਕੋ ਸਮਰਥਿਤ ਤਰੀਕਾ ਹੈ ਬਾਹਰ ਕੱਢੇ ਪ੍ਰੀਫਿਕਸ ਤੋਂ ਇਲਾਵਾ ਸਭ ਲਈ ਰੂਟ ਜੋੜਨਾ, ਭਾਵ ਪੂਰਕ ਪ੍ਰੀਫਿਕਸ ਤੁਹਾਨੂੰ ਆਪ ਗਿਣਨੇ ਪੈਣਗੇ। ਦੋਵੇਂ ਕਾਲ ਸ਼ੀਸ਼ੇ ਦੀਆਂ ਤਸਵੀਰਾਂ ਨਹੀਂ: ਇੱਕ ਇੰਟਰਫ਼ੇਸ ਦੇ ਰੂਟ ਸੈੱਟ ਵਿੱਚੋਂ ਘਟਾਉਂਦੀ ਹੈ, ਦੂਜੀ ਸੈੱਟ ਨੂੰ ਜ਼ੀਰੋ ਤੋਂ ਬਣਾਉਂਦੀ ਹੈ, ਅਤੇ ਪੁਰਾਣਾ ਯੰਤਰ ਅਣਜਾਣ ਕਾਲ ਸੁੱਟ ਦਿੰਦਾ ਹੈ ਜਾਂ ਚੁੱਪਚਾਪ ਅਣਡਿੱਠ ਕਰਦਾ ਹੈ। Build.VERSION.SDK_INT ਅਨੁਸਾਰ ਸ਼ਾਖਾ ਬਣਾਓ ਅਤੇ ਦੋਵੇਂ ਰਾਹ ਅਸਲ ਹਾਰਡਵੇਅਰ 'ਤੇ ਪਰਖੋ।
ਪੂਰਕ ਗਿਣਦਿਆਂ ਪ੍ਰੀਫਿਕਸ ਸੰਰੇਖਣ ਵੱਲ ਧਿਆਨ ਦਿਓ। /16 ਰੂਟ ਦੇ ਅੰਦਰ /24 ਬਾਹਰ ਕੱਢਣ ਲਈ ਬਾਕੀ ਹਿੱਸੇ ਦਾ ਸੱਚਮੁੱਚ ਵਰਣਨ ਕਰਨ ਵਾਲੇ ਢੱਕਣ ਪ੍ਰੀਫਿਕਸ ਚਾਹੀਦੇ ਹਨ, ਇੱਕ ਵਿਗੜਿਆ /8 ਨਹੀਂ। ਅੰਤਿਮ ਸੂਚੀ ਲੌਗ ਕਰੋ ਅਤੇ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਬਾਹਰ ਕੱਢਿਆ ਹੋਸਟ ਅਜੇ ਵੀ ਟਨਲ ਤੋਂ ਬਾਹਰਲੇ ਰਾਹ ਰਾਹੀਂ ਹੱਲ ਹੁੰਦਾ ਹੈ।
ਪ੍ਰੌਕਸੀ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੱਸੇ ਨਹੀਂ ਜਾ ਸਕਦੇ
setHttpProxy(ProxyInfo) ਇੰਟਰਫ਼ੇਸ ਨੂੰ HTTP ਜਾਂ SOCKS ਪ੍ਰੌਕਸੀ ਵੱਲ ਮੋੜਦਾ ਹੈ, ਅਤੇ PAC URL ਹਰ ਮੰਜ਼ਿਲ ਲਈ ਦੋਵਾਂ ਵਿੱਚੋਂ ਚੁਣ ਸਕਦਾ ਹੈ। ProxyInfo ਜਾਂ PAC ਫਾਰਮੈਟ ਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਨਾਂ ਅਤੇ ਪਾਸਵਰਡ ਨਹੀਂ ਰੱਖਦਾ, ਇਸ ਲਈ ਪ੍ਰਮਾਣਿਕਤਾ ਮੰਗਣ ਵਾਲੀ ਪ੍ਰੌਕਸੀ ਪਲੇਟਫਾਰਮ API ਤੋਂ ਬਾਹਰ ਰਹਿੰਦੀ ਹੈ। ਜਿਨ੍ਹਾਂ ਐਪਾਂ ਨੂੰ ਇਹ ਚਾਹੀਦੀ ਹੈ ਉਹ ਆਮ ਤੌਰ 'ਤੇ userspace ਸਟੈਕ, tun2socks ਜਾਂ ਇਸੇ ਤਰ੍ਹਾਂ ਦਾ ਇੰਜਣ ਸ਼ਾਮਲ ਕਰਦੀਆਂ ਹਨ ਅਤੇ 407 ਚੁਣੌਤੀ ਦਾ ਜਵਾਬ ਖੁਦ ਦਿੰਦੀਆਂ ਹਨ।
ਇਸ ਚੋਣ ਦੇ ਨਤੀਜੇ ਹਨ। userspace ਸਟੈਕ ਸਿਰਫ਼ ਉਹ ਟ੍ਰੈਫਿਕ ਵੇਖਦਾ ਹੈ ਜੋ ਤੁਸੀਂ ਉਸ ਵੱਲ ਰੂਟ ਕਰਦੇ ਹੋ, ਇਸ ਲਈ ਇਹ ਉਸੇ ਡਿਸਕ੍ਰਿਪਟਰ ਹੱਦ ਅੰਦਰ ਰਹਿਣਾ ਚਾਹੀਦਾ ਹੈ, ਅਤੇ ਆਪਣੇ uplink ਸਾਕਟ ਲਈ ਉਹੀ protect() ਲੋੜ ਵਿਰਾਸਤ ਵਿੱਚ ਮਿਲਦੀ ਹੈ। protect() ਛੱਡ ਦਿਓ ਤਾਂ ਟਨਲ ਆਪਣਾ ਹੀ ਟ੍ਰਾਂਸਪੋਰਟ ਫੜ ਲੈਂਦੀ ਹੈ, ਜੋ ਪਹਿਲੇ ਪੈਕਟ ਤੋਂ ਬਾਅਦ ਅਟਕਣ ਵਾਲੇ ਹੈਂਡਸ਼ੇਕ ਵਜੋਂ ਦਿਖਦੀ ਹੈ। ਪ੍ਰਮਾਣ-ਪੱਤਰ ਮੰਗਣ ਵਾਲੀ ਪ੍ਰੌਕਸੀ ਵਿਰੁੱਧ ਪਰਖੋ, ਕਿਉਂਕਿ ਖੁੱਲ੍ਹੀ ਪ੍ਰੌਕਸੀ ਪਲੇਟਫਾਰਮ ਦੇ ਰਾਹ ਲੰਘ ਜਾਂਦੀ ਹੈ ਅਤੇ ਕੁਝ ਸਾਬਤ ਨਹੀਂ ਕਰਦੀ।
ਹਰ ਐਪ ਦੀ ਸੂਚੀ ਅਤੇ DNS ਵੀ ਐਲਾਨ ਹਨ
Builder ਵਿੱਚ addAllowedApplication ਅਤੇ addDisallowedApplication ਦੋਵੇਂ ਹਨ, ਅਤੇ ਇਹ ਇੱਕ ਦੂਜੇ ਦੇ ਵਿਰੋਧੀ ਹਨ: ਦੋਵੇਂ ਕਾਲ ਕਰਨ 'ਤੇ ਅਪਵਾਦ ਆਉਂਦਾ ਹੈ। ਕਿਸੇ ਵੀ ਹਾਲਤ ਵਿੱਚ ਸੂਚੀ ਇੰਟਰਫ਼ੇਸ ਸੈੱਟਅੱਪ ਵੇਲੇ ਹਰ ਵਰਤੋਂਕਾਰ ਲਈ ਲਾਗੂ ਹੁੰਦੀ ਹੈ, ਇਸ ਲਈ ਕੰਮ ਪ੍ਰੋਫ਼ਾਈਲ ਦੀ ਐਪ ਤੁਹਾਡੀ ਟਨਲ ਦੀ ਬਜਾਏ ਕੰਮ ਪ੍ਰੋਫ਼ਾਈਲ ਦੀ ਟਨਲ ਨਾਲ ਚੱਲਦੀ ਹੈ। ਕੋਈ API ਤੁਹਾਨੂੰ ਦੂਜੀ ਐਪ ਦੇ ਫ਼ੈਸਲੇ 'ਤੇ ਕੰਟਰੋਲ ਨਹੀਂ ਦਿੰਦਾ: ਤੁਸੀਂ ਬਾਹਰੋਂ ਪੈਕਟ ਨੂੰ ਆਪਣੀ ਟਨਲ ਵਿੱਚ ਨਹੀਂ ਧੱਕ ਸਕਦੇ, ਅਤੇ ਪਹਿਲਾਂ ਹੀ ਸਰਗਰਮ VPN ਨੂੰ ਬੰਦ ਜਾਂ ਮੁੜ-ਸੰਰਚਿਤ ਨਹੀਂ ਕਰ ਸਕਦੇ।
DNS ਵੀ ਇਹੀ ਨਮੂਨਾ ਅਪਣਾਉਂਦਾ ਹੈ। addDnsServer resolver ਦਾ ਪਤਾ ਐਲਾਨਦਾ ਹੈ; ਇਹ ਤੁਹਾਡੀ ਐਪ ਨੂੰ ਸਵਾਲਾਂ ਦਾ ਜਵਾਬ ਦੇਣ ਨਹੀਂ ਦਿੰਦਾ। ਜੇ ਤੁਸੀਂ ਖੁਦ ਨਾਂ ਹੱਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ resolver ਚਲਾਓ ਅਤੇ ਉਸ ਦਾ ਪਤਾ ਟਨਲ ਵਿੱਚ ਰੂਟ ਕਰੋ। ਸਥਿਰ ਹੋਸਟਨਾਂ 'ਤੇ DoT ਜਾਂ DoH ਵਰਤਣ ਵਾਲੀਆਂ ਐਪਾਂ ਤੁਹਾਡੇ ਐਲਾਨੇ ਪਤੇ ਨੂੰ ਟਾਲ ਸਕਦੀਆਂ ਹਨ, ਇਸ ਲਈ ਸਵਾਲ ਦਾ ਰਾਹ ਵੀ ਰੋਕਣ ਤੱਕ ਨਾਂ-ਹੱਲ ਨੂੰ ਸਭ ਤੋਂ ਵਧੀਆ ਕੋਸ਼ਿਸ਼ ਮੰਨੋ।
Manifest, always-on ਅਤੇ ਚਾਰ ਪੜਾਅ ਦੀ ਪਰਖ
ਯੋਗਤਾ manifest ਵਿੱਚ ਐਲਾਨੀ ਜਾਂਦੀ ਹੈ: BIND_VPN_SERVICE, android.net.VpnService intent ਫਿਲਟਰ, ਅਤੇ foreground ਸੇਵਾ ਜੇ ਟਨਲ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਟਿਕਣਾ ਹੈ। Always-on VPN ਵਾਧੂ ਤੌਰ 'ਤੇ ਸਾਫ਼ onRevoke ਮੰਗਦੀ ਹੈ, ਕਿਉਂਕਿ ਵਰਤੋਂਕਾਰ ਸੈਟਿੰਗਾਂ ਬਦਲਦਾ ਹੈ ਜਾਂ ਕੋਈ ਹੋਰ ਐਪ ਕੰਟਰੋਲ ਲੈ ਲੈਂਦੀ ਹੈ ਤਾਂ ਸਿਸਟਮ ਇਸਨੂੰ ਕਾਲ ਕਰਦਾ ਹੈ।
ਜਾਂਚਾਂ ਕ੍ਰਮ ਵਿੱਚ ਚਲਾਓ ਅਤੇ ਪਹਿਲੀ ਅਸਫਲਤਾ 'ਤੇ ਰੁਕੋ। ਪਹਿਲਾਂ, builder ਨੂੰ ਦਿੱਤੀਆਂ ਪਤਾ, ਰੂਟ ਅਤੇ DNS ਸੂਚੀਆਂ ਕੱਢੋ। ਦੂਜਾ, ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ establish() ਨੇ ਡਿਸਕ੍ਰਿਪਟਰ ਵਾਪਸ ਕੀਤਾ ਅਤੇ ਟ੍ਰਾਂਸਪੋਰਟ ਸਾਕਟ ਸੁਰੱਖਿਅਤ ਹੈ। ਤੀਜਾ, ਸ਼ਾਮਲ ਪ੍ਰੀਫਿਕਸ ਦੇ ਅੰਦਰ ਇੱਕ ਅਤੇ ਬਾਹਰ ਕੱਢੇ ਪ੍ਰੀਫਿਕਸ ਦੇ ਅੰਦਰ ਇੱਕ ਮੰਜ਼ਿਲ ਮੰਗੋ। ਚੌਥਾ, ਸਿਰਫ਼ ਤੁਹਾਡਾ resolver ਹੀ ਹੱਲ ਕਰ ਸਕਣ ਵਾਲਾ ਹੋਸਟਨਾਂ ਪੁੱਛ ਕੇ ਵੇਖੋ ਕਿ ਅਸਲ ਵਿੱਚ ਕਿਹੜੇ resolver ਨੇ ਜਵਾਬ ਦਿੱਤਾ।
ਪੂਰਾ ਹੋਇਆ ਹੈਂਡਸ਼ੇਕ ਬਾਅਦ ਦੇ ਕਿਸੇ ਵੀ ਪੜਾਅ ਨੂੰ ਸਾਬਤ ਨਹੀਂ ਕਰਦਾ। ਹਰ ਜਾਂਚ ਇੱਕ ਪਰਤ ਨੂੰ ਵੱਖ ਕਰਦੀ ਹੈ, ਇਸ ਲਈ ਦੂਜੇ ਪੜਾਅ ਦੀ ਸਫਲਤਾ ਚੌਥੇ ਬਾਰੇ ਕੁਝ ਨਹੀਂ ਕਹਿੰਦੀ।
VpnService.Builder ਸੰਦਰਭ builder ਦੀ ਪੂਰੀ ਸਤ੍ਹਾ ਦੀ ਸੂਚੀ ਦਿੰਦਾ ਹੈ। ਇਸ ਤੋਂ ਬਾਹਰ ਜੋ ਵੀ ਲੋੜੀਂਦਾ ਹੈ ਉਹ ਦੂਜਾ API, ਦੂਜੀ ਐਪ ਜਾਂ ਤੁਹਾਡਾ ਆਪਣਾ userspace ਸਟੈਕ ਹੈ, ਅਤੇ ਉਹ ਸਪਲਿਟ-ਟਨਲ ਬੱਗ ਨਹੀਂ ਸਗੋਂ ਡਿਜ਼ਾਈਨ ਫ਼ੈਸਲਾ ਹੈ।