VPN на Mac при стартиране: launchd управлява задачата, не тунела
Чист 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 смята, че задачата е неуспешна и политиката му за рестартиране ще направи нещо, което не сте имали предвид.
Използвайте документирания режим на преден план или на услуга на клиента. Ако продуктът има собствена поддържана функция за стартиране, тя вече знае как да остане на преден план и как да предаде на мрежовия стек; собствената задача е отделен дизайн, а не подобрение на нея.
Дайте на задачата уникален етикет, желания изпълним файл и обмислен масив от аргументи. Масивът не е команден ред на shell, затова тръбите и пренасочванията не работят там и кавичките се държат различно. Команда, която успява в терминала на администратор, в най-добрия случай е предварителна проверка.
Идентификационните данни трябва да работят без подкана
Необслужваната работа премества проблема с идентификационните данни, вместо да го премахва. Някой трябва да притежава идентичността, да реши колко дълго живее и да документира как се подменя. Сертификат без наблюдение на срока на валидност се превръща в прекъсване с дата в календара.
Пазете тайните извън аргументите и извън стандартния изход на задачата. Ако клиентът поддържа четене на идентификационни данни от защитено хранилище, използвайте този път и проверете дали контекстът на изпълнение на задачата може да стигне до хранилището. Демон, работещ като root, обикновено не може да прочете елемент от ключодържателя за вход и това е детайлът, който се появява само в системния контекст.
Определете какво означава готовност и тествайте там
Успешното стартиране доказва, че процесът е започнал. То не доказва, че мрежата работи, че шлюзът е приел идентичността или че частното приложение е достъпно. Ако нещо друго зависи от тунела, то се нуждае от сигнал за готовност, който отразява връзката, а не времето за стартиране на задачата.
Повторните опити трябва да са ограничени и да различават липсваща мрежа от отказани идентификационни данни. Рестартирането при всеки провал не може да поправи изтекъл сертификат и създава журнал, пълен с еднакви опити, който скрива истинския.
Приемете задачата в контекста, в който реално ще работи: без мрежа при стартиране, при нормален вход, при събуждане от сън и при контролирано спиране. После запишете етикета на задачата, версията на клиента и ревизията на профила заедно, така че следващият човек да наследи услуга с ясен произход, а не файл, който някога е работил.