PAC: различия между версиями

Материал из ALT Linux Wiki
Строка 104: Строка 104:


====isInNet====
====isInNet====
This function evaluates the IP address of a hostname, and if within a specified subnet returns true. If a hostname is passed the function will resolve the hostname to an IP address.
Данная функция определяет IP-адрес имени хоста и, если он находится в пределах указанной подсети, возвращает true. Если передается имя хоста, то функция преобразует его в IP-адрес.
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
// If IP of requested website website falls within IP range, send direct to the Internet.  
// Если IP-адрес запрашиваемого сайта попадает в указанный диапазон IP-адресов, то происходит перенаправление в Интернет.  
if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0"))  
if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0"))  
     return "DIRECT";
     return "DIRECT";

Версия от 17:49, 24 ноября 2023

Введение

Файлы Proxy Auto-Config (сокращенно PAC-файлы) и поддерживающие их браузеры были впервые созданы компанией Netscape в 1995-1996 гг. для обеспечения большей гибкости при перенаправлении трафика веб-браузера через прокси-сервер, расположенный выше по маршруту сети.

Возможности того времени позволяли пользователю или ИТ-администратору настраивать браузер на пересылку трафика через прокси-сервер, явно определяя хост, порт и список явных исключений или протоколов. Хотя это было весьма полезно, такая конфигурация не поддерживала и до сих пор не поддерживает переключение между прокси-серверами и не имеет какого-либо разумного управления трафиком. Например, если прокси содержит IP-адрес сервера, а пользователь вводит полное доменное имя (FQDN), указывающее на этот IP-адрес, то совпадения не будет, и трафик все равно пойдет через прокси.

Вместо того чтобы определять правила переадресации прокси непосредственно в самом браузере, компания Netscape выбрала в качестве основы язык программирования JavaScript, основанный на стандартах, и создала набор гибких функций на базе JavaScript, которые можно использовать в файле, обычно предоставляемом веб-сервером (хотя он мог распологаться и на локальной файловой системе), определяющем набор правил для веб-браузера по переадресации веб-трафика через прокси. Это позволяет управлять трафиком браузера из единого централизованного файла без необходимости вносить изменения на каждое пользовательское устройство.

В Netscape были реализованы функции, позволяющие создавать правила для FQDN, URL и IP-адресов, к которым осуществляется доступ, а также вспомогательные функции для преобразования FQDN в IP-адрес, определения принадлежности IP-адреса к определенной подсети, а также менее распространенные возможности, поддерживающие правила на основе даты и времени и IP-адреса устройства. Кроме того, с помощью PAC-файлов можно настроить несколько прокси-серверов для резервирования и восстановления работоспособности.

Благодаря этим возможностям пользователь или администратор может легко перенаправлять трафик на вышестоящий прокси-сервер, автоматически обходить трафик локальной сети, а также реализовать обход отказа между прокси-серверами.

Пример PAC-файла

PAC-файлы, написанные на языке JavaScript, могут быть очень мощными, но эти возможности также могут привести к усложнению и раздуванию кода, поэтому рекомендуется разрабатывать PAC-файл, постоянно помня о двух вопросах:

  • Какой трафик должен и не должен передаваться через прокси?
  • Будет ли текущая и будущая поддержка PAC-файла осуществляться людьми, имеющими опыт работы с JavaScript?

Особенности файла PAC

  • Правила обхода прокси-сервера для частных IP-сетей, внутренних имен хостов и хостов с расширением домена .local.
  • Пример правила обхода имени хоста.
  • Пример правила обхода протоколов и URL.
  • Пример правила обхода IP-маршрутизации на основе машин.
  • Правило обхода прокси по умолчанию, если все вышеперечисленные правила не подходят.

Пример файла PAC

Приведенный ниже пример PAC-файла демонстрирует свою гибкость, разборчивость и простоту обновления. Такие простые блоки кода могут служить примером того, что они могут быть скопированы, отредактированы и созданы людьми с ограниченным опытом работы с JavaScript.

