Εντοπισμός ενεργού VPN μέσα σε sandboxed εφαρμογή Mac
Δεν υπάρχει δημόσιο API για αυτό το ερώτημα, και το κόλπο με το όνομα διεπαφής είναι απλώς μια ευρετική μέθοδος. Έξι έλεγχοι για να αποφασίσετε από τι πρέπει πραγματικά να εξαρτάται η εφαρμογή σας.
Χρειάζεστε μία οθόνη να συμπεριφέρεται διαφορετικά όταν η σήραγγα είναι ενεργή, και δεν υπάρχει κλήση που να σας το λέει. Αυτός είναι ο περιορισμός παράδοσης: στο macOS κανένα δημόσιο πλαίσιο δεν αναφέρει αν είναι συνδεδεμένο ένα αυθαίρετο VPN, και στο iOS η κατάσταση ανήκει στην εφαρμογή που εγκατέστησε τη διαμόρφωση. Οι παρακάτω έλεγχοι πηγαίνουν από αυτό το όριο σε κάτι που μπορείτε να παραδώσετε, και οποιοσδήποτε από αυτούς μπορεί να τερματίσει νωρίς την αναζήτηση.
Έλεγχος 1: μπορεί να απαντηθεί καθόλου το ερώτημα;
Το sandboxing επιλύει το ερώτημα πριν το κάνει οποιοδήποτε API. Μια διεργασία τρίτου μέρους δεν μπορεί να απαριθμήσει την επέκταση άλλου προμηθευτή, ούτε μπορεί να διαβάσει τη διαμόρφωση αυτής της επέκτασης, άρα δεν υπάρχει υποστηριζόμενο αντικείμενο για να ρωτήσετε.
Κάθε παράκαμψη συναντά τον ίδιο τοίχο. Οι λίστες διεπαφών, scutil --nc list και οι άμεσες αναγνώσεις της διαμόρφωσης συστήματος είτε απαιτούν δικαιώματα που το sandbox κρατά είτε εξαρτώνται από συμπεριφορά που η Apple δεν υποσχέθηκε ποτέ. Αν το σχέδιο χρειάζεται ένα από αυτά, το πρόβλημα είναι το σχέδιο. Ένα χαρακτηριστικό χτισμένο πάνω σε ατεκμηρίωτη λεπτομέρεια είναι ένα αίτημα υποστήριξης με ημερομηνία παράδοσης.
Έλεγχος 2: διαχειρίζεται η εφαρμογή σας τη σήραγγα μόνη της;
Αν ναι, έχετε μια υποστηριζόμενη απάντηση για τη δική σας διαμόρφωση. Φορτώστε τις προτιμήσεις, χειριστείτε το σφάλμα, μετά διαβάστε την κατάσταση και εγγραφείτε στις αλλαγές αντί να κάνετε δημοσκοπήσεις:
vpnManager.loadFromPreferences { error in
// handle a load failure before reading status
}
NotificationCenter.default.addObserver(
forName: .NEVPNStatusDidChange,
object: nil,
queue: nil
) { note in
let status = (note.object as? NEVPNConnection)?.status
}Να είστε ακριβείς για το τι επιστρέφει αυτό: την κατάσταση της σήραγγας που εγκαταστήσατε. Ένας χρήστης που τρέχει άλλον πελάτη θα εμφανιστεί ως αποσυνδεδεμένος, και αυτό δεν είναι σφάλμα στον κώδικά σας. Αποφασίστε ποιο από τα δύο ερωτήματα θέτει πραγματικά το χαρακτηριστικό σας πριν χτίσετε πάνω στην απάντηση.
Έλεγχος 3: τι θα σας έλεγε πραγματικά μια ευρετική μέθοδος;
Η ευρέως αντιγραμμένη προσέγγιση ζητά από το λεξικό διαμεσολαβητή του συστήματος τις εγγραφές με εύρος και διαβάζει τα κλειδιά, που τυχαίνει να είναι ονόματα διεπαφών:
let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []Ένα κλειδί που αρχίζει με tap, tun, ppp, ipsec ή utun υποδηλώνει ότι υπάρχει διεπαφή με εύρος σήραγγας. Η αντιστοίχιση ολόκληρου του ονόματος αποτυγχάνει αμέσως, επειδή το iOS 12 έφερε utun1 και utun2 και μερικά προφίλ εμφανίζονται ως ipsec4, ppp0 ή utun0. Συγκρίνετε προθέματα αντί γι' αυτό.
Παρόλα αυτά, ένα όνομα δεν προσδιορίζει ιδιοκτήτη. Χαρακτηριστικά συστήματος και επεκτάσεις άλλων προμηθευτών δημιουργούν επίσης διεπαφές utun, και μία μπορεί να υπάρχει χωρίς να μεταφέρει τίποτα από την κίνησή σας. Διαβάστε το ως ένδειξη ότι κάτι σε σχήμα σήραγγας υπάρχει κοντά, τίποτα δυνατότερο. Ένα ψευδώς θετικό εδώ είναι φθηνό αν φιλτράρετε μόνο ένα χαρακτηριστικό, και ακριβό αν φιλτράρετε την οθόνη σύνδεσης.
Έλεγχος 4: μπορείτε να δοκιμάσετε τον προορισμό αντί γι' αυτό;
Αν η εφαρμογή χρειάζεται μόνο να ξέρει αν μια εσωτερική υπηρεσία είναι προσβάσιμη, δοκιμάστε αυτή την υπηρεσία. Ένας σύντομος έλεγχος με χρονικό όριο απαντά στο ερώτημα από το οποίο εξαρτάται πραγματικά το χαρακτηριστικό, και συνεχίζει να λειτουργεί όταν ο χρήστης αλλάζει πελάτη ή η σήραγγα αλλάζει σχήμα.
Η προσβασιμότητα είναι μια παρατήρηση για τη διαδρομή σας. Ένα όνομα διεπαφής είναι ένα συμπέρασμα για κάτι δίπλα στη διαδρομή σας, γι' αυτό η ευρετική μέθοδος παράγει διαφωνίες στις αναφορές σφαλμάτων και ο έλεγχος παράγει αποδείξεις. Αν ο έλεγχος αποτύχει ενώ ο χρήστης επιμένει ότι το VPN είναι ενεργό, τώρα έχετε μια συγκεκριμένη διαδρομή για αποσφαλμάτωση: επίλυση ονομάτων, διαδρομή ή άδεια υπηρεσίας.
Έλεγχος 5: μπορεί η πλατφόρμα να επιβάλει αυτό που χρειάζεστε;
Όταν η απαίτηση είναι εγγύηση ότι τίποτα δεν διαφεύγει από τη σήραγγα, το προφίλ είναι το σωστό μέρος, όχι ο ανιχνευτής. Η ενεργοποίηση του includeAllNetworks σε διαμόρφωση πλήρους σήραγγας σε iOS 14 ή νεότερο αλλάζει τη συμπεριφορά της πλατφόρμας αντί να ζητά από την εφαρμογή σας να το συμπεράνει. Η σημαία τεκμηριώνεται στην αναφορά NEVPNProtocol.
Αυτό είναι διαφορετικό είδος απάντησης: επιβολή αντί παρατήρησης. Ισχύει επίσης μόνο για προφίλ που ελέγχετε, οπότε δεν βοηθά μια εφαρμογή καταναλωτή που παρακολουθεί τη σήραγγα κάποιου άλλου.
Έλεγχος 6: κάντε την αποτυχία ασφαλή και παρατηρήσιμη
Απενεργοποιήστε μόνο τη δυνατότητα που χρειάζεται τη σήραγγα και αφήστε την υπόλοιπη εφαρμογή χρησιμοποιήσιμη. Ένας ανιχνευτής που κρύβει ολόκληρη τη διεπαφή όποτε δεν είναι σίγουρος κατασκευάζει μια διακοπή για όποιον η σήραγγα του χρησιμοποιεί όνομα που δεν προβλέψατε ποτέ. Επιστρέψτε στη συντηρητική συμπεριφορά: τα τοπικά χαρακτηριστικά συνεχίζουν να λειτουργούν και μόνο η απομακρυσμένη κλήση που χρειάζεται πραγματικά τη σήραγγα απενεργοποιείται. Αυτή η επιλογή είναι απόφαση προϊόντος και αξίζει να γραφτεί δίπλα στην ευρετική μέθοδο.
Καταγράψτε τι παρατηρήσατε: ονόματα διεπαφών, έκδοση πλατφόρμας και το αποτέλεσμα ενός ελέγχου. Αυτό μετατρέπει την επόμενη αναφορά από διαφωνία σε έλεγχο. Μετά προτιμήστε μια υποστηριζόμενη δήλωση όπου την έχετε, γιατί μια διαχειριζόμενη διαμόρφωση μπορεί να μεταφέρει την πρόθεση ρητά και να αφαιρέσει το μεγαλύτερο μέρος του λόγου να επιθεωρείτε ονόματα καθόλου.
Αν οι έλεγχοι 1 έως 5 σας άφησαν χωρίς υποστηριζόμενη απάντηση, παραδώστε τον έλεγχο και ονομάστε το αποτέλεσμα ειλικρινά. Ένα τεκμηριωμένο σήμα βέλτιστης προσπάθειας είναι καλύτερη απόφαση προϊόντος από ένα ιδιωτικό API που σπάει στην επόμενη έκδοση.