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 ಸ್ಟಾಕ್, ಮತ್ತು ಅದು ಸ್ಪ್ಲಿಟ್-ಟನೆಲ್ ದೋಷವಲ್ಲ, ವಿನ್ಯಾಸದ ನಿರ್ಧಾರ.