«호스트가 이 PAC 파일을 사용하니 같은 URL을 VM에 넣었다»는 합리적인 문장이자 불완전한 계획이다. PAC URL은 프록시가 아니라 정책 스크립트를 가리킨다. 게스트가 그 스크립트를 가져와 게스트 자신의 주소로 평가하고 스크립트가 지목하는 프록시에 도달할 수 있을 때까지, URL은 설정 필드 안의 문자열일 뿐이다. 가상 머신의 프록시 정책을 둘러싼 혼란의 대부분은 그 한 줄을 전체 구성으로 취급하는 데서 온다.

PAC URL은 스크립트이며 프록시가 아니다

파일에는 URL과 호스트를 받아 프록시 설명이나 DIRECT라는 단어를 반환하는 함수가 들어 있다. URL 어디에도 애플리케이션에 트래픽을 어디로 보낼지 알려 주는 것이 없으며, 그 결정은 런타임에, 스크립트 안에서, 스크립트가 플랫폼에 요청하는 데이터를 사용해 내려진다. PAC URL을 받아들이는 설정 대화 상자는 결정 절차를 가리키는 포인터를 받아들이는 셈이다.

그 구분 때문에 URL을 복사하는 것이 성공한 것처럼 보일 수 있다. 필드는 채워지고 설정은 저장되며, 실패는 나중에야, 스크립트를 가져올 수 없을 때나 게스트가 도달할 수 없는 프록시를 반환할 때에야 드러난다.

네 단계는 각각 다른 방식으로 실패한다

게스트 내부에서는 네 가지 일이 순서대로 일어나야 하고, 각각 고유한 오류 흔적이 있다. 게스트가 PAC 파일을 가져온다. 애플리케이션이 로컬 정보를 사용해 요청된 URL에 대한 스크립트를 평가한다. 선택된 프록시가 확인되고 그곳에 도달한다. 프록시가 요구하면 인증이 일어난다.

가져오기를 증명하는 것부터 시작하라, 그것이 없으면 이후의 모든 것은 무의미하다. 사설 서버의 PAC 파일은 어떤 규칙도 도움이 되기 전에 그 서버로 가는 허용된 경로가 필요하며, 도달할 수 없는 스크립트 안의 프록시 선택은 그것을 가져올 경로를 만들 수 없다:

curl -sS -o /dev/null -w '%{http_code}\n' http://pac.corp.example/proxy.pac
getent hosts pac.corp.example

그 요청이 게스트에서는 실패하고 호스트에서는 성공한다면, 문제는 스크립트의 내용이 아니라 게스트에서 PAC 서버로 가는 경로다. JavaScript 파일을 반환한다면 두 번째 단계로 가서 스크립트가 게스트의 상황에 대해 무엇을 결정하는지 알아내라.

같은 스크립트가 VM 안에서는 다르게 결정한다

PAC 함수는 요청된 호스트와 평가를 수행하는 머신에 대한 정보를 검사할 수 있다. 클라이언트 자신의 주소를 바탕으로 만든 규칙, 예를 들어 인터페이스 주소나 서브넷 소속을 확인하는 규칙은 물리적 호스트의 주소가 아니라 게스트의 주소를 보게 된다. 호스트 측 NAT 뒤에서는 이 둘이 다른 주소이므로, 같은 스크립트가 VM 안에서 다른 프록시를 고르거나 DIRECT로 되돌아갈 수 있다.

이것은 스크립트의 결함이 아니다. 스크립트는 원래 목적대로 다른 입력을 받아 동작하고 있을 뿐이며, 그것이 호스트는 프록시를 쓰고 게스트는 직접 연결한다는 혼란스러운 보고를 설명한다. 결정에 대해 추론하지 말고, 주소와 URL을 받는 PAC 평가기가 배포판에 들어 있다면 그것으로 재현해 한 명령으로 정리하라. 그렇지 않다면 실제로 사용될 애플리케이션으로 시험하고, 추측하는 대신 그 프록시 로그를 읽어라.

게스트가호스트의 프록시 설정을 물려받았다고결론 내리지 마라, 그 트래픽이 호스트 측 변환을 거칠 뿐이기 때문이다. 네트워크 변환은 패킷을 전달하지만 애플리케이션 구성을 복사하지 않으며, 시스템 프록시는 애플리케이션 구성이다.

PAC을 전혀 읽지 않는 도구

명령줄 도구는 별개의 경계이며, 바로 여기서 많은 시간이 낭비된다. curl은 PAC 파일을 실행하지 않는다고프록시 문서가 분명히 말한다. 프록시 변수를 PAC 다운로드 URL로 지정한다고 해서 스크립트가 프록시 종점이 되는 것은 아니며, 도구는 JavaScript 파일과 HTTP로 대화하려다 네트워크 문제처럼 보이는 방식으로 실패한다.

같은 말이 명시적 프록시 변수나 자체 구성만 따르는 많은 패키지 관리자, 언어 런타임, 빌드 도구에도 해당한다. 관심 있는 시험이 CLI 도구라면, PAC 스크립트가 골랐을 구체적 프록시로 그것을 구성하고, 그 선택에 어떻게 이르렀는지 기록해 다음 사람이 재현할 수 있게 하라.

Linux의 데스크톱 애플리케이션에서는 시스템 설정을 자동 모드로 두고 URL도 주어야 한다. 모드가 아직 수동일 때 저장한 URL은 아무것도 하지 않으므로, 둘 다 게스트 내부에서 확인하라:

gsettings get org.gnome.system.proxy mode
gsettings get org.gnome.system.proxy autoconfig-url

DIRECT도 결정이다

PAC 결과가 DIRECT라는 것은 애플리케이션이 HTTP 프록시를 우회한다는 뜻이며, 네트워크를 벗어났다는 뜻이 아니다. 그 결과 연결은 여전히 터널을 지나는 운영체제 경로를 따를 수도 있고, 프록시 사용과 아무 관련이 없는 이유로 실패할 수도 있다. 반대로 프록시 결과는 한 애플리케이션의 요청을 설명하며, 게스트의 모든 프로세스를 설명하지는 않는다.

그러므로 요구사항이 쓰인 방향으로 검증하라. 요구사항이 «이 애플리케이션이 내부 사이트에 도달한다»라면 그 애플리케이션이 도달함을 증명하고, 어느 프록시나 경로가 그것을 실어 날랐는지 기록하라. 요구사항이 «VM이 기업 네트워크에 있다»라면 선택된 프록시를 통해 동작하는 브라우저는 그 브라우저에 대한 증거일 뿐이다.

시험을 통과시키려고 호스트의 터널을 끄거나 전달 정책을 느슨하게 하는 대신 게스트 내부에서 사슬을 고쳐라. 사슬에는 네 개의 고리가 있고, 그중 하나를 건너뛰는 변경은 다음에 스크립트가 갱신되거나 게스트의 주소가 바뀔 때까지만 유지된다.

관련 글