터미널에서 scutil --nc로 저장된 Mac VPN 시작하기
scutil --nc로 저장된 macOS VPN 서비스를 시작, 검사, 중지하고 자격 증명을 argv 밖에 두며 트래픽이 실제로 터널을 사용하는지 증명하십시오.
시스템 설정에 저장된 VPN 서비스가 있고, 터미널로 그것을 시작하려고 합니다. macOS에서 지원되는 경로는 scutil --nc이지만, 시스템 자체의 네트워크 연결 관리자가 소유한 서비스에만 해당합니다. 메뉴 막대는 API가 아닙니다: 타사 클라이언트는 보통 자체 자동화를 갖고 있고, 관리 서비스가 배포한 프로파일은 로컬 시작을 거부할 수 있습니다. 제가 실행하는 체크리스트는 이렇습니다: 정확한 서비스를 찾고, 상태를 읽고, 시작하고, 상태가 바뀌기를 기다린 다음, 트래픽이 실제로 터널을 사용하는지 증명합니다. 맞지 않는 첫 단계에서 멈추십시오. 이후 명령은 모두 앞 단계가 성공했다고 가정하기 때문입니다.
시작을 시도하기 전에 서비스를 찾으십시오
기억하는 프로파일 이름이 아니라 목록에서 시작하십시오:
scutil --nc help
scutil --nc list
각 줄은 상태를 서비스 식별자, 유형, 표시 이름과 짝짓습니다. 표시 이름은 중복되고 편집될 수 있으므로 스크립트가 상대할 값은 식별자입니다. Apple의 scutil 매뉴얼은 네트워크 연결 모드를 문서화하고, 설치된 --nc help는 그 Mac에서 하위 명령의 권위 있는 목록이며, 오래된 안내서의 플래그가 아직 macOS 버전에 있다고 가정하지 마십시오.
빈 목록은 결과이며 오류가 아닙니다. 공급업체 클라이언트나 관리 프로파일이 만든 서비스는 여기 보이지 않으면서 활성일 수 있고, 네이티브 컨트롤러가 다룰 수 없는 유형으로 보일 수도 있습니다. 그런 경우 공급업체 도구나 프로파일 문서를 사용하십시오. 시작할 대상이 있으려고 병렬 네이티브 프로파일을 만드는 것은 나쁜 거래입니다.
현재 상태를 읽고 선택자를 확인하십시오
시작하기 전에 서비스에 상태를 물어, 성공한 시작이 무엇을 바꿔야 하는지 알아 두십시오:
scutil --nc status "Office VPN"
두 서비스가 표시 이름을 공유하면 이름이 모호합니다. 대신 식별자를 전달하십시오; 명령은 둘 다 받지만 서비스 하나를 확실히 선택하는 것은 식별자뿐입니다. 스크립트에서 해석하기 전에 상태 단어가 아는 것인지 확인하십시오: 보통 Connected, Disconnected, Connecting, Disconnecting입니다. 프로파일이 관리되는지도 확인하십시오; 잠긴 구성은 명령을 받아들이고도 무시하거나 확인을 요청할 수 있습니다.
이 상태 호출은 저렴하므로 자동화의 가드로 사용하십시오: 상태가 Disconnected일 때만 시작하고 Connecting을 실패로 보지 마십시오. 서비스가 이미 Connected라면 작동 중인 터널을 끊지 말고 시작을 건너뛰십시오.
연결을 시작하고 상태가 안정될 때까지 기다리십시오
시작 요청은 비동기입니다. 명령은 요청이 수락되었을 때 돌아오며, 인증이 끝났거나 경로가 설치되었을 때가 아닙니다. 실행한 뒤 제한된 대기로 상태를 조회하고 서비스가 Disconnected로 돌아가면 빠져나오십시오:
scutil --nc start "Office VPN"
n=0
while [ "$n" -lt 30 ]; do
state=$(scutil --nc status "Office VPN" | head -n 1)
[ "$state" = "Connected" ] && break
[ "$state" = "Disconnected" ] && { echo "start failed"; exit 1; }
sleep 2
n=$((n + 1))
done
해결되지 않는 Connecting 상태는 보통 자격 증명, MFA 또는 서버를 가리키며 scutil이 아닙니다. 명령은 대화형 로그인을 제공할 수 없으므로 토큰이나 하드웨어 키를 기대하는 프로파일은 Connecting에 머물다 결국 되돌아갑니다. 재시도를 추가하기 전에 상태 단어를 읽으십시오; 인증 프롬프트에 대한 루프는 성공할 수 없습니다.
셸의 종료 상태를 준비 완료로 보지 마십시오. 유용한 신호는 상태 문자열이며, 그 뒤에 터널이 트래픽을 운반한다는 증거가 따릅니다. 조용히 돌아오는 시작 명령도 결코 인증되지 않는 연결을 남길 수 있습니다.
터널이 트래픽을 운반함을 증명하십시오, Connected라고 말하는 것만으로는 부족합니다
Connected는 연결을 설명하며 라우팅 결정이 아닙니다. 네이티브 PPP와 IKEv2 서비스는 ppp 또는 utun 인터페이스를 만들고 경로를 설치하며, 분할 터널은 기본 경로를 의도적으로 그대로 둡니다. 인터페이스와 두 주소 체계를 검사하십시오:
ifconfig -l
netstat -rn -f inet
netstat -rn -f inet6
scutil --dns
번호를 추측하지 말고 서비스가 만든 인터페이스를 찾은 다음, 특정 목적지가 어느 인터페이스를 쓰는지 라우팅 테이블에 물으십시오: route -n get 10.0.0.10 부분은 내부 호스트로 바꿉니다. 물리 인터페이스를 보고하면 터널은 올라가 있지만 그 흐름을 운반하지 않습니다. 분할 터널 경로, 리졸버 순서, 터널 인터페이스는 허용하지만 프로세스는 허용하지 않는 로컬 방화벽 규칙을 확인하십시오.
이름 해석이 흔한 거짓 음성입니다. 터널이 완전히 건강해도 내부 이름이 잘못된 리졸버로 해석될 수 있으며, 이는 VPN 장애처럼 보이지만 장애가 아닙니다. scutil --dns는 macOS가 사용할 순서를 보여줍니다; 리졸버를 바꾼 뒤에는 dscacheutil -flushcache와 sudo killall -HUP mDNSResponder로 캐시를 비우십시오.
자격 증명과 권한을 명령줄에서 멀어지게 하십시오
비밀번호, 사전 공유 키 또는 토큰을 인수에 넣지 마십시오. 인수는 프로세스 목록에 보이고 셸 기록에 남으며, 복사된 지원 기록이 이를 유출할 수 있습니다. 프로파일 자체의 자격 증명 처리, 즉 Keychain 항목, 시스템 프롬프트 또는 클라이언트의 인증 흐름이 비밀을 둘 곳입니다.
sudo로 명령을 실행해도 대화형 로그인이 무인 감독 없이 되지는 않습니다. 바뀌는 것은 유효 사용자이며 GUI 프롬프트, 하드웨어 토큰, 로그인 Keychain의 가용성이 아닙니다. LaunchAgent는 사용자가 로그인하고 Keychain이 잠금 해제된 뒤 서비스를 시작할 수 있습니다; LaunchDaemon은 보통 사용자 세션의 그 부분에 닿지 못합니다. 조직이 서비스를 관리하면 그 수명 주기 규칙이 어떤 로컬 스크립트보다 우선합니다.
서비스를 중지하고 중지된 채로 남았는지 확인하십시오
시작할 때 쓴 것과 같은 선택자로 중지한 다음, 터널이 사라졌다고 가정하지 말고 상태를 다시 읽으십시오:
scutil --nc stop "Office VPN"
scutil --nc status "Office VPN"
Disconnected로 돌아오는 중지도 확인할 것이 하나 남습니다: 프로파일이 요청 시 연결로 설정되어 있으면 스크립트 없이도 다시 올라올 수 있습니다. 같은 Mac에서 다른 클라이언트가 경로를 소유하고 있으면 그 경로는 네이티브 중지 후에도 살아남을 수 있습니다. 머신이 VPN 밖에 있다고 결론 내리기 전에 경로 확인을 다시 실행하십시오.
직접 실행하는 래퍼라면 순서를 고정하십시오: 목록, 상태, 시작, 조회, 경로 테스트, 중지, 확인. 식별자를 사용할 수 있을 때 자유 형식 출력에서 친숙한 이름을 해석하지 말고, 시작 명령의 종료를 준비 완료로 보지 마십시오. 연결 관리자는 상태를 보고합니다; 당신의 증거는 상태와 터널을 가리키는 경로입니다.