부팅 시 Mac VPN: launchd가 감독하는 것은 작업이지 터널이 아니다
lint를 통과한 plist는 자격 증명이나 준비 상태를 전혀 보증하지 않는다. 작업을 해당 세션에 맞추고 클라이언트를 포그라운드에 두고 그 맥락에서 테스트하라.
로그인할 때 작업이 실행되고 로그에는 클라이언트 시작이 남지만 터널은 올라오지 않는다. 아니면 올라왔다가 몇 초 뒤에 사라진다. 두 경우 모두 프로퍼티 목록 자체는 아마 정상이었다. launchd 는 작업을 받아들일 때 두 가지를 약속했다: 프로세스를 감독하고, 그 프로세스가 계속 실행된다는 것이다. VPN에는 둘 다 필요하지만 올바른 XML 파일은 어느 것도 제공하지 않는다.
유효한 프로퍼티 목록은 동작하는 서비스가 아니다
plutil -lint 는 구조를 검사한다. 바이너리가 있는지, 이 클라이언트 버전이 인수를 지원하는지, 자격 증명을 쓸 수 있는 맥락에서 작업이 시작되는지는 알려주지 못한다. 이는 의미론적 질문이며 launchd 문제처럼 보이는 실패의 대부분이 여기서 나온다.
plutil -lint /Library/LaunchDaemons/com.example.vpn.plist
launchctl print system/com.example.vpn
작업이 로드되었다고 가정하지 말고 두 번째 명령의 출력을 읽어라. 마지막 종료 상태와 서비스 실행 여부를 보고하므로, 프로파일을 건드리기 전에 "한 번도 시작되지 않음"과 "시작했다가 죽음"을 구분할 수 있다.
에이전트는 사용자 세션을 상속하고 데몬은 그렇지 않다
Apple의 launchd 문서는 사용자별 에이전트와 시스템 데몬을 구분한다. 에이전트는 로그인한 사용자의 맥락에서 그 사용자의 키체인과 환경과 함께 실행된다. 데몬은 그 세션 없이 실행되며, 작업을 시스템 디렉터리로 옮겨도 사용자의 대화형 자격 증명이 다시 만들어지지 않는다.
설계를 결정하는 것은 이 차이다. 연결에 사람이 로그인하거나 MFA 프롬프트를 승인해야 한다면 지원되는 구성은 로그인 후 실행되는 사용자 세션 작업. 아무도 로그인하지 않은 상태에서 동작해야 한다면 클라이언트에는 자체 갱신 및 폐기 절차를 갖춘 승인된 무인 신원이 필요하다. 잘못된 행을 고르면 깨끗하게 시작하고 첫 인증 단계에서 실패하는 작업이 만들어진다.
인수 배열에 비밀번호를 넣거나 인증서 검사를 끄는 것으로 그 차이를 덮지 마라. 둘 다 인증 요구 사항을 읽을 수 있는 파일 안의 영구 비밀로 바꾸고, 후자는 터널이 응답하는 모든 대상의 인증을 통과시킨다는 뜻이다.
감독은 프로세스가 전면에 남을 때만 작동한다
스스로 데몬화하는 클라이언트는 제어를 즉시 launchd에 돌려주고, 감독자는 이미 종료된 프로세스를 지켜보게 된다. 터널은 올라와 있을 수 있지만 launchd는 작업이 실패했다고 판단하고 재시작 정책이 의도하지 않은 일을 한다.
클라이언트가 문서화한 포그라운드 또는 서비스 모드를 사용하라. 제품에 자체 지원 시작 기능이 있다면 그 기능은 이미 전면에 머무는 방법과 네트워크 스택으로 넘기는 방법을 알며, 사용자 지정 작업은 별도의 설계이지 그 개선이 아니다.
작업에 고유한 레이블, 의도한 실행 파일, 의도적으로 구성한 인수 배열을 부여하라. 배열은 셸 명령줄이 아니므로 파이프와 리다이렉션이 동작하지 않고 인용 동작도 다르다. 관리자 터미널에서 성공하는 명령은 기껏해야 예비 검사다.
자격 증명은 프롬프트 없이 동작해야 한다
무인 운영은 자격 증명 문제를 제거하지 않고 옮길 뿐이다. 누군가는 신원을 소유하고, 수명을 정하고, 교체 방법을 문서화해야 한다. 만료 모니터링이 없는 인증서는 달력에 날짜가 찍힌 장애가 된다.
비밀을 인수와 작업의 표준 출력 밖에 두라. 클라이언트가 보호된 저장소에서 자격 증명을 읽을 수 있다면 그 경로를 쓰고, 작업의 실행 맥락이 저장소에 접근할 수 있는지 확인하라. root로 실행되는 데몬은 보통 로그인 키체인 항목을 읽지 못하며, 이런 세부 사항은 시스템 맥락에서만 드러난다.
준비 완료의 의미를 정의하고 그곳에서 테스트하라
성공적인 실행은 프로세스가 시작되었음을 증명한다. 네트워크가 올라와 있는지, 게이트웨이가 신원을 받아들였는지, 사설 애플리케이션에 도달할 수 있는지는 증명하지 않는다. 다른 무엇인가가 터널에 의존한다면 작업 시작 시각이 아니라 연결을 반영하는 준비 신호가 필요하다.
재시도는 제한되어야 하고 네트워크 부재와 거부된 자격 증명을 구분해야 한다. 실패할 때마다 다시 실행하는 것은 만료된 인증서를 고치지 못하고 진짜 시도를 가리는 동일한 시도로 가득한 로그를 만든다.
작업을 실제로 실행될 맥락에서 받아들여라: 부팅 시 네트워크 없음, 정상 로그인, 잠자기에서 깨어남, 통제된 중지. 그런 다음 작업 레이블, 클라이언트 버전, 프로파일 리비전을 함께 기록해 다음 사람이 한때 동작했던 파일이 아니라 추적 가능한 서비스를 물려받게 하라.