VPN 클라이언트는 네트워크를 다시 구성하려면 권한 있는 도움을 받아야 하고, 그 사실이 주변의 모든 것에 지나치게 넓게 적용됩니다. 파일 공유를 마운트하는 스크립트에 root가 필요 없는 것은, 공유가 로그인한 사용자의 세션과 그 사용자의 자격 증명에 속하기 때문입니다. 마운트를 권한 있는 경로에서 빼내면 sudo 규칙, root 훅, 함께 배포되는 앱 편집이 필요 없어집니다. 남는 것은 열린 채로 하나의 프로필을 감시하고 한 번만 시도하는 작은 애플릿입니다.

이것이 사용자 세션에 속하는 이유

마운트된 볼륨은 그것을 마운트한 세션의 속성입니다. 다른 사용자의 세션에서는 보이지 않고, root 소유의 마운트는 Finder가 만든 것과 다르게 동작합니다. 마운트를 사용자 세션에 두면 그 의미가 유지됩니다.

권한 있는 도우미는 정말로 필요한 부분, 곧 터널 인터페이스 생성과 경로 변경, 리졸버 갱신을 위해 존재합니다. SMB 공유 마운트는 그런 부분이 아닙니다. 그런 것처럼 다루면 비밀번호 없는 sudo와 아무도 없을 때 실행되는 root 스크립트 중 하나를 골라야 합니다. 둘 다 문제가 정당화하는 것보다 큰 위험이며, 사용자 세션 방식은 그 선택 자체를 피합니다.

Tunnelblick 자체의 연결 훅은 데스크톱 세션 밖에서 실행되고 클라이언트 스크립트와의 순서가 정의되어 있지 않으므로 여기서 대안이 되지 못합니다. 사용자 애플릿에서 상태를 조회하는 쪽이 가정이 더 적은 작은 메커니즘입니다.

먼저 손으로 공유가 되는지 확인하기

자동화는 존재하지 않는 경로나 권한, 계정을 제공할 수 없습니다. 스크립트를 쓰기 전에 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를 통해 구성과 그 상태를 노출하며, 이것이 이 설계에 필요한 유일한 훅입니다. 중요한 상태는 바로 그 프로필에 대해 보고되는 문자열이며, 앱의 존재 여부가 아닙니다.

조회에는 언급할 만한 대가가 따릅니다. 간격보다 짧은 재연결은 지나쳐 버릴 수 있고, 애플릿은 그 전환을 전혀 보지 못합니다. 마운트 감시에는 받아들일 수 있지만 모든 이벤트에 반응해야 하는 무엇에도 받아들일 수 없습니다. 이벤트 충실도가 필요하다면 이것은 간격을 줄일 메커니즘이 아니라 잘못된 메커니즘입니다. 그 절충을 염두에 두고 간격을 고르십시오.

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가 아니라 로그인한 세션에서 실행하십시오.

한 번 마운트하고 나면 시도를 멈추기

‘시도함’ 플래그가 이것을 자격 증명을 추측하는 루프로 만들지 않게 막는 장치입니다. 애플릿은 한 번 시도한 뒤에는 연결 상태가 바뀔 때까지 기다렸다가 다시 시도합니다.

그 동작은 의도된 것입니다. 마운트를 거부하는 공유는 보통 재시도로 고칠 수 없는 이유로 거부하며, 반복 시도는 한 번의 프롬프트를 연속된 프롬프트로 바꿉니다. 프로필이 연결 상태를 떠날 때 플래그가 초기화되므로, 실제 재연결은 정확히 한 번의 새 시도를 만듭니다. 애플릿을 종료하고 다시 실행해도 초기화되며, 그것이 수동 개입 지점입니다. 어느 경로도 실패를 숨기지 않으며, 둘 다 Finder에 실패를 남깁니다.

스크립트는 어떤 비밀번호도 담지 않으며 그렇게 남아야 합니다. 마운트 작업이 물어보게 하고, 키체인이 조직이 지원하는 일을 하게 두십시오. 자격 증명을 URL에 넣으면 편의 스크립트가 교체해야 하는 비밀이 됩니다.

도우미가 할 수 없는 일

세 가지 한계를 애플릿 옆에 적어 둘 만합니다. 네트워크 장애 후 사용 중인 볼륨을 꺼낼 수 없고, 상태가 연결됨이라고 해도 DNS와 서버가 준비되었다고 보장할 수 없으며, 모든 재연결에 반응하지는 않습니다.

첫 번째 한계가 실무에서 가장 중요합니다. 서버가 사라진 공유는 마운트된 것처럼 보이면서 접근 시 멈추는 볼륨을 남기고, 정중한 대처는 예정된 연결 해제 전에 파일 작업을 끝내고 볼륨을 꺼내는 것입니다. 두 번째는 대부분의 첫 시도 실패를 설명하는데, 터널은 올라갔는데 리졸버가 아직 따라오지 못했으므로 기다렸다가 한 번 직접 마운트해 확인하십시오. 세 번째는 앞서 말한 조회의 절충이며 고쳐야 할 버그가 아닙니다.

무인 머신이나 관리되는 플리트에는 이 설계가 맞지 않습니다. 데스크톱 애플릿을 권한 있는 서비스로 확장하는 대신 관리자가 소유한 마운트 정책을 쓰십시오.

관련 글