function FindProxyForURL(url, host) { 
// If the hostname matches, send direct. 
    if (dnsDomainIs(host, "intranet.domain.com") || 
        shExpMatch(host, "(*.abcdomain.com|abcdomain.com)")) 
        return "DIRECT"; 

// If the protocol or URL matches, send direct. 
    if (url.substring(0, 4)=="ftp:" || 
        shExpMatch(url, "http://abcdomain.com/folder/*")) 
        return "DIRECT"; 

// If the requested website is hosted within the internal network, send direct. 
    if (isPlainHostName(host) || 
        shExpMatch(host, "*.local") || 
        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"; 

// If the IP address of the local machine is within a defined 
// subnet, send to a specific proxy. 
    if (isInNet(myIpAddress(), "10.10.5.0", "255.255.255.0")) 
        return "PROXY 1.2.3.4:8080"; 

// DEFAULT RULE: All other traffic, use below proxies, in fail-over order. 
    return "PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080"; }

Рекомендации

При развертывании правил для URL и хостов необходимо следить за тем, чтобы правила были как можно более явными. В приведенных ниже примерах подробно описано, как должны быть реализованы правила для хостов и URL.

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

Предостережения

Приведенный ниже код является примером, который может иметь непредвиденные последствия из-за широкой интерпретации при использовании функции shExpMatch с подстановочными знаками и именами хостов.

// Would send both of the following requests direct to the Internet:
// 1. www.hotmail.com 2. phishing-scam.com?email=someone@hotmail.com
if (shExpMatch(url, "*hotmail.com*"))
        return "DIRECT";
// Would send only traffic to the the host and subdomains of hotmail.com
if (shExpMatch(host, "*.hotmail.com"))
        return "DIRECT";

Функции PAC

Все современные браузеры поддерживают набор функций, явно предназначенных для использования в PAC-файлах. PAC-файлы работают в "песочнице", и хотя многие стандартные функции JavaScript могут поддерживаться, "песочница" не позволяет PAC-файлам выполнять действия, основанные на содержимом веб-страницы, а также не дает им доступа к функциям, позволяющим получить доступ к пользовательскому агенту браузера или узнать публичный IP-адрес пользователя.

Функции

dnsDomainIs

Оценивает имена хостов и возвращает true, если имена хостов совпадают. Используется в основном для сопоставления и исключения отдельных имен хостов.

// Если имя хоста совпадает с google.com или www.google.com, 
// выполняется перенаправлние в Интернет.
if (dnsDomainIs(host, "google.com") || dnsDomainIs(host, "www.google.com")) 
    return "DIRECT";

shExpMatch

Попытается сопоставить имя хоста или URL с указанным выражением оболочки и в случае совпадения возвратит true.

// Все запросы с именем хоста, заканчивающимся расширением .local,
// будут направлены напрямую в Интернет.
if (shExpMatch(host, "*.local"))
    return "DIRECT";
// Запрос к хосту vpn.domain.com или любой запрос к файлу или папке в
// расположении http://abcdomain.com/folder/ будет направлен напрямую в Интернет.
if (shExpMatch(host, "vpn.domain.com") ||
    shExpMatch(url, "http://abcdomain.com/folder/*"))
    return "DIRECT";

isInNet

Данная функция определяет IP-адрес имени хоста и, если он находится в пределах указанной подсети, возвращает true. Если передается имя хоста, то функция преобразует его в IP-адрес.

// Если IP-адрес запрашиваемого сайта попадает в указанный диапазон IP-адресов, то происходит перенаправление в Интернет. 
if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")) 
    return "DIRECT";

myIpAddress

Returns the IP address of the host machine. However, with the rise of IPv6 and no ability to distinguish between multiple active network adapters, this function should be avoided.

// If the machine requesting a website falls within IP range, 
// send traffic via proxy 10.10.5.1 running on port 8080. 
if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0")) 
    return "PROXY 10.10.5.1:8080";

dnsResolve

Resolves a hostname to an IP address. Note that browsers do not perform unique DNS lookups for the same host per function-use – local DNS caching is respected and multiple uses of this function will not have a DNS load or performance impact.

// Example #1 - If IP of the requested host falls within any of the ranges specified, send direct. 
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";
// Example #2 - If IP of the requested host falls within any of the ranges specified, send direct. 
resolvedHost = dnsResolve(host);
if (isInNet(resolvedHost, "10.0.0.0", "255.0.0.0") || 
    isInNet(resolvedHost, "172.16.0.0", "255.240.0.0") || 
    isInNet(resolvedHost, "192.168.0.0", "255.255.0.0") || 
    isInNet(resolvedHost, "127.0.0.0", "255.255.255.0")) 
    return "DIRECT";

isPlainHostName

This function will return true if the hostname contains no dots, e.g. http://intranet – useful when applying exceptions for internal websites.

// If user requests plain hostnames, e.g. http://intranet/, // http://webserver-name01/, send direct. 
if (isPlainHostName(host)) 
    return "DIRECT";

localHostOrDomainIs

Evaluates hostname and only returns true if exact hostname match is found.

// If the Host requested is "www" or "www.google.com", send direct. 
if (localHostOrDomainIs(host, "www.google.com")) 
    return "DIRECT";

isResolvable

Attempts to resolve a hostname to an IP address and returns true if successful.

// If the host requested can be resolved by DNS, send via proxy1.example.com. 
if (isResolvable(host)) 
    return "PROXY proxy1.example.com:8080";

dnsDomainLevels

This function returns the number of DNS domain levels (number of dots) in the hostname. Can be used to exception internal websites which use short DNS names, e.g. http://intranet

// If hostname contains any dots, send via proxy1.example.com, otherwise send direct. 
if (dnsDomainLevels(host) > 0) 
    return "PROXY proxy1.example.com:8080"; 
        else return "DIRECT";

weekdayRange

Allows rules to be time based, e.g. only return a proxy during specific days.

// If during the period of Monday to Friday, proxy1.example.com will be returned, otherwise 
// users will go direct for any day outside this period. 
if (weekdayRange("MON", "FRI")) 
    return "PROXY proxy1.example.com:8080"; 
        else return "DIRECT";

dateRange

Allows rules to be time based, e.g. only return a proxy during specific months.

// If during the period of January to March, proxy1.example.com will be returned, otherwise 
// users will go direct for any month outside this period. 
if (dateRange("JAN", "MAR")) 
    return "PROXY proxy1.example.com:8080"; 
        else return "DIRECT";

timeRange

Allows rules to be time based, e.g. only return a proxy during specific hours.

// If during the period 8am to 6pm, proxy1.example.com will be returned, otherwise 
// users will go direct for any time outside this period. 
if (timeRange(8, 18)) 
    return "PROXY proxy1.example.com:8080"; 
        else return "DIRECT";

Источник