Jy het twee maniere om die tonnel se eie pakkette buite die tonnel te hou: beskerm die transportsokkel, of haal die hele app uit die VPN. Hulle los verskillende probleme op, en om die wyer een te kies omdat dit makliker is om te bedraad, is hoe apps plaaslike netwerktoegang en geskeide DNS verloor sonder om dit te agterkom. Begin by wat buite die tonnel moet bly, en kies dan die kleinste omvang wat dit bereik.

Wat protect() uit die tonnel verwyder

VpnService.protect() is 'n per-sokkel-oproep. Jy gee dit die sokkel of descriptor wat die tonnel dra, en Android merk daardie sokkel sodat sy verkeer die onderliggende netwerk gebruik in plaas van die VPN-koppelvlak. Alles anders wat die app stuur, volg steeds die normale VPN-roete.

Daardie smal omvang is die punt. 'n Beskermde sokkel verander nie hoe jou HTTP-kliënt name oplos, watter koppelvlak jou analytics-oproepe gebruik, of wat met 'n tweede verbinding gebeur wat later oopgemaak word nie.

Drie voorwaardes wat die omvang bepaal

Voorwaarde een is of net die tonneltransport moet ontsnap. As die app se ander verkeer steeds deur die VPN moet gaan, is sokkelbeskerming die regte omvang. Voorwaarde twee is of jy beheer het oor sokkel-skepping. 'n Biblioteek wat sy eie sokkel diep binne oopmaak, gee jou geen plek om protect() te roep nie, tensy dit 'n haak blootstel of 'n voorafgeboude sokkel aanvaar. Voorwaarde drie is of die app die plaaslike netwerk of 'n captive portal direk moet bereik, wat 'n ander vereiste is as om die tonnel lewendig te hou.

Om die app uit te sluit met addDisallowedApplication() is die bot werktuig. Dit verwyder elke verbinding wat die app maak uit die VPN, insluitend dié wat jy wou ondersoek, en op sommige toestelle verander dit ook hoe plaaslike ontdekking werk.

'n Derde opsie is om die transport aan 'n gekose netwerk te bind met bindProcessToNetwork() of 'n sokkelvlak-netwerkhandvatsel. Dit is nuttig wanneer die toestel gelyktydig Wi-Fi en selfoon het en jy wil hê die tonnel moet op 'n spesifieke opstroom ry.

Roep dit terwyl die transport geskep word

Roep protect() in dieselfde blok wat die transport skep, voor connect() of send(). As die oproep vals terugkeer, sluit die sokkel en laat die opstelling misluk; om aan te hou laat jou met 'n transport waarvan die pakkette jou eie koppelvlak kan binnegaan.

Die vorm is klein genoeg om op een plek te hou:

DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
    transport.close();
    throw new IOException("transport not protected");
}
transport.connect(serverAddress);

Drie besonderhede byt hier. Eerste,die boolean is die enigste sein wat jy kry, so teken die mislukking aan met genoeg konteks om 'n herroepte toestemming van 'n geweierde oproep te onderskei. Tweede,protect() dek die sokkel, nie die descriptor-nommer nie: as jy die sokkel sluit en later dieselfde heelgetal vir 'n ander sokkel hergebruik, is die nuwe sokkel nie beskerm nie. Derde, wanneer 'n native biblioteek die transport oopmaak, beskerm die descriptor voordat die native kode verbind, of die roete is dalk al gekies. Die VpnService-verwysing is die plek om te bevestig watter oorladings jou teiken-API-vlak werklik bied.

Toets die geblokkeerde pad, nie net die gelukkige pad nie

Verifieer met die tonnel op, want dit is die enigste toestand waarin die twee paaie kan verskil. Stuur een versoek deur die beskermde transport en een vanaf 'n kode-pad wat nooit protect() geroep het nie, en vergelyk dan wat die verre kant sien: die beskermde verbinding behoort met die onderliggende netwerk as bron te arriveer, terwyl die onbeskermde een die tonnel se eie adres wys en die tonnel se grepe-tellers beweeg. Op die toestel wys ss of netstat dieselfde splitsing voordat enigiets die radio verlaat.

Toets herroeping afsonderlik, want 'n toestemmingsverandering breek die koppelvlak af sonder om jou sokkelkode te raak. Herroep die VPN-toestemming of stop die diens, bou die transport weer, en bevestig dat protect() steeds waar terugkeer en dat die transport weer verbind sodra toestemming weer gegee word.

As die beskermde versoek nietemin die tonnel volg, gebeur die beskermingsoproep waarskynlik nadat die sokkel reeds gerouteer is. Skuif dit vroeër en toets weer.

Hou die besluit neergeskryf langs die transport-opstelling: watter sokkels beskerm is, watter app-verkeer uitgesluit is, en wat die app doen wanneer beskerming misluk. Daardie lyn is wat 'n latere herontwerp keer om die uitsluiting na die hele app te verbreed omdat 'n enkele toets gefaal het. Dit gee ook die volgende persoon 'n manier om die bedoeling na te gaan sonder om die manifest terug te ontleed.

Verwante artikels