Android VPN: VpnService ಡಿಸ್ಕ್ರಿಪ್ಟರ್ ಮತ್ತು root tun ಸಾಧನ
Android ಅಪ್ಲಿಕೇಶನ್ಗಳು tun0 ಅನ್ನು ತಾವೇ ರಚಿಸಲಾರವು: establish() ಏನನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ, Binder ಎಲ್ಲಿ ನಿಲ್ಲುತ್ತದೆ ಮತ್ತು JNI ಎಲ್ಲಿ ಆರಂಭವಾಗುತ್ತದೆ, ಮತ್ತು root ರಚಿಸಿದ ಸಾಧನ ಯಾವಾಗ ಗೆಲ್ಲುತ್ತದೆ.
ಎರಡು ಮಾರ್ಗಗಳು Android ಅಪ್ಲಿಕೇಶನ್ನ ಮುಂದೆ IP ಇಂಟರ್ಫೇಸ್ ಇಡಬಹುದು, ಮತ್ತು ಎರಡೂ ಬಹಳ ಬೇರೆ ಮಾಲೀಕರಿರುವ ಒಂದೇ ರೀತಿಯ ಫೈಲ್ ಡಿಸ್ಕ್ರಿಪ್ಟರ್ನಲ್ಲಿ ಕೊನೆಗೊಳ್ಳುತ್ತವೆ. ಒಂದು VpnService ಮತ್ತು ಅದರ builder ಮೂಲಕ ಹೋಗುತ್ತದೆ, ಇನ್ನೊಂದು root shell ಮತ್ತು /dev/net/tun ಮೂಲಕ. ಆ ಡಿಸ್ಕ್ರಿಪ್ಟರ್ನಲ್ಲಿನ ಪ್ರತಿ ಓದು ಹೊರಹೋಗುವ ಪ್ಯಾಕೆಟ್ ಮತ್ತು ಪ್ರತಿ ಬರಹ ಒಳಬರುವ ಪ್ಯಾಕೆಟ್. ಮಾರ್ಗಗಳನ್ನು ಬೇರ್ಪಡಿಸುವುದು ನೀತಿ ಯಾರ ಬಳಿ ಇದೆ, OS ನವೀಕರಣವನ್ನು ಯಾರು ಬದುಕುತ್ತಾರೆ, ಮತ್ತು ರೂಟಿಂಗ್ ಕೋಷ್ಟಕದ ಎಷ್ಟನ್ನು ನೀವು ಮುಟ್ಟಬಹುದು ಎಂಬುದು.
ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗವನ್ನು ತೆಗೆದುಕೊಳ್ಳಿ, ಅದು ಮಾಡಲು ನಿರಾಕರಿಸುವ ನಿರ್ದಿಷ್ಟ ವಿಷಯವನ್ನು ನೀವು ಹೆಸರಿಸಲು ಸಾಧ್ಯವಾಗದಿದ್ದರೆ. ಆ ನಿರಾಕರಣೆ ಸಾಮಾನ್ಯವಾಗಿ TAP, ನಿಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್ ಸೆಟ್ನ ಹೊರಗಿನ ಕ್ಯಾಪ್ಚರ್, ಅಥವಾ ಫ್ರೇಮ್ವರ್ಕ್ ಎಂದಿಗೂ ಬಹಿರಂಗಪಡಿಸದ ರೂಟಿಂಗ್ ನಿಯಮ.
ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗದಲ್ಲಿ ನೀವು ಆದೇಶಗಳ ಬದಲು ಉದ್ದೇಶವನ್ನು ಘೋಷಿಸುತ್ತೀರಿ. ಕನಿಷ್ಠ ಒಂದು ವಿಳಾಸ, ಬಯಸಿದ ರೂಟ್ಗಳು, DNS ಸರ್ವರ್ಗಳು ಮತ್ತು ಐಚ್ಛಿಕ ಅಪ್ಲಿಕೇಶನ್ ಪಟ್ಟಿಯನ್ನು ನೀಡುತ್ತೀರಿ, ನಂತರ Android ನ ಸಿಸ್ಟಮ್ ಸೇವೆ ತನ್ನದೇ ಗುರುತಿನಲ್ಲಿ ಸವಲತ್ತು ಪಡೆದ ಸೆಟಪ್ ಮಾಡುತ್ತದೆ. ಇಂಟರ್ಫೇಸ್ನ ಹೆಸರನ್ನು ನೀವು ಮೊದಲೇ ಎಂದಿಗೂ ತಿಳಿಯುವುದಿಲ್ಲ, ಮತ್ತು ಅದನ್ನು ರಚಿಸುವ ioctl ಅನ್ನು ಎಂದಿಗೂ ಹೊರಡಿಸುವುದಿಲ್ಲ, ಮತ್ತು ಅದೇ ಮುಖ್ಯ ಅಂಶ.
IP ಇಂಟರ್ಫೇಸ್ ಪಡೆಯುವ ಎರಡು ದಾರಿಗಳು
root ಮಾರ್ಗ ಹಳೆಯ ವಿಧಾನ. ನೀವು /dev/net/tun ತೆರೆಯುತ್ತೀರಿ, IFF_TUN ಜೊತೆ TUNSETIFF ಕರೆಯುತ್ತೀರಿ, ip link ನಿಂದ ಇಂಟರ್ಫೇಸ್ ಎತ್ತುತ್ತೀರಿ, ಮತ್ತು ವಿಳಾಸ ಹಾಗೂ ರೂಟ್ಗಳನ್ನು ಕೈಯಿಂದ ಸೇರಿಸುತ್ತೀರಿ. ಪ್ರತಿ ಹೆಜ್ಜೆಯನ್ನೂ ನೀವೇ ಸರಿಯಾಗಿ ಮಾಡಬೇಕು, ಫ್ರೇಮ್ವರ್ಕ್ ಸದ್ದಿಲ್ಲದೆ ನಿಭಾಯಿಸುತ್ತಿದ್ದವು ಸಹ. ಒಂದು ರೂಟ್ ಕಾಣೆಯಾದರೆ ಬಳಕೆದಾರರಿಗೆ ಸತ್ತ ಸರ್ವರ್ನಂತೆಯೇ ವರದಿ ಸಿಗುತ್ತದೆ.
ಡೀಬಗ್ ಮಾಡುವುದು ಸೆಟಪ್ನಷ್ಟೇ ಭಿನ್ನ. root ಮಾರ್ಗದಲ್ಲಿ ಇಂಟರ್ಫೇಸ್ ಇದೆ ಅಥವಾ ನಿಮ್ಮ ioctl ನೇರವಾಗಿ ಓದಬಹುದಾದ ದೋಷವನ್ನು ಹಿಂತಿರುಗಿಸಿದೆ. ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗದಲ್ಲಿ ಇಂಟರ್ಫೇಸ್ establish() ಯಶಸ್ವಿಯಾದ ನಂತರವೇ ಇರುತ್ತದೆ, ಆದ್ದರಿಂದ ವೈಫಲ್ಯ ಡಿವೈಸ್ ನೋಡ್ ಬದಲು ಎಕ್ಸೆಪ್ಶನ್ ಅಥವಾ null ಡಿಸ್ಕ್ರಿಪ್ಟರ್ ಆಗಿ ಬರುತ್ತದೆ, ಅದನ್ನು ನೀವು ಕೆದಕಬಹುದು.
establish() ನಿಜವಾಗಿ ಏನನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ
Builder.establish() ಗೆ ಮೂರು ಫಲಿತಾಂಶಗಳಿವೆ ಮತ್ತು ಅವು ಮೂರು ಬೇರೆ ಪ್ರತಿಕ್ರಿಯೆಗಳನ್ನು ಬಯಸುತ್ತವೆ. ಡಿಸ್ಕ್ರಿಪ್ಟರ್ ಎಂದರೆ ಇಂಟರ್ಫೇಸ್ ಸಂರಚಿಸಲಾಗಿದೆ ಮತ್ತು ಬಳಸಲು ನಿಮ್ಮದು, null ಎಂದರೆ ವಿನಂತಿ ದಾಟಲಿಲ್ಲ, ಮತ್ತು ಎಸೆದ ಎಕ್ಸೆಪ್ಶನ್ ಎಂದರೆ ಸಿಸ್ಟಮ್ ಸೇವೆ ಅದನ್ನು ತಿರಸ್ಕರಿಸಿತು. null ಮತ್ತು ಯಶಸ್ಸನ್ನು ಒಂದೇ boolean ಗೆ ಸೇರಿಸುವುದು ಪ್ಯಾಕೆಟ್ ಎಂದಿಗೂ ಸಾಗಿಸದ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಸುರಂಗವನ್ನು ಅಪ್ಲಿಕೇಶನ್ ವರದಿ ಮಾಡುವ ಅತ್ಯಂತ ಸಾಮಾನ್ಯ ವಿಧಾನ. Builder ಉಲ್ಲೇಖ ವಿಳಾಸದ ಅಗತ್ಯವನ್ನು ತಿಳಿಸುತ್ತದೆ, ಮತ್ತು ಸರ್ವರ್ಗೆ ದೂರು ಹೇಳುವ ಮೊದಲು ಅದನ್ನು ಓದುವುದು ಯೋಗ್ಯ.
ದಿಕ್ಕುಗಳನ್ನು ಡಿಸ್ಕ್ರಿಪ್ಟರ್ ನಿರ್ಧರಿಸುತ್ತದೆ, ನಿಮ್ಮ ಪ್ರೋಟೋಕಾಲ್ ಅಲ್ಲ. ಓದುಗಳು ಈಗಾಗಲೇ VPN ಗೆ ಆಯ್ಕೆಯಾದ ಹೊರಹೋಗುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ನಿಮಗೆ ನೀಡುತ್ತವೆ, ಮತ್ತು ಬರಹಗಳು ಒಳಬರುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಮತ್ತೆ ಇಂಟರ್ಫೇಸ್ಗೆ ಚುಚ್ಚುತ್ತವೆ. ಆ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್, ದೃಢೀಕರಿಸಿ ಮತ್ತು ಫ್ರೇಮ್ ಮಾಡುವುದು ನಿಮ್ಮದೇ ಸಾರಿಗೆಯ ಕೆಲಸ, ಏಕೆಂದರೆ ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಪ್ಯಾಕೆಟ್ ಗಡಿಯಲ್ಲಿ ನಿಲ್ಲುತ್ತದೆ.
Binder ಒಂದು ಹೆಜ್ಜೆ, JNI ಇನ್ನೊಂದು ಅಕ್ಷ
builder ವಿನಂತಿ Binder ಮೂಲಕ ಸಿಸ್ಟಮ್ ಪ್ರವೇಶಿಸುತ್ತದೆ, ಮತ್ತು ಅದರ ಕೆಳಗೆ ಎಲ್ಲೋ ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಸಾಧನವನ್ನು ಸಂರಚಿಸಲು ಸ್ಥಳೀಯ ಕೋಡ್ ಕರೆಯುತ್ತದೆ. ಇವು ಒಂದೇ ಕರೆಯಲ್ಲಿ ಜೋಡಿಸಲಾದ ಎರಡು ವಿಭಿನ್ನ ಕಾರ್ಯವಿಧಾನಗಳು. Binder ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಮತ್ತು ಸಿಸ್ಟಮ್ ಸೇವೆಯ ನಡುವಿನ ಪ್ರಕ್ರಿಯೆಗಳ ನಡುವಿನ ಸಂವಹನ, ಆದರೆ JNI ಪ್ರಕ್ರಿಯೆಯೊಳಗೆ Java ನಿಂದ ಸ್ಥಳೀಯ ಕೋಡ್ಗೆ ಸೇತುವೆ. Android 9 AOSP ಮರವನ್ನು ಓದಿದರೆ ಸ್ಟಾಕ್ ಅಕ್ಷರಶಃ ಕಾಣುತ್ತದೆ, ಮತ್ತು ಒಳಗಿನ ವರ್ಗದ ಹೆಸರುಗಳು ಹಾಗೂ ಫೈಲ್ ಮಾರ್ಗಗಳು ಬಿಡುಗಡೆಗಳ ನಡುವೆ ಬದಲಾಗುತ್ತವೆ ಎಂಬುದನ್ನು ನೆನಪಿಡಿ.
ಬದಲಾಗದಿರುವುದು ನೀವು ಅವಲಂಬಿಸಬಹುದಾದ ಒಪ್ಪಂದ: builder, ಅದು ಹಿಂತಿರುಗಿಸುವ ಡಿಸ್ಕ್ರಿಪ್ಟರ್, ಮತ್ತು ಅದರ ಸುತ್ತಲಿನ ಸೇವಾ ಜೀವನಚಕ್ರ. ಇಂಟರ್ಫೇಸ್ ಪಡೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಆಂತರಿಕ ಸೇವಾ ವಹಿವಾಟನ್ನು ಕರೆಯಬಾರದು ಅಥವಾ ಡಿವೈಸ್ ನೋಡ್ ಅನ್ನು ಮತ್ತೆ ರಚಿಸಬಾರದು. ನಿಮ್ಮ ಕೋಡ್ AOSP ವರ್ಗದ ಹೆಸರನ್ನು ಅವಲಂಬಿಸಿದರೆ, ನೀವು ಪರೀಕ್ಷಿಸದ ಬಿಡುಗಡೆಯಲ್ಲಿ ಅದು ಮುರಿಯುತ್ತದೆ.
TUN IP ಸಾಗಿಸುತ್ತದೆ, TAP Ethernet
TUN ಒಂದು IP ಇಂಟರ್ಫೇಸ್. TAP ಒಂದು Ethernet ಇಂಟರ್ಫೇಸ್, ಮತ್ತು ಆ ವ್ಯತ್ಯಾಸ ಬ್ರಿಡ್ಜಿಂಗ್ ಸಾಧ್ಯವೇ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ. TUN ಸಾಧನಕ್ಕೆ MAC ವಿಳಾಸವಿಲ್ಲ ಮತ್ತು ಮುಂದುಗಡೆ ಕಳುಹಿಸಲು Ethernet ಹೆಡರ್ ಇಲ್ಲ, ಆದ್ದರಿಂದ TUN ಕ್ಲೈಂಟ್ ರೂಟ್ಗಳನ್ನು ಹೇಗೇ ಬರೆದರೂ layer-2 ಬ್ರಿಡ್ಜ್ಗೆ ಸೇರಲಾರದು.
VpnService ನಿಮಗೆ IP ರೂಪಾಂತರ ನೀಡುತ್ತದೆ, ಅದೇ ಅಪ್ಲಿಕೇಶನ್ ಮಟ್ಟದ VPN ಗೆ ಬೇಕಾಗಿರುವುದು ಮತ್ತು ಕಚ್ಚಾ Ethernet ಸ್ಟಾಕ್ ಇಲ್ಲದೆ ಬೆಂಬಲಿಸಬಹುದಾದದ್ದು. ನಿಮ್ಮ ವಿನ್ಯಾಸಕ್ಕೆ ಬ್ರಿಡ್ಜಿಂಗ್ ಬೇಕಾದರೆ, ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗ ನಿಮ್ಮನ್ನು ಅಲ್ಲಿಗೆ ಒಯ್ಯುವುದಿಲ್ಲ, ಮತ್ತು root ಮಾರ್ಗ ಕರ್ನಲ್ ಹಾಗೂ ಸಾಧನದ ಅನುಮತಿಗಳು ಸಹಕರಿಸಿದರೆ ಮಾತ್ರ ಒಯ್ಯುತ್ತದೆ.
root ಮಾರ್ಗ ಇನ್ನೂ ಗೆಲ್ಲುವ ಸ್ಥಳ
ಮೂರು ಕೆಲಸಗಳು ಜನರನ್ನು ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗದಿಂದ ದೂರ ತಳ್ಳುತ್ತವೆ. layer-2 ಬ್ರಿಡ್ಜಿಂಗ್ಗೆ TAP ಬೇಕು. ನಿಮ್ಮ VPN ವ್ಯಾಪ್ತಿಯ ಹೊರಗಿನ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಸಂಚಾರವನ್ನು ಹಿಡಿಯಲು ಫ್ರೇಮ್ವರ್ಕ್ ನೀಡದ ಗೋಚರತೆ ಬೇಕು. builder ಎಂದಿಗೂ ಬಹಿರಂಗಪಡಿಸದ ನೀತಿ ರೂಟಿಂಗ್, ಉದಾಹರಣೆಗೆ ಒಂದು ಗಮ್ಯಸ್ಥಾನಕ್ಕೆ ಪ್ರತ್ಯೇಕ ಕೋಷ್ಟಕ, ನೀವೇ ಸ್ಥಾಪಿಸುವ ನಿಯಮಗಳನ್ನು ಬಯಸುತ್ತದೆ.
ವೆಚ್ಚಗಳು ನಂತರ ಬರುತ್ತವೆ: ಅನ್ಲಾಕ್ ಮಾಡಿದ bootloader ಅಥವಾ root ಮಾಡಿದ ಇಮೇಜ್, ನಿಮ್ಮ ಕಾಲಿನಡಿಯಲ್ಲಿ ಜರುಗುವ SELinux ನೀತಿ, ಮತ್ತು OTA ನಂತರ ಸರಿಯಾಗಿ ವರ್ತಿಸುವುದನ್ನು ನಿಲ್ಲಿಸುವ ಸಾಧನ. root ಮಾಡಿದ ವಿಧಾನವನ್ನು ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್ ವಿತರಣೆಯ ಮೂಲಕ ಕಳುಹಿಸಲೂ ಸಾಧ್ಯವಿಲ್ಲ, ಆದ್ದರಿಂದ ಬಹುಪಾಲು ತಂಡಗಳು ಅದನ್ನು ಉತ್ಪನ್ನದ ಬದಲು ಆಂತರಿಕ ರೋಗನಿರ್ಣಯ ಮಾರ್ಗವಾಗಿ ಇಟ್ಟುಕೊಳ್ಳುತ್ತವೆ.
ಎರಡರ ನಡುವೆ ಆಯ್ಕೆ
ನಿಮ್ಮ ಬಳಿ ಇರುವ ಕೋಡ್ನಿಂದ ಅಲ್ಲ, ನಿಮಗೆ ಬೇಕಾದ ಇಂಟರ್ಫೇಸ್ನಿಂದ ಪ್ರಾರಂಭಿಸಿ. ಉತ್ತರ ಅಪ್ಲಿಕೇಶನ್-ಸೀಮಿತ ರೂಟ್ಗಳಿರುವ TUN ಸಾಧನವಾದರೆ, ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗ ಚಿಕ್ಕದು ಮತ್ತು ನವೀಕರಣಗಳನ್ನು ಬದುಕುತ್ತದೆ. ಉತ್ತರದಲ್ಲಿ Ethernet ಫ್ರೇಮ್ಗಳು, ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಕ್ಯಾಪ್ಚರ್, ಅಥವಾ builder ತಿರಸ್ಕರಿಸುವ ರೂಟಿಂಗ್ ನಿಯಮಗಳು ಸೇರಿದ್ದರೆ, ನೀವು root ಪ್ರದೇಶದಲ್ಲಿದ್ದೀರಿ ಮತ್ತು ಅದನ್ನು ಕಾರ್ಯಾಚರಣಾ ವೆಚ್ಚವಾಗಿ ಬಜೆಟ್ ಮಾಡಬೇಕು.
ಬಹುಪಾಲು ಚರ್ಚೆಗಳನ್ನು ತೀರಿಸುವ ಒಂದು ಪರಿಶೀಲನೆ: ಮೊದಲು ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಮಾರ್ಗವನ್ನು ನಿರ್ಮಿಸಿ, establish() ಫಲಿತಾಂಶವನ್ನು ದೂರದ ಸೆಶನ್ ಸ್ಥಿತಿಯಿಂದ ಪ್ರತ್ಯೇಕವಾಗಿ ದಾಖಲಿಸಿ, ಮತ್ತು ಪ್ರತಿ ದಿಕ್ಕಿನಲ್ಲಿ ಒಂದು ಪ್ಯಾಕೆಟ್ ದೃಢೀಕರಿಸಿ. ಆಮೇಲೆಯೇ ಕಾಣೆಯಾದ ಸಾಮರ್ಥ್ಯ ಬೆಂಬಲಿತ ಮಾರ್ಗ ಬಿಡಲು ಸಮರ್ಥನೆ ನೀಡುತ್ತದೆಯೇ ಎಂದು ನಿರ್ಧರಿಸಿ.