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

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


====myIpAddress====
====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.
Возвращает IP-адрес хост-машины. Однако с появлением протокола IPv6 и отсутствием возможности различать несколько активных сетевых адаптеров от использования этой функции следует отказаться.
 
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
// If the machine requesting a website falls within IP range,  
// Если машина, запрашивающая сайт, попадает в диапазон IP-адресов,
// send traffic via proxy 10.10.5.1 running on port 8080.  
// отправьте трафик через прокси 10.10.5.1, работающий на порту 8080.  
if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0"))  
if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0"))  
     return "PROXY 10.10.5.1:8080";
     return "PROXY 10.10.5.1:8080";

Версия от 14:53, 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

Возвращает IP-адрес хост-машины. Однако с появлением протокола IPv6 и отсутствием возможности различать несколько активных сетевых адаптеров от использования этой функции следует отказаться.

// Если машина, запрашивающая сайт, попадает в диапазон IP-адресов,
// отправьте трафик через прокси 10.10.5.1, работающий на порту 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";

Источник