세 가지 질문이 이것을 결정하며, 오직 셋뿐입니다. 클라이언트가 재부팅 후에도 남는 연결 항목을 운영 체제에 만드는가? 인수 목록이 아닌 다른 곳에서 비밀을 받을 수 있는 명령줄을 제공하는가? 신원 요구가 사람에게 브라우저 프롬프트에 답하도록 강요하는가? 이 순서로 답하면 선택은 취향 문제가 아니게 됩니다. 예약된 작업은 세 답 중 가장 약한 것이 허용하는 만큼만 헤드리스일 수 있기 때문입니다.

클라이언트를 세 가지 스크립트 가능 계층에 맞추기

운영 체제 기본 프로필, 공급사 CLI, GUI만 있는 클라이언트, 브라우저 SSO 클라이언트에는 네 가지 다른 접근이 필요합니다. 앞의 둘은 무인 재부팅을 견디며, 무인 재부팅이 바로 핵심입니다. 나머지 둘은 스크립트보다 먼저 설계 결정이 필요합니다.

What the client exposesWhat to scriptWhat still bites
OS-native connection entryrasdial, scutil --nc, nmcliTunnel is up before DNS and routes settle
Vendor CLI reading stdinCLI wrapped by the scheduler, secret from the credential storePrompt text changes between releases
GUI onlyPinned version plus a state assertionLocale and DPI break the click targets

경로 하나: 프로필을 이미 운영 체제가 소유하는 경우

가장 저렴한 경로이며 대부분이 놓치는 경로입니다. Windows에서는 rasdial "Office" 이 연결하고 rasdial "Office" /disconnect 이 끊습니다. rasphone -d "Office" 은 같은 항목을 전화 접속 인터페이스로 구동합니다. macOS는 scutil --nc list 로 저장된 서비스를 나열하고 scutil --nc start 로 하나를 시작합니다. Linux는 이 일을 NetworkManager에 넘깁니다.

rasdial "Office" user *
scutil --nc start "Office"
nmcli connection up id Office
nmcli -t -f GENERAL.STATE connection show Office

이 인터페이스들은 운영 체제가 소유한 프로필만 알기 때문에 임의의 서드파티 클라이언트를 구동할 수 없습니다. 프로필이 없으면 한 번만 만들고, 매번 다시 만드는 대신 스크립트가 존재를 확인하게 하십시오. 스크립트를 멱등하게 만드십시오. 현재 상태를 읽고, 끊겼을 때만 연결하고, 그다음 작업이 실제로 필요로 하는 사설 이름을 검사하십시오.

경로 둘: 공급사가 명령줄을 제공하는 경우

일부 클라이언트는 감쌀 수 있을 만큼 명령줄을 노출합니다. Cisco AnyConnect는 오랫동안 연결 전용 도우미를 두었고, OpenConnect는 하나의 바이너리로 AnyConnect, GlobalProtect, Pulse 프로토콜을 말합니다. 중요한 요구는 플래그 목록이 아니라 비밀이 어디서 오는가입니다. 인수 목록의 비밀번호는 프로세스를 나열할 수 있는 누구나 읽을 수 있습니다.

printf '%s\n' "$VPN_PASS" | openconnect --protocol=anyconnect \
  --user "$VPN_USER" --passwd-on-stdin vpn.example.com

FortiClient와 일부 GlobalProtect 빌드에는 지원되는 CLI가 전혀 없으며, 커뮤니티 클라이언트나 공급사 라이선스 대체품은 구매 결정이지 우회가 아닙니다. CI에서는 서비스 계정에 셸이 아니라 바로 그 바이너리에 대한 권한을 주어, 주입된 인수가 root 명령이 되지 않게 하십시오.

경로 셋: GUI 자동화, 그리고 그것이 마지막인 이유

공식 클라이언트에 인터페이스가 없으면 스크립트는 창 메시지나 SendKeys로 버튼을 누릅니다. 이것은 버전과 언어에 취약하고, 반쯤 연결된 세션을 남길 수 있으며, 대화 상자가 잘못된 언어로 뜨면 조용히 실패합니다. 이 길을 택한다면 클라이언트 버전을 고정하고, 그 뒤에 결과 연결 상태를 확인하고, 수동 대체 절차를 스크립트 옆에 문서화해 두십시오.

프로세스를 죽여 클라이언트를 강제로 끊는 경우에도 같은 주의가 필요합니다. 터널이 프로세스보다 오래 살 수 있고, 감시자가 다시 시작할 수도 있으므로 죽이고 다시 시작하는 것도 신뢰할 만한 초기화가 아닙니다.

터널이 올라온 뒤에 깨지는 것

성공한 연결은 인증만 증명할 뿐 그 이상은 아닙니다. 작업이 존재하는 이유인 자원을 자체 프로토콜과 짧은 타임아웃으로 시험하고, 실패 메시지에 단계 이름을 넣으십시오. 데스크톱에서 보이는 프로필, 인증서, 저장된 자격 증명은 서비스 세션에서는 보이지 않을 수 있으므로, 믿기 전에 스케줄러 자체 계정으로 한 번 실행하십시오.

재시도를 제한하십시오. 거부된 자격 증명을 반복하는 루프는 계정을 잠그고, MFA 프롬프트는 등록 설계 없이는 헤드리스 작업이 답할 수 없습니다. 브라우저 SSO 흐름에 대한 스크립트 재시도는 시도만 태울 뿐입니다. 여러 대를 위해 MDM으로 배포하는 VPN 페이로드나 구성 프로파일을 선호하고, 그렇게 관리할 수 없는 클라이언트에만 스크립트를 남기십시오.

종료 코드와 처음 실패한 자원을 기록하십시오. 스크립트가 돌았다는 사실이 아닙니다. 그 한 줄이 스케줄러 경고를 오 분 진단으로 바꿉니다.

관련 글