Монтирование общей папки из Tunnelblick без работы от имени root
AppleScript, остающийся открытым, может следить за одним профилем Tunnelblick и монтировать SMB-ресурс от имени вошедшего пользователя, без root-хука и без sudo без пароля.
VPN-клиенту нужна привилегированная помощь для перенастройки сети, и этот факт применяется слишком широко ко всему вокруг. Скрипту, который монтирует файловый ресурс, root не нужен, потому что ресурс принадлежит сеансу вошедшего пользователя и его учётным данным. Вынесение монтирования из привилегированного пути убирает необходимость в правилах sudo, root-хуках и правках встроенных приложений. Остаётся небольшой applet, который остаётся открытым, следит за одним профилем и делает одну попытку.
Почему это относится к пользовательскому сеансу
Смонтированный том — свойство сеанса, который его смонтировал. Сеанс другого пользователя его не видит, а монтирование, принадлежащее root, ведёт себя иначе, чем созданное Finder. Сохранение монтирования в пользовательском сеансе сохраняет эту семантику.
Привилегированные помощники существуют для тех частей, которым они действительно нужны: создание туннельного интерфейса, изменение маршрутов, обновление резолвера. Монтирование SMB-ресурса не относится к этим частям. Обращение с ним как с таковым вынуждает выбор между sudo без пароля и root-скриптом, который выполняется, когда никого нет. И то и другое — больший риск, чем оправдывает проблема, а подход через пользовательский сеанс полностью избегает этого выбора.
Собственные хуки подключения Tunnelblick здесь не замена, поскольку они выполняются вне сеанса рабочего стола, а их порядок относительно скриптов клиента не определён. Опрос состояния из пользовательского applet — меньший механизм с меньшим числом допущений.
Сначала докажите вручную, что ресурс работает
Автоматизация не может предоставить маршрут, разрешение или учётную запись, которых нет. Подключите VPN вручную и откройте ресурс в Finder, прежде чем писать какой-либо скрипт. Если это не удастся, скрипт потерпит неудачу более запутанным образом.
Запишите три значения, которые будет использовать скрипт: имя профиля точно так, как его перечисляет Tunnelblick, URL ресурса и имя тома, которое Finder показывает после монтирования. Имя тома важно, потому что проверка существующего монтирования использует его, а проверка только по имени — удобная страховка, а не доказательство идентичности сервера. Используйте имя, уникальное на машине. Затем убедитесь, что сервер вообще отвечает.
smbutil view //files.corp.example
osascript -e 'tell application "Tunnelblick" to get state of first configuration whose name is "Office"'
mount | grep -i smbfs
Первая команда доказывает, что сервер отвечает, вторая — что имя профиля разрешается, а третья показывает, как выглядит успешное монтирование. Зафиксируйте все три, прежде чем что-либо автоматизировать.
Прочитайте состояние профиля из Tunnelblick
Tunnelblick предоставляет свои конфигурации и их состояния через AppleScript, и это единственный хук, который нужен этому проекту. Важно то состояние, которое сообщается для этого одного профиля, а не присутствие приложения.
У опроса есть последствия, о которых стоит сказать. Переподключение короче интервала может пройти незамеченным, и applet вообще не видит перехода. Это приемлемо для страховки монтирования и неприемлемо для всего, что должно реагировать на каждое событие. Если нужна точность событий, это неподходящий механизм, а не механизм, которому нужен более короткий таймер. Выбирайте интервал с учётом этого компромисса.
property attempted : false
on idle
set profileName to "Office"
set shareURL to "smb://files.corp.example/OfficeTeam"
set volName to "OfficeTeam"
tell application "Tunnelblick" to set vpnState to state of first configuration whose name is profileName
if vpnState is not "CONNECTED" then
set attempted to false
return 20
end if
tell application "Finder" to set mounted to (exists disk volName)
if (not mounted) and (not attempted) then
set attempted to true
try
mount volume shareURL
end try
end if
return 20
end idle
Экспортируйте его как приложение с возможностью оставаться открытым, затем запустите в сеансе вошедшего пользователя, а не через sudo.
Смонтируйте один раз, затем прекратите попытки
Флаг попытки — это то, что не даёт этому превратиться в цикл угадывания учётных данных. Как только applet попробовал, он ждёт изменения состояния подключения, прежде чем пробовать снова.
Такое поведение намеренно. Ресурс, который отказывает в монтировании, обычно отказывает по причине, которую повторная попытка не исправит, а повторные попытки превращают один запрос в их поток. Флаг сбрасывается, когда профиль покидает подключённое состояние, поэтому настоящее переподключение даёт ровно одну новую попытку. Выход и повторный запуск applet тоже сбрасывают его, и это ручное переопределение. Ни один из путей не скрывает сбой; оба оставляют его видимым в Finder.
Скрипт не содержит пароля, и так должно остаться. Позвольте операции монтирования спросить, а связке ключей — делать то, что поддерживает организация. Встраивание учётных данных в URL превращает удобный скрипт в секрет, который нужно ротировать.
Что помощник не может
Три ограничения стоит записать рядом с applet. Он не может извлечь занятый том после сетевого сбоя, не может гарантировать, что DNS и сервер готовы, когда состояние говорит «подключено», и не реагирует на каждое переподключение.
Первое ограничение важнее всего на практике. Ресурс, сервер которого исчезает, оставляет том, который выглядит смонтированным и блокирует доступ, а вежливое исправление — завершить файловые операции и извлечь его до планового отключения. Второе объясняет большинство неудачных первых попыток: туннель поднят, пока резолвер ещё не догнал, поэтому подождите и затем один раз смонтируйте вручную для подтверждения. Третье — тот самый компромисс опроса, а не ошибка, которую нужно исправить.
Для машины без присмотра или управляемого парка эта схема имеет неправильную форму. Используйте политику монтирования, принадлежащую администратору, вместо расширения applet рабочего стола до привилегированной службы.