Klient VPN potrzebuje uprzywilejowanej pomocy do ponownej konfiguracji sieci, a ten fakt bywa stosowany zbyt szeroko do wszystkiego wokół. Skrypt montujący udział plikowy nie potrzebuje roota, ponieważ udział należy do sesji zalogowanego użytkownika i do jego poświadczeń. Przeniesienie montowania poza uprzywilejowaną ścieżkę usuwa potrzebę reguł sudo, haków root i modyfikacji dołączonych aplikacji. Zostaje mały, stale otwarty applet, który obserwuje jeden profil i wykonuje jedną próbę.

Dlaczego to należy do sesji użytkownika

Zamontowany wolumin jest właściwością sesji, która go zamontowała. Sesja innego użytkownika go nie widzi, a montowanie należące do roota zachowuje się inaczej niż to utworzone przez Findera. Utrzymanie montowania w sesji użytkownika zachowuje tę semantykę.

Uprzywilejowani pomocnicy istnieją dla tych części, które naprawdę ich potrzebują: tworzenia interfejsu tunelu, zmiany tras, aktualizacji resolvera. Montowanie udziału SMB nie jest jedną z tych części. Traktowanie go tak, jakby było, wymusza wybór między sudo bez hasła a skryptem root uruchamianym, gdy nikogo nie ma. Oba są większym ryzykiem, niż uzasadnia problem, a podejście sesji użytkownika całkowicie unika tego wyboru.

Własne haki połączenia Tunnelblick nie są tu zamiennikiem, ponieważ działają poza sesją pulpitu, a ich kolejność względem skryptów klienta nie jest zdefiniowana. Odpytywanie stanu z appletu użytkownika to mniejszy mechanizm z mniejszą liczbą założeń.

Najpierw udowodnij ręcznie, że udział działa

Automatyzacja nie dostarczy trasy, uprawnienia ani konta, które nie istnieje. Połącz się z VPN ręcznie i otwórz udział w Finderze, zanim napiszesz jakikolwiek skrypt. Jeśli to się nie uda, skrypt zawiedzie w bardziej mylący sposób.

Zapisz trzy wartości, których użyje skrypt: nazwę profilu dokładnie tak, jak wyświetla ją Tunnelblick, adres URL udziału i nazwę woluminu, którą Finder pokazuje po zamontowaniu. Nazwa woluminu ma znaczenie, ponieważ sprawdzenie istniejącego montowania jej używa, a sprawdzenie oparte tylko na nazwie jest wygodnym zabezpieczeniem, nie dowodem tożsamości serwera. Użyj nazwy unikalnej na maszynie. Następnie potwierdź, że serwer w ogóle odpowiada.

smbutil view //files.corp.example
osascript -e 'tell application "Tunnelblick" to get state of first configuration whose name is "Office"'
mount | grep -i smbfs

Pierwsze polecenie dowodzi, że serwer odpowiada, drugie, że nazwa profilu się rozwiązuje, a trzecie pokazuje, jak wygląda udane montowanie. Zapisz wszystkie trzy, zanim cokolwiek zautomatyzujesz.

Odczytaj stan profilu z Tunnelblick

Tunnelblick udostępnia swoje konfiguracje i ich stany przez AppleScript, i to jest jedyny hak, którego potrzebuje ten projekt. Stan, który się liczy, to ciąg zgłaszany dla tego jednego profilu, a nie obecność aplikacji.

Odpytywanie ma konsekwencje, które warto wymienić. Ponowne połączenie krótsze niż interwał może przejść niezauważone, a applet w ogóle nie widzi przejścia. To jest do przyjęcia dla strażnika montowania i nie do przyjęcia dla czegokolwiek, co musi reagować na każde zdarzenie. Jeśli potrzebujesz wierności zdarzeń, to jest zły mechanizm, a nie mechanizm wymagający krótszego timera. Wybierz interwał, mając ten kompromis na uwadze.

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

Wyeksportuj go jako aplikację z opcją pozostania otwartym, a następnie uruchom w zalogowanej sesji, a nie przez sudo.

Zamontuj raz, potem przestań próbować

Flaga próby jest tym, co nie pozwala temu stać się pętlą zgadującą poświadczenia. Gdy applet spróbuje, czeka na zmianę stanu połączenia, zanim spróbuje ponownie.

To zachowanie jest zamierzone. Udział, który odmawia montowania, zwykle odmawia z powodu, którego ponowna próba nie naprawi, a powtarzane próby zamieniają jedno zapytanie w ich strumień. Flaga jest resetowana, gdy profil opuszcza stan połączenia, więc prawdziwe ponowne połączenie daje dokładnie jedną nową próbę. Wyjście i ponowne uruchomienie appletu również ją resetuje, i to jest ręczne nadpisanie. Żadna z tych ścieżek nie ukrywa awarii; obie zostawiają ją widoczną w Finderze.

Skrypt nie zawiera hasła i tak powinno zostać. Pozwól operacji montowania zapytać, a pękowi kluczy rób to, co wspiera organizacja. Osadzenie poświadczenia w adresie URL zamienia skrypt wygody w sekret, który trzeba rotować.

Czego pomocnik nie potrafi

Trzy ograniczenia warto zapisać obok appletu. Nie potrafi wysunąć zajętego woluminu po awarii sieci, nie potrafi zagwarantować, że DNS i serwer są gotowe, gdy stan mówi połączono, i nie reaguje na każde ponowne połączenie.

Pierwsze ograniczenie ma w praktyce największe znaczenie. Udział, którego serwer znika, pozostawia wolumin, który wygląda na zamontowany i blokuje przy dostępie, a uprzejmą poprawką jest dokończenie operacji na plikach i wysunięcie przed planowanym rozłączeniem. Drugie wyjaśnia większość nieudanych pierwszych prób: tunel jest podniesiony, podczas gdy resolver jeszcze nie nadążył, więc poczekaj, a potem zamontuj raz ręcznie, aby to potwierdzić. Trzecie to omówiony wcześniej kompromis odpytywania, a nie błąd do naprawienia.

Dla maszyny bez nadzoru lub zarządzanej floty ten projekt ma niewłaściwy kształt. Użyj polityki montowania należącej do administratora, zamiast rozszerzać applet pulpitu w uprzywilejowaną usługę.

Powiązane artykuły