프로파일을 설치하고 터널이 올라오면 모든 것이 끝난 것처럼 보입니다. 그런데 기기가 재부팅되면 on-demand가 전면에 앱이 없는 상태에서 연결을 깨우고, 터널은 시작을 거부합니다. 프로파일은 그대로 있고 비밀번호도 여전히 맞습니다. 그래서 이 고장은 사람들을 엉뚱한 곳으로 보냅니다. Network Extension은 프로파일에서 비밀을 읽을 수 없습니다. 스스로 해석할 수 있는 키체인 참조가 필요합니다.

아래 설명은 참조를 만드는 쿼리에서 그것을 시험하는 재부팅까지, 이 인계를 지나는 한 번의 연결 시도를 따라갑니다.

프로파일은 비밀이 아니라 손잡이를 저장합니다

NEVPNProtocol이 passwordReference와 sharedSecretReference를 노출하는 데는 이유가 있습니다. 데몬이 터널을 시작할 때 그것은 여러분의 프로세스 안에서 실행되지 않을 수 있으므로, 여러분의 코드를 호출해 비밀번호를 물을 수 없습니다. 영구 키체인 참조를 읽고, 자기 컨텍스트에서 해석하고, 항목을 직접 가져옵니다.

그 참조는 키체인에 요청해서 만듭니다. 이것은 데이터를 요청하는 것과 다른 요청입니다.

let query: [String: Any] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrService as String: "vpn-credentials",
  kSecAttrAccount as String: "user",
  kSecReturnPersistentRef as String: true,
  kSecMatchLimit as String: kSecMatchLimitOne
]

돌려받은 객체를 프로토콜에 넘기고, 항목의 데이터를 넘기지 마십시오. 실제로 프로파일은 비밀이 어디 사는지 기록하며, 구성 백업이 비밀번호를 plist에 조용히 복제하지 않는 이유도 그것입니다.

API가 -50을 돌려주는 이유

errSecParam은 요청이나 값이 그 작업에 맞지 않게 만들어졌다는 뜻이며, 참조 요청과 데이터 요청이 뒤섞일 때 가장 자주 보이는 오류입니다. 받는 쪽 코드가 참조를 기다리는데 데이터를 요청하기, passwordReference에 원시 바이트를 대입하기, 앱이 쓸 수 없는 접근 그룹으로 질의하기, 모두 이것을 만들어냅니다.

래퍼 라이브러리가 이를 부추깁니다. 바이트를 돌려주는 헬퍼는 참조를 돌려주는 헬퍼와 바꿔 쓸 수 없으므로, 고치는 일은 보통 다른 비밀번호가 아니라 다른 쿼리입니다.

같은 불일치가, 문제없이 저장된 뒤 연결되지 않는 프로파일을 설명합니다. 저장된 것은 손잡이가 아니라 덩어리이며, 데몬에는 해석할 것이 없습니다.

저장은 잘 되고 연결에서 실패합니다

저장은 여러분 앱의 컨텍스트를 사용합니다. 연결은 데몬의 컨텍스트를 사용하고, 둘의 접근 권한은 같지 않습니다. 그래서 프로파일은 시뮬레이터에서 돌린 모든 테스트를 통과하고 첫 on-demand 시작에서 실패할 수 있습니다.

재부팅 증상도 같은 모양입니다. 앱이 열려 있는 동안에는 되고, 시스템이 스스로 터널을 시작하면 죽습니다.

출시 전에 백그라운드 경로를 일부러 시험하십시오. 앱을 닫은 채 on-demand 연결을 일으키고, 앱 로그가 아니라 기기 콘솔을 읽으십시오. 실패는 참조를 해석하려 한 프로세스가 기록하기 때문입니다. 콘솔이 데몬이 항목을 거부한다고 보여 주면 참조는 정상이고 문제는 항목의 접근성입니다.

재부팅이 되는지는 접근성이 결정합니다

항목은 터널을 시작하는 어떤 시스템 프로세스든 읽을 수 있어야 하며, 그 대상은 앱이 전면에 있을 때보다 넓습니다. 그 제약이 접근성 속성을 대신 골라 줍니다. 첫 잠금 해제까지 보호된 항목은 기기가 한 번 잠금 해제된 뒤 백그라운드 시작에 쓸 수 있습니다. 기기가 지금 잠금 해제되어 있어야 하는 항목은 그렇지 않습니다.

더 엄격한 등급을 고르는 것은 솔깃하고, 바로 그것이 잠긴 기기에서 on-demand 프로파일을 깨뜨립니다.

등급을 바꾼 뒤에는 기존 항목의 속성을 편집하지 말고 항목을 다시 만들고, 새 참조로 프로토콜을 다시 저장하십시오. 기존 항목의 속성 변경은 문서가 암시하는 동작을 늘 만들어 내지는 않으며, 다시 만든 항목은 의심을 없앱니다.

로테이션은 저장된 프로파일이 썩는 곳입니다

키체인의 비밀번호를 바꿔도 저장된 프로파일이 가리키는 대상은 자동으로 바뀌지 않습니다. 항목을 지우는 것은 더 나쁩니다. 프로파일은 더 이상 존재하지 않는 것에 대한 참조를 유지하고, 고장은 인증 거부처럼 보입니다.

한 가지 순서로 로테이션하십시오. 항목을 갱신하고, 새 영구 참조를 질의하고, 프로토콜을 다시 저장한 뒤, 앱을 닫은 채 연결해 데몬이 여전히 해석할 수 있음을 증명하십시오. 사용자 비밀번호와 공유 비밀을 별도 항목에 두어 각자 자기 일정대로 돌게 하고, 쿼리 사전이나 참조 자체를 절대 로그에 남기지 마십시오. 손잡이는 비밀이 아니지만 비밀로 가는 지도입니다.

관련 글