미꾸라지 PAC (Proxy auto-config) 문법

Warning

이 문서는 미꾸라지 v3 (EOL (End Of Life) 된 구 버전) 프로그램에 대한 문서이며 미꾸라지 v3.6.1 버전까지만 유요한 문서입니다.

최신 미꾸라지 버전은 v4 이며 http://mudfish.net/ 에서 다운로드 받으실 수 있습니다.

Note

문서에 오류가 있거나 건의 사항이 있으시면 메세지를 미꾸라지 포럼 (http://forums.loxch.com) 에 남겨주세요.

미꾸라지의 웹 가속 서비스는 WPAD(Web Proxy Auto-Discovery) 프로토콜을 기반으로 실행이 되는데, 그 중 PAC (Proxy auto-config) 파일 포맷에 따라 작동을 하게 됩니다.

Note

여기에 언급된 예제나 설명들은 아래의 사이트의 내용을 번역하거나 참고하여 작성되었습니다.

WPAD(Web Proxy Auto-Discovery) 소개

Web Proxy Auto-Discovery (WPAD) 프로토콜은 DHCP 혹은 DNS discovery 방법을 사용하여 사용자가 설정 파일의 URL 위치를 알 수 있도록 하는 방법중에 하나인데요, 이것이 작동하게 되면 브라우저는 자동으로 설정 파일을 다운로드 받아서 특정 URL 혹은 호스트에 대한 proxy 설정을 하게 됩니다. 사실 WPAD 프로토콜은 설정 파일을 어떻게 발견할 수 있을 까하는 방법론에 관한 것이 대부분이고 실제 설정 파일 포맷에 대허는 Proxy auto-config format 이 사용됩니다. 참고로 PAC 파일 포멧은 정말 옛날 브라우저인 Netscape Navigator 에서 처음 소개되었습니다.

쉽게 따라하는 PAC 포맷 예제들

처음 미꾸라지 UI 의 ‘설정 -> WPAD’ 메뉴에 들어가시면 아래와 같이 기본 설정이 들어가 있는데요, 이 내용을 수정하고 자신이 원하는 사이트를 넣음으로써 가속 적용 여부를 정할 수 있습니다.

/*
 * 이 예제는 사용자가 아무런 rule 을 설정하지 않았을 때 나타나는 기본
 * 설정 파일입니다.
 */
function FindProxyForURL(url, host) {
    /* 모든 요청을 PROXY (SOCKS) 서버를 거치지 않고 직접 연결합니다. */
    return "DIRECT";
}

예를 들어, 던전 파이터 홈페이지 (http://df.nexon.com) 와 블러드앤소울 홈페이지 (http://bns.plaync.com) 에 접속하는 부분을 미꾸라지 중계 서버 KT IDC (PROXY 서버 주소는 10.255.96.1 이고 HTTP proxy 의 경우 포트 8080, SOCKS proxy 의 경우 8081 로 이용가능합니다.) 노드를 통해 접속하고 나머지는 모두 직접 접속하고 싶을때는 아래와 같이 설정할 수 있습니다. (참고로 주석은 모두 제거하였습니다.)

function FindProxyForURL(url, host) {
    if (shExpMatch(host, "df.nexon.com"))
        return "PROXY 10.255.96.1:8080";
    if (shExpMatch(host, "bns.plaync.com"))
        return "SOCKS 10.255.96.1:8081";
    return "DIRECT";
}

그럼 반대의 경우도 생각해 볼 수 있는데요, 특정 페이지를 제외한 모든 접속을 미꾸라지 특정 노드를 통해 접속하도록 할 수 있습니다.

function FindProxyForURL(url, host) {
    /*
     * 127.0.0.1 주소는 반드시 예외 처리를 해주셔야 합니다.  왜냐하면
     * 해당 주소는 Mudfish Launcher 가 사용하는 주소 중의 하나이기
     * 때문입니다.
     */
    if (shExpMatch(host, "localhost") ||
        shExpMatch(host, "127.0.0.1"))
        return "DIRECT";
    return "PROXY 10.255.96.1:8080";
}

Warning

모든 요청을 HTTP 혹은 SOCKS proxy 을 거치도록 설정을 하고 싶다면 반드시 127.0.0.1 주소와 localhost 주소는 예외 처리해 주셔야 합니다. 그렇지 않으면 브라우저 상에서 작동하는 MUDFISH Launcher 가 제대로 동작하지 않을 수 있습니다.

기타 아래의 각각 함수들의 사용법을 통해서 좀 더 유연하게 웹 페이지들의 주소를 설정할 수 있습니다.

PAC 함수들

PAC 포맷을 지원하는 브라우저들은 보통 Netscape 사에 지정한 표준 포맷에서 제시된 함수들을 지원하도록 되어 있습니다.

하지만 보통 이러한 기능들은 sandbox 내에서 작동하기 때문에 엄격히 제한된 환경에서 실행되게 됩니다. 예를 들어 User Agent 정보를 살펴본다거나 하는 행위가 원천 봉쇄되어 있습니다.

아래는 sandbox 환경내에서 허용되는 함수에 대해서 기술을 하였습니다.

dnsDomainIs

Hostname 을 검사해서 서로 매치된다면 true 을 리턴하게 됩니다. 보통 예외적인 개별 hostname 을 검사할 때 사용됩니다.

// 만약 hostname 이 google.com 과 같거나 하위 주소들이 매치된다면
// (예를 들어 maps.google.com, www.google.com),
// 브라우저로 하여금 proxy 을 거치지 않고 직접 접속하게 합니다.

if (dnsDomainIs(host, "google.com"))
    return "DIRECT";

shExpMatch

Hostname 혹은 URL 을 shell 표현식으로 지정된 문자열과 비교를 하여 매치가 된다면 true 을 리턴합니다.

// 모든 request 들 (.local 로 끝나는 모든 hostname 에 해당) 이
// 브라우저로 하여금 proxy 을 거치지 않고 직접 접속하게 합니다.

if (shExpMatch(url, "*.local"))
    return "DIRECT";

// vpn.domain.com 에 접속할려고 하거나
// http://abcdomain.com/folder/ 하위의 모든 폴더 혹은 파일에 접속하는
// 요청들을 proxy 경유없이 직접 접속합니다.

if (shExpMatch(host, "vpn.domain.com") ||
    shExpMatch(url, "http://abcdomain.com/folder/*"))
    return "DIRECT";

isInNet

이 함수는 hostname 의 IP address 를 검사해서 특정 subnet 하에 존재할 경우, true 을 리턴합니다. 만약 hostname 이 인자로 넘겨진다면 DNS resolving 을 통해서 IP 변환 작업을 하게 됩니다.

// 만약 요청한 hostname 의 IP 주소가 (DNS resolving 후) 인자로 넘겨진
// IP 대역에 포함되는 것이면 직접 접속합니다.

if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0"))
    return "DIRECT";

myIpAddress

현재 나의 컴퓨터의 IP 주소를 반환합니다.

// 만약 나의 컴퓨터가 특정 IP 대역에 속할 경우 proxy 10.10.5.1 (포트는 8080)
// 를 통해 요청하도록 합니다.

if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0"))
    return "PROXY 10.10.5.1:8080";

dnsResolve

DNS resolving 을 통해서 hostname 을 IP 주소로 변환합니다.

// 만약 요청한 host 의 IP 가 지정한 범위에 속할 경우 직접 접속하도록
// 합니다.

if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
    isInNet(dnsResolve(host), "172.16.0.0",  "255.240.0.0") ||
    isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
    isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0"))
    return "DIRECT";

isPlainHostName

만약 hostname 이 아무런 . (dot) 문자를 포함하지 않을 경우 true 을 반환합니다. 예를 들면 http://intranet 와 같은 것을 말하는데요, 보통 내부망 웹 주소에 접근할 경우 사용될 수 있습니다.

// 만약 사용자가 plain hostname (예를 들면, http://intranet/ 혹은
// http://webserver-name01/) 를 요청할 경우, 직접 접속하도록 합니다.

if (isPlainHostName(host))
    return "DIRECT";

localHostOrDomainIs

Hostname 을 검사해서 hostname 부분이 서로 일치할 경우 true 을 반환합니다.

// 만약 요청한 hostname 이 "www" 혹은 "www.google.com" 일 경우, 직접
// 접속합니다.

if (localHostOrDomainIs(host, "www.google.com"))
    return "DIRECT";

isResolvable

Hostname 을 IP 주소로 변환을 해서 성공적이면 true 을 반환합니다.

Warning

만약 domain 주소가 resolving 이 제대로 안될 경우 브라우저 자체가 잠깐 얼어 버릴 수 있습니다. (멈출 수 있습니다). 주의 깊게 사용하셔야 합니다.

// 만약 요청한 hostname 이 DNS 서버로 부터 resolving 이 될 수 있다면,
// proxy1.example.com 프록시를 통해 요청합니다.

if (isResolvable(host))
    return "PROXY proxy1.example.com:8080";

dnsDomainLevels

Hostname 을 검사해서 해당 문자열에 몇 개의 . (dot) 이 존재하는지 반환합니다. 예를 들면 내부망 웹서버를 예외로 지정할 때 사용될 수 있습니다.

// 만약 hostname 이 . (dot) 을 하나라도 포함하고 있으면 proxy1.example.com
// 프록시를 통해 접속하고 그렇지 않으면 직접 접속합니다.

if (dnsDomainLevels(host) > 0)
    return "PROXY proxy1.example.com:8080";
else
    return "DIRECT";

weekdayRange

시간을 기준으로 rule 을 생성할 때 사용될 수 있는데요, 예를 들면 특정 날에만 proxy 설정을 반환하도록 하고 싶을 때 사용될 수 있습니다.

// 만약 월요일부터 금요일 사이에는 proxy1.example.com 프록시를 사용하도록
// 하고 그렇지 않을 경우는 직접 인터넷에 접속하도록 합니다.

if (weekdayRange("MON", "FRI"))
    return "PROXY proxy1.example.com:8080";
else
    return "DIRECT";

dateRange

시간을 기준으로 rule 을 생성할 때 사용될 수 있는데요, 예를 들면 특정 달에만 proxy 적용을 하고 싶을 때 사용될 수 있습니다.

// 만약 1월부터 3월까지는 proxy1.example.com 프록시를 사용하도록 설정하고
// 그렇지 않을 경우는 직접 접속하도록 조치합니다.

if (dateRange("JAN", "MAR"))
    return "PROXY proxy1.example.com:8080";
else
    return "DIRECT";

timeRange

특정 시간대에서만 proxy 를 사용하게끔 하고 싶을 때 사용될 수 있습니다.

// 오직 아침 8 시부터 오후 6 시까지만 proxy1.example.com 을 사용하도록
// 하고 그렇지 않을 경우는 직접 접속합니다.

if (timeRange(8, 18))
    return "PROXY proxy1.example.com:8080";
else
    return "DIRECT";

alert

이 함수의 경우 처음 PAC 포맷이 정의되었을 때는 없었지만, troubleshooting 을 하기 위해서 Internet Explorer 와 Firefox 브라우저의 경우 정의가 되어 있는 함수입니다.

// 브라우저의 error 콘솔창에 DNS resolving 한 결과를 출력하도록 합니다.

resolved_host = dnsResolve(host);
alert(resolved_host);