Το ping στο 192.0.2.10 σας λέει ότι μια διεύθυνση απάντησε σε ένα ICMP echo, και τίποτα άλλο. Σε δίκτυο χωρίς σήραγγα μπορεί να πετύχει, γιατί η διεύθυνση μπορεί να βρίσκεται στο τοπικό υποδίκτυο· με υγιή σήραγγα μπορεί να αποτύχει, γιατί ο διακομιστής πετάει τα ICMP ενώ εξυπηρετεί HTTPS. Ο έλεγχος που χρειάζεται το script σας είναι ένα ερώτημα κατάστασης της πλατφόρμας συν ένα τεστ διαδρομής για τον προορισμό που χρησιμοποιεί η εφαρμογή. Αντιμετωπίστε τα ως δύο ξεχωριστά πεδία, ποτέ ως ένα boolean.

Τι αποδεικνύει στην πραγματικότητα μια απάντηση echo

Το ICMP είναι πρωτόκολλο προσβασιμότητας χωρίς αντίληψη διεπαφών ή σηράγγων. Όταν φτάνει μια απάντηση, ο πυρήνας αναφέρει ότι απάντησε ένας host· δεν αναφέρει ποια διαδρομή μετέφερε το αίτημα ή ποια μετέφερε την απάντηση. Το φιλτράρισμα κάνει το σήμα ακόμη πιο θορυβώδες, γιατί ένα firewall που μπλοκάρει αιτήματα echo δεν λέει τίποτα για τις θύρες πίσω του. Και ένα προφίλ με split tunnel μπορεί να εξαιρεί σκόπιμα τη διεύθυνση που δοκιμάζετε, ενώ κάθε άλλος προορισμός λειτουργεί.

Αυτό που θέλετε πραγματικά να μάθετε είναι αν μια συγκεκριμένη υπηρεσία είναι χρησιμοποιήσιμη μέσω της διαδρομής που ακολουθεί η εφαρμογή. Διαλέξτε τον host και τη θύρα που καλεί η εφαρμογή και μετά απαιτήστε απάντηση στο επίπεδο εφαρμογής.

Η προσβασιμότητα και η κατάσταση της σήραγγας είναι διαφορετικά γεγονότα, και οποιοδήποτε από τα δύο μπορεί να είναι αληθές ενώ το άλλο ψευδές. Το να τα κρατάτε χωριστά σας λέει ποιος κατέχει την αποτυχία. Το να τα συνενώσετε σε έναν έλεγχο παράγει ένα δελτίο που κανείς δεν μπορεί να δρομολογήσει.

Ρωτήστε το Android για τη μεταφορά, όχι για ping

Το Android απαντά στην ερώτηση κατάστασης απευθείας μέσω του ConnectivityManager. Οι δυνατότητες του ενεργού δικτύου φέρουν μια σημαία μεταφοράς VPN, που τίθεται όταν η κίνηση δρομολογείται μέσω διεπαφής VPN. Η κλήση είναι τοπική, φθηνή και ανεξάρτητη από το αν απαντά κάποιος απομακρυσμένος host.

Αυτή η έκδοση Java επιστρέφει false αντί να πετάει εξαίρεση όταν δεν υπάρχει ενεργό δίκτυο. Επειδή διαβάζει το ενεργό δίκτυο, αντανακλά το προφίλ που επέλεξε ο χρήστης στις Ρυθμίσεις.

ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

Για ειδοποιήσεις αλλαγής, καταχωρίστε ένα NetworkCallback αντί να ερωτάτε με χρονόμετρο. Μην το μπερδεύετε με το VpnService.prepare, που αναφέρει μόνο αν ο χρήστης έδωσε άδεια για VPN, όχι αν ρέουν πακέτα. Η ανάκληση φτάνει μέσω VpnService.onRevoke, αλλά το να ξεχάσετε ένα προφίλ στις Ρυθμίσεις δεν παράγει καμία εκπομπή.

iOS: τα ονόματα διεπαφών είναι ευρετική, όχι συμβόλαιο

Πολλά αποσπάσματα iOS εξετάζουν τις ρυθμίσεις proxy, βρίσκουν το λεξικό __SCOPED__ και ψάχνουν κλειδιά διεπαφής όπως tap, tun, utun2, ppp ή ipsec. Αυτή η προσέγγιση είναι σύμβαση ονοματοδοσίας, όχι τεκμηριωμένη εγγύηση, οπότε μια ενημέρωση του λειτουργικού που μετονομάζει μια διεπαφή μπορεί να τη σπάσει. Έχει επίσης την τάση να αναφέρει αληθές για παλιές εγγραφές που επιβιώνουν της σήραγγας.

Όταν η εφαρμογή σας κατέχει τη διαμόρφωση, το NEVPNManager σας δίνει πραγματική κατάσταση. Περιγράφει τη σήραγγα που ξεκίνησε η εφαρμογή σας· με VPN ανά εφαρμογή, άλλες εφαρμογές μπορεί να βρίσκονται εντελώς έξω από αυτή τη σήραγγα.

Φορτώστε ξανά τις προτιμήσεις πριν διαβάσετε την κατάσταση, γιατί η τιμή αλλάζει καθώς η σήραγγα ανεβαίνει και πέφτει:

let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
    let up = manager.connection.status == .connected
    print(up)
}

Μια σημαία κατάστασης της πλατφόρμας εξακολουθεί να μην αποδεικνύει ότι η κίνηση φτάνει στον peer. Αυτό το κενό καλύπτει το τεστ διαδρομής, και γι' αυτό ένα boolean δεν αρκεί για την υποστήριξη.

Τα προφίλ των Windows εκθέτουν πραγματικό πεδίο κατάστασης

Τα Windows παρακολουθούν τα προφίλ VPN χωριστά από τους προσαρμογείς, και το Get-VpnConnection εκθέτει ConnectionStatus για κάθε προφίλ που γνωρίζει. Προφίλ που δημιουργήθηκαν μέσω του πελάτη Windows ή πακέτου παροχής εμφανίζονται εδώ. Το cmdlet δεν είναι γενικός ανιχνευτής σηράγγων.

Διαβάστε το πεδίο για επώνυμο προφίλ, προσθέτοντας -AllUserConnection όταν το προφίλ ανήκει σε όλους τους χρήστες:

Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress

Οι πελάτες τρίτων συχνά μένουν αόρατοι σε αυτό το cmdlet ακόμη και όταν η σήραγγά τους είναι ενεργή, οπότε ένα κενό αποτέλεσμα σημαίνει άγνωστο, όχι αποσυνδεδεμένο. Οι λίστες προσαρμογέων παραπλανούν εξίσου: ένας προσαρμογέας κατασκευαστή μπορεί να παραμένει ενώ είναι αδρανής, και μερικοί προσαρμογείς υπάρχουν μόνο κατά τη διάρκεια μιας συνεδρίας. Για προφίλ που ανήκει στα Windows, το rasdial αναφέρει κωδικό εξόδου στον οποίο μπορείτε να διακλαδωθείτε. Όλα αυτά περιγράφουν τοπική πεποίθηση, όχι προσβασιμότητα του peer.

Κατάσταση συν διαδρομή: ο έλεγχος δύο μερών

Ένα συνδεδεμένο προφίλ δεν λέει τίποτα για το πού πάνε τα πακέτα. Το split tunneling μπορεί να κρατά τη σήραγγα ενεργή ενώ εξαιρεί τον προορισμό που σας νοιάζει. Τα προφίλ always-on μένουν συνδεδεμένα με νεκρό διακομιστή, και ένα kill switch μπλοκάρει σκόπιμα την κίνηση όταν πέφτει η σήραγγα.

Δοκιμάστε και τα δύο επίπεδα: επιβεβαιώστε ότι είναι ενεργή μια μεταφορά VPN ή ένα προφίλ, και μετά ότι ο προορισμός επιλύεται και απαντά σε αυτή τη διαδρομή. Στο Linux, ρωτήστε τον πυρήνα ποια διεπαφή θα χρησιμοποιούσε:

ip route get 192.0.2.10
resolvectl query intranet.example.test

Όταν ο πελάτης είναι εκτός ελέγχου σας, καταγράψτε και τα δύο αποτελέσματα και αφήστε το μοτίβο να δείξει το επίπεδο. Το συνδεδεμένο με αποτυχημένο τεστ διαδρομής υποδηλώνει split tunneling, DNS ή πολιτική. Το αποσυνδεδεμένο με λειτουργικό τεστ διαδρομής σημαίνει ότι άλλη διαδρομή μεταφέρει την κίνηση.

Ένα τεστ που μπορείτε να εκτελέσετε με σειρά

Καταγράψτε πρώτα την κατάσταση της πλατφόρμας, πριν αλλάξετε οποιαδήποτε κατάσταση δικτύου. Επιλύστε το όνομα host και σημειώστε την οικογένεια διευθύνσεων, γιατί μια εγγραφή AAAA μπορεί να ακολουθήσει διαφορετική διαδρομή από μια εγγραφή A. Ανοίξτε τη θύρα της υπηρεσίας και απαιτήστε απάντηση εφαρμογής αντί για γυμνή χειραψία. Κρατήστε κάθε παρατήρηση στο δικό της πεδίο καταγραφής.

Σε μηχάνημα Linux με dig και curl, τρεις εντολές καλύπτουν επίλυση, διαδρομή και την ίδια την υπηρεσία. Εκτελέστε τις με τη σήραγγα ενεργή και ξανά με αυτήν ανενεργή:

dig +short intranet.example.test
ip route get 198.51.100.20
curl -sS -o /dev/null -w "%{http_code}" --max-time 8 https://intranet.example.test/health

Τέσσερα ξεχωριστά πεδία κερδίζουν ένα boolean, γιατί κατάσταση, DNS, διαδρομή και πολιτική αποτυγχάνουν ανεξάρτητα και καταλήγουν σε διαφορετικές ομάδες. Το ping σε τερματικό παραμένει καλός χειροκίνητος έλεγχος. Είναι όμως κακός ορισμός συνδεσιμότητας για αυτοματισμό, όπου το API της πλατφόρμας και ένα τεστ διαδρομής απαντούν στο πραγματικό ερώτημα.

Σχετικά άρθρα