API VPN cho iOS: NEVPNManager, nhà cung cấp tunnel hay profile?
Chọn API theo transport mà bạn phải nói chuyện, sau đó chứng minh tunnel mang lưu lượng: thứ tự save-load-start, entitlement của provider và các quy tắc on-demand.
Ba sản phẩm khác nhau cùng mang tên iOS VPN và chúng không chia sẻ một API. Personal VPN chạy trên các transport IPsec và IKEv2 có sẵn trong hệ thống. Custom tunnel chạy giao thức của riêng bạn bên trong network extension. Configuration profile cấu hình một trong hai và có thể thêm hành vi on-demand. Chọn theo transport mà bạn phải nói chuyện nhanh hơn chọn theo hướng dẫn nào được biên dịch trước.
Chạy các kiểm tra dưới đây theo thứ tự, vì mỗi bước giả định bước trước đã tạo ra một cấu hình hợp lệ.
Bước 1: chọn theo transport
Nếu máy chủ là IKEv2 hoặc IPsec kiểu Cisco, NEVPNManager là đủ và các transport của hệ thống đi kèm miễn phí. Nếu máy chủ nói OpenVPN, WireGuard hoặc bất cứ thứ gì khác, NEVPNManager không thể giúp: nó không có móc nối cho giao thức của bên thứ ba. Trường hợp đó cần NETunnelProviderManager với một packet tunnel provider triển khai giao thức. Profile chỉ phân phối cấu hình và không thể thêm một transport mà hệ điều hành không có.
PPTP không phải mục tiêu trên các hệ thống hiện tại. IPsec với shared secret vẫn mong đợi tên nhóm trong remoteIdentifier, một mục keychain giữ bí mật và xác thực mở rộng khi máy chủ yêu cầu tên người dùng. Mỗi phần thiếu đều hiện ra như cùng một lỗi cấu hình chung, vì vậy hãy thêm tất cả trước khi gỡ lỗi bất cứ điều gì khác.
Bước 2: tôn trọng thứ tự lưu, tải, khởi động
NEVPNManager ghi vào preferences, đọc lại chúng và chỉ sau đó mới khởi động. Điền các đối tượng giao thức và manager, gọi saveToPreferences, gọi loadFromPreferences và gọi startVPNTunnel từ load completion handler. Khởi động trước khi quá trình tải trở lại tạo ra lỗi configuration-invalid, NEVPNErrorDomain code 1, trên một cấu hình mà nếu không thì vẫn đúng.
Hình dạng đủ ngắn để giữ ở một chỗ:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }startVPNTunnel trả về khi yêu cầu được chấp nhận, không phải khi tunnel đã lên. Quan sát NEVPNStatusDidChange và đọc connection.status để biết trạng thái thật. Ứng dụng giả định thành công tại chỗ gọi báo cáo VPN đã kết nối trong khi extension vẫn đang thương lượng. Trạng thái connecting là bình thường trong chốc lát; trạng thái không bao giờ rời khỏi nó là lỗi đáng ghi log.
Bước 3: cho tiến trình provider những gì nó cần
Custom transport chạy trong một tiến trình riêng với bundle identifier riêng và entitlement riêng. Cả ứng dụng container lẫn provider đều cần entitlement network-extension khi ký, và bản build Developer ID ngoài App Store vẫn phải mang nó trong provisioning profile. Một entitlement thiếu trông giống lỗi giao thức vì extension đơn giản là không khởi động.
Không có socket descriptor công khai nào để mượn. NEPacketTunnelProvider cung cấp cho bạn NEPacketTunnelFlow với read, write và cancel, và mã vươn tới các đường dẫn khóa riêng sẽ hỏng giữa các bản phát hành. Provider tiếp tục chạy khi ứng dụng ở chế độ nền, nên ứng dụng container không cần chế độ nền cho việc đó.
Bước 4: on-demand là một tập quy tắc, không phải công tắc
isOnDemandEnabled chỉ trang bị các quy tắc; NEOnDemandRuleConnect và anh em của nó quyết định khi nào tunnel lên. Một quy tắc evaluate-connection với probe URL chỉ tốt bằng chính URL đó. Nếu probe trả lời mà không có tunnel, quy tắc kết luận mạng riêng đã tiếp cận được và không bao giờ kết nối, vì vậy hãy trỏ nó vào thứ chỉ trả lời từ bên trong.
Always-on là một lời hứa riêng. Nó cần một thiết bị được giám sát và một profile được quản lý, và người dùng không được giám sát có thể xóa profile bất cứ lúc nào. Đừng phát hành thiết kế phụ thuộc vào always-on trừ khi đội thiết bị được giám sát.
Bước 5: chứng minh đường đi, không phải nhãn
Quét các interface tun, tap, ppp hoặc ipsec chứng minh rằng một VPN đã được cấu hình, không phải rằng yêu cầu của bạn đã dùng nó. NWPathMonitor với usesInterfaceType(.other) cho biết một interface ảo có sẵn, và một viability handler có thể kiểm tra một host. Cả hai đều không chứng minh đường ra, vì vậy hãy kết hợp chúng với một yêu cầu đến tài nguyên mà chỉ tunnel mới tiếp cận được. Tên interface là trợ giúp chẩn đoán, không bao giờ là cổng mà logic ứng dụng phải rẽ nhánh.
Để kiểm tra thực địa, so sánh địa chỉ công cộng có và không có tunnel và lấy một trang chỉ nội bộ. Một lệnh gọi status có thể báo cáo đã kết nối trong khi provider đang thương lượng, vì vậy hãy để kết quả tài nguyên quyết định và coi status là bằng chứng hỗ trợ.