pac url прокси что это
Использование файлов автоматической настройки прокси-сервера (PAC) в IEAK11
15 июня 2022 г. настольное приложение Internet Explorer 11 будет снято с службы поддержки. Список того, что имеется в области, см. в faq. Те же приложения и сайты IE11, которые вы используете сегодня, можно открывать в Microsoft Edge в режиме Internet Explorer. Более подробную информацию см. здесь.
Здесь приведены различные способы использования файла автоматической настройки прокси-сервера (PAC) для указания URL-адреса автоматического прокси-сервера. Мы добавили здесь некоторые примеры в помощь. Однако нужно будет изменить имена прокси-серверов, номера портов и IP-адреса в соответствии со сведениями о вашей организации.
Пример1. Прямое подключение для локального узла.
В этом примере возможно прямое подключение для локального узла. Если же сервер не является локальным, то он должен устанавливать подключение через прокси-сервер. В частности, функция isPlainHostName проверяет наличие точек (.) в имени узла. Если функция находит точки, это значит, что узел не является локальным, и она возвращает значение false. В противном случае она возвращает значение true.
Пример2. Прямое подключение для узла за брандмауэром.
В этом примере возможно прямое подключение для узла за брандмауэром. Если же сервер находится вне брандмауэра, то он должен устанавливать подключение через прокси-сервер. В частности, функция localHostOrDomainIs работает только для URL-адресов в локальном домене. Если доменное имя узла соответствует предоставленным данным о домене, то функция dnsDomainIs возвращает значение true.
Пример3. Прямое подключение для разрешимого имени узла.
В этом примере возможно прямое подключение для узла, имя которого удается разрешить. Если же имя не удается разрешить, то сервер должен устанавливать подключение через прокси-сервер. В частности, эта функция запрашивает DNS-сервер для разрешения переданного ей имени узла. Если удается разрешить имя, устанавливается прямое подключение. В противном случае устанавливается подключение через прокси-сервер. Это особенно полезно, если внутренний DNS-сервер используется для разрешения всех внутренних имен узлов.
Пример4. Прямое подключение для узла в указанной подсети.
В этом примере возможно прямое подключение для узла в указанной подсети. Если же сервер находится вне указанной подсети, то он должен устанавливать подключение через прокси-сервер. В частности, функция isInNet (узел, шаблон, маска) возвращает значение true, если IP-адрес узла соответствует указанному шаблону. Маска указывает, какую часть IP-адреса сопоставлять (255 = сопоставлять, 0 = игнорировать).
Пример5. Определение типа подключения на основе домена узла.
Пример6. Определение типа подключения на основе протокола.
В этом примере используемый протокол извлекается из сервера и служит для выбора прокси-сервера. Если соответствие протокола не обнаруживается, то сервер устанавливает прямое подключение. В частности, функция substring извлекает указанное количество символов из строки. Это особенно удобно, если протокол является одним из критериев выбора прокси-сервера.
Пример7. Определение прокси-сервера по имени узла, соответствующему IP-адресу.
В этом примере прокси-сервер выбирается путем преобразования имени узла в IP-адрес с последующим сравнением адреса с указанной строкой.
Пример8. Подключение через прокси-сервер, если IP-адрес узла соответствует указанному IP-адресу.
В этом примере прокси-сервер выбирается путем явного получения IP-адреса с последующим сравнением его с указанной строкой. Если соответствие протокола не обнаруживается, то сервер устанавливает прямое подключение. В частности, функция myIpAddress возвращает IP-адрес (в формате целых чисел, разделенных точками) для узла, на котором работает браузер.
Пример9. Подключение через прокси-сервер, если имя узла содержит точки.
В этом примере функция проверяет наличие точек (.) в имени узла. Если имя содержит точки, то подключение устанавливается через прокси-сервер. Если точек нет, то устанавливается прямое подключение. В частности, функция dnsDomainLevels возвращает целое число, равное количеству точек в имени узла.
Примечание
Это другой способ определения типа подключения, основанный на характеристиках имени узла.
Пример10. Подключение через прокси-сервер в зависимости от дня недели.
Десять примеров того, как не нужно писать PAC-файлы
Введение
Практически любое внедрение Web Security Gateway, будь то облачное SaaS решение, вроде Zscaler или on-premises appliance, такое, как Cisco WSA (IronPort), не обходится без конфигурирования прокси-серверов в браузерах при определенных кейсах и потому по работе мне часто приходится сталкиваться с файлами авто-конфигурации прокси-серверов (PAC, proxy auto configuration). В этой статье я бы хотел рассмотреть несколько примеров оптимизации их производительности.
Зачем нужна эта статья
Почему я решил написать эту статью и есть ли в ней польза? Надеюсь, что да, и вот почему. По сути, PAC-файл есть JavaScript функция поиска соответствия строки/подстроки полей url/host, которая возвращает имя прокси сервера для ресурса или предписывает браузеру использовать прямой доступ к ресурсу в обход прокси. Как и любой язык программирования, код JavaScript также можно оптимизировать для выполнения. В условиях крупных компаний/предприятий со сложной, распределенной инфраструктурой доступа к сети Интернет и, как следствие, PAC-файлами, состоящими из нескольких сотен строк кода, задача по оптимизации PAC-файлов уже не кажется чем-то абсолютно бесполезным, так как, например, проценты времени исполнения одной не оптимальной или используемой не к месту функции, очевидно, будут помножены на количество её вхождений (применений) её в коде.
Disclaimer
Эта статья не ставит своей целью развернуто описать функции, применяемые в PAC-файлах. Для более подробного описания каждой функции я рекомендую обратиться за справкой, например, к сайту http://findproxyforurl.com. Результаты тестов производительности различных браузеров в этой статье могут быть спорными и ни в коем случае не претендуют на абсолютную истину, однако, автор старался приложить максимум усилий, чтобы достичь правдивого результата. Тем не менее, по обозначенной причине спорности, сводные результаты тестов не приводятся — читателю предлагается самостоятельно убедиться в преимуществе использования тех или иных подходов. Для этого там, где возможно, будут даны ссылки на тесты. В своём изыскании я в первую очередь полагался на ресурс jsperf.com, который очень кстати позволяет при наличии аккаунта на github создавать сценарии тестирования и замерять производительность кода на JavaScript, именно там будут храниться сценарии тестов к этой статье.
Ну что же, перейдем к делу.
Пример первый
Первым в моём списке идёт наиболее простой случай, когда требуется выбрать прокси для строго определенного хоста. Очень часто коллеги зачем-то используют в таком случае проверку url не к месту или обрамляют строку «*». Часто такое бывает, когда в PAC-файле уже за сотню строк и кто-то добавляет по аналогии новое условие вроде следующего:
или так все же с host:
Проблема здесь даже не в том, что для Chrome 58 и IE11 первый вариант почти на 1% медленнее (для Firefox 53 между ними почти нет разницы), самое зло здесь в том, как, надеюсь, многие из читателей догадались, что для URL, например, «http://www.noncisco.com/evil/cisco.com» оба результата вернут true. Решение проблемы очень простое — не использовать функцию shExpMatch, которая для этого не предназначена, а вместо неё искать точное совпадение:
Минус здесь также очевиден. Код выше вернёт false для http://cisco.com, хотя, конечно, никто не мешает вам сделать две проверки:
Собственно, ссылка на тест, для желающих убедиться в производительности: https://jsperf.com/inefficient-shexpmatch
К слову, а как тестировать PAC-файлы? Не перебирать же их вручную в браузере в самом деле? Хотя этот способ и будет ультимативным, я все же использую для этих целей ресурс http://home.thorsen.pm/proxyforurl, который меня ещё не подводил и не обманывал.
Пример второй
Проблема номер два очень близка по своей сути к тому, что мы рассмотрели выше, и здесь опять применяют нелюбимую мной функцию по-умолчанию shExpMatch.
Задача — для определенного домена использовать MyProxy2. Что делают:
Опять же не оптимально, не точно, не к месту. Используем функцию
Хотя, строго говоря, для браузеров FF и Chrome эти функции почти равны по производительности, для IE11 это существенно и разница более чем в 1%.
Собственно, тест:
https://jsperf.com/dnsdomainis-vs-shexpmatch
Пример третий
Проблемка номер три, которая часто возникает из-за невнимательности администраторов, заключается она в дублирующих друг друга условиях. Пример:
Мало того, что условия дублируют (перекрывают) друг друга, так ещё они и не отработают в принципе, если пользователь ввёл доменное имя, а не ipv4 адрес в адресную строку браузера. Решение — исключить повторяющиеся условия и выполнить разрешение имени, хотя бы так:
Пример четвертый
Собственно, проблема номер четыре является развитием того, что описано в предыдущем разделе. Положим, администратор желает для всех подсетей из диапазона RFC1918 направить клиентов в обход прокси и делает так:
Само собой, напрашивается один раз провести разрешение имени и далее уже работать с переменной, в которой будет записан результат:
Вместо 18 запросов на разрешение имени в худшем случае (для последнего else if), мы получаем предсказуемую производительность и запрашиваем разрешение имени только один раз, что, бесспорно, эффективнее без каких-либо дополнительных тестов.
Пример пятый
Продолжаем нашу оптимизационную рекурсию. Блок кода из предыдущей проблемы уже из-за своего размера напрашивается к оптимизации. Допустим, изначально функция выглядела так:
Даже если оптимизировать код выше и использовать вместо else if логическое или (||), по результатам тестов среди трех уже упомянутых браузеров, наиболее оптимальной оказалось задействовать проверку регулярного выражения следующим образом:
Заметьте, это не только эффективнее, но и выглядит компактнее и изящнее. Но нет предела совершенству, и если воспользоваться специализированной функцией IsInNet, то можно добиться ещё более впечатляющих результатов. По сравнению с предыдущим примером, код ниже даёт прирост производительности от 0,2 до 2% в различных браузерах:
Пример шестой
Небольшое отступление от основной линии для разнообразия. Рассмотрим две строки кода ниже:
Если первая строка вернет ожидаемо true (да, да, именно true, это всего лишь поиск подстроки!), то вторая строка, несмотря на кажущееся точное соответствие, из-за разницы в прописных буквах вернет false (к слову, вроде как в FF до версии 52 результат был бы все же true, но автор вычитал это где-то на просторах сети и не проверял это самолично).
Таким образом, для решения проблемы крайне желательно в самом начале PAC-файла выполнить преобразование строки url и host, если далее мы работаем с ними, например, так:
И далее работать только с url_lc и host_lc.
Пример седьмой
Очень простая проблема, но от того не менее распространенная. Как и многие проблемы, возникает по невнимательности, пример ниже взят из реального кейса внедрения, но имена, конечно, вымышленные и любые совпадения являются чистой случайностью:
И в конце файла мы видим что-то вроде (и даже с комментарием!):
Помимо проблем, что мы уже рассмотрели ранее, блок кода выше полностью бесполезен и лишь замедляет работу браузера, ведь в конечном итоге по умолчанию используется тот же самый proxy-сервер.
Пример восьмой
Проблема номер восемь связана с внутренними ресурсам компании.
Скажем, есть у нас такой код:
То есть PAC-файл проверяет, не обратился ли браузер ко внутреннему ресурсу по hostname без указания домена, так как домены поиска заданы на PC. Хорошим решением для оптимизации таких проверок будет использование всего одной функции:
Пример девятый
Задача оптимизации номер 9 близка к предыдущей и опять же появляется при использовании внутренних ресурсов организации. Что делать, если пользователь может запросить один и тот же сайт как с указанием домена, так и без него, как на примере ниже?
Оптимизировать такие проверки можно довольно просто, если задействовать функцию localHostOrDomainIs:
Пример десятый
Спорная проблема оптимизации if условий. Суть такова, что в PAC-файлах после проверки какого-либо условия по if в подавляющем большинстве случаев идёт возврат из функции FindProxyForURL по return, так зачем же тогда использовать конструкцию, приведенную ниже?
Результаты тестирования FF подсказывают, что оптимальным будет использование OR условия ( || ):
Для Chrome результат будет несколько иным, но блок if / else if опять проигрывает:
На основе сказанного делаем вывод, что оптимальнее будет использовать if statement или if + or, хотя тестирование IE11 даёт кардинально противоположный результат. Возможно, хорошей идеей было бы задействовать switch statement, но данный опус я уже дописываю глубоко ночью, а потому отдаю тестирование этого кейса на откуп многоуважаемому читателю.
Вместо заключения
Вместо заключения, я хотел бы выразить благодарность читателю, если он осилил этот небольшой труд до конца и я искренне надеюсь, что он окажется полезен не только как советы в оптимизации, но и в большей степени как источник новых знаний или идей в работе с инфраструктурой доступа в сеть Интернет для предприятия.
Записки IT специалиста
Технический блог специалистов ООО»Интерфейс»
WPAD или автоматическая настройка параметров прокси
Прежде всего немного теории. Давайте разберемся, как работает протокол и какие сетевые службы нужны для этого.
Автоматическая настройка системы на работу с прокси-сервером производится специальным набором инструкций на JavaScript, который называется PAC-файл (Proxy Auto Configuration), для нахождения его расположения в локальной сети используется протокол WPAD (Web Proxy Auto-Discovery Protocol).
Рассмотрим следующую схему:
Получив запрос от пользователя браузер пытается найти расположение PAC-скрипта используя различные сетевые механизмы. В первую очередь отправляется DHCP-запрос, ответ на который должен содержать URL PAC-файла в специальном поле ответа, для этого используется опция 252 протокола DHCP.
Если в ответе DHCP-сервера искомый адрес не найден, то посылается DNS-запрос для хоста wpad в текущем домене. Некоторые браузеры, например, Firefox, не используют DHCP-запросы, а сразу обращаются к DNS. С механизмом поиска службы WPAD через DNS связана одна серьезная уязвимость. Если в текущем домене хост с именем wpad не найден, то поиск будет произведен в вышестоящем домене, при этом выход за пределы домена организации никак не контролируется.
Что это значит? Допустим клиент расположен в домене office.spb.example.com, то поочередно будет произведен поиск следующих хостов:
Пользуясь этим, злоумышленники могут расположить PAC-файл по адресу за пределами домена предприятия и направить весь трафик на свои прокси сервера, в том числе и зашифрованный, в отношении которого можно осуществить атаку типа «человек посередине» с подменой сертификата.
В связи с этим DNS-сервер от Microsoft начиная с Windows Server 2008 содержит хост wpad в черном списке и не разрешает данное имя, даже если соответствующая запись на данном сервере существует.
В среде OC Windows, если предыдущие попытки не принесли результата, производится поиск хоста WPAD на WINS-сервере и посредством широковещательных протоколов LLMNR ( Link-Local Multicast Name Resolution) и NBNS (NetBIOS Name Service).
Поэтому, если данный веб-сервер использует виртуальные хосты, хост wpad должен являться хостом по умолчанию (или корневым хостом), т.е. его содержимое должно отдаваться при обращении к данному серверу без указания имени хоста, просто по IP-адресу.
Также, в целях безопасности, PAC-файл не должен быть доступен за пределами локальной сети.
PAC-файл
Как мы уже упоминали, PAC-файл является JavaScript-скриптом, однако количество инструкций в нем жестко ограничено. Разберем некоторые из них.
Этих инструкций вполне достаточно, чтобы составить достаточно подробные и разветвленные правила для работы с прокси-сервером. Попробуем составить реальный сценарий.
Прежде всего укажем функцию:
Данная функция получает от браузера URL и host из запроса и в ответ должна вернуть адрес прокси-сервера. Внутри фигурных скобок следует располагать инструкции и условия, в зависимости от выполнения которых браузеру будет возвращен тот или иной результат.
Начнем с того, что не следует направлять на прокси. Прежде всего это «плоские» имена, когда к какому-либо ресурсу пытаются обратиться по короткому имени, например, http://server, так как это однозначно ресурс локальной сети.
Согласно данной записи, если в поле host запроса содержится «плоское» имя, то возвращаем браузеру директиву DIRECT, что означает, что прокси-сервер для этого соединения использовать не следует.
Таким же образом предписываем обращаться напрямую по запросам с IP-адресами локальной сети:
И локальным адресам:
Кстати, первое правило можно переписать по-другому:
В доменной сети также следует настроить прямое соединение для внутренних ресурсов:
Аналогичным образом можно направить мимо прокси какие-либо критичные внешние ресурсы, например, интернет-банки или площадки электронных торгов.
Если ваш прокси не обрабатывает https запросы, то их тоже следует направить мимо, обратите внимание, что вместо host в данном правиле мы используем url:
Тоже самое следует сделать и для ftp запросов:
И наконец все, что не попало ни под одно правило отправляем на прокси:
Разобравшись с тем, как устроен PAC-файл перейдем к сценариям практической реализации служб WPAD в сети.
Сети Active Directory
Так как все наши статьи преемственны, то далее будет подразумеваться что WPAD настраивается для работы с роутером в сети Active Directory, описанного нами в цикле Настраиваем Squid для работы с Active Directory, таким образом данный материал может служить его логическим завершением.
Начнем с настройки DHCP, откроем соответствующую оснастку и перейдем к списку серверов, щелкните правой кнопкой мыши на пункт IPv4 и выберите Предопределенные параметры.
В открывшемся окне нажмите Добавить
И заполните поля следующим образом:
Если в вашей сети более одного DHCP-сервера, то аналогичные настройки нужно выполнить на каждом их них.
Следующим шагом будет настройка DNS, прежде всего откорректируем черный список, для этого на DNS-сервере откроем редактор реестра и перейдем в раздел:
Откроем опцию GlobalQueryBlockList и удалим оттуда значение wpad, после чего службу DNS нужно перезапустить.
Данную операцию следует выполнить на каждом DNS-сервере в вашей сети.
Затем добавьте запись типа A для хоста wpad, которая должна указывать на веб-сервер с PAC-файлом.
Закончив настройки DHCP и DNS следует наконец установить на выбранный хост веб-сервер и разместить на нем wpad.dat. Никаких ограничений здесь нет, вы можете настроить любой веб-сервер на любом узле сети. В нашем случае напрашиваются два варианта: веб-сервер непосредственно на роутере, мы рекомендуем для этих целей простой и легкий lighttpd или веб-сервер на одном из контроллеров домена, в этом случае предпочтение следует отдать IIS.
В данной части статьи мы рассмотрим вариант с IIS, а к lighttpd вернемся чуть позже, когда будем говорить об одноранговых сетях. Мы не будем подробно останавливаться на установке роли Веб-сервер (IIS), достаточно просто пройти все шаги мастера со значениями по умолчанию.
Для правильной работы с PAC-файлом добавьте новый тип MIME, указав расширение .dat и тип MIME application/x-ns-proxy-autoconfig.
Выполнив данную настройку не забудьте перезапустить веб-сервер и разместите в его корневой директории C:\inetpub\wwwroot файл wpad.dat.
Браузеры на основе Google Chrome (в т.ч. Opera, Яндекс) используют настройки, заданные для IE. Проблемы, как всегда, возникают с Firefox, который с настройкой по умолчанию Использовать системные настройки прокси игнорирует их и ходит напрямую, поэтому данную опцию следует изменить на Автоматически определять настройки прокси для этой сети.
Одноранговая сеть
В одноранговых сетях обычно применяются прозрачные прокси, не требующие настройки параметров браузера, однако в ряде случаев, например, для аутентификации, от прозрачности приходится отказываться, следовательно, возникает потребность в WPAD. Далее мы будем рассматривать настройку на примере роутера, настроенного по нашей статье: Ubuntu Server. Настраиваем роутер NAT + DHCP + Squid3.
Так как в большинстве случаев лишних серверов в небольших сетях нет, то все службы будем располагать в пределах роутера. DHCP и кэширующий DNS у нас уже есть, в виде пакета dnsmasq, а в качестве веб-сервера можно установить легковесный lighttpd. На первый взгляд все необходимое имеется и особых проблем возникнуть не должно.
Чтобы убедиться в этом, следует проверить DNS-суффикс текущего подключения. Для этого в консоли PowerShell выполните команду:
Ниже показан вывод команды для одноранговой и доменной сетей, разница в отсутствии DNS-суффикса отлично видна «невооруженным глазом».
Если все оставить как есть, то тот же Firefox не сможет получить настройки прокси и будет требовать ручного ввода параметров. Что делать? К счастью в протоколе DHCP есть опция 015, позволяющая передавать клиенту DNS-суффикс подключения.
Откроем /etc/dnsmasq.conf и последовательно изменим в нем следующие опции:
DNS-имя домена, передаваемое клиенту в опции 015 DHCP.
Задает расположение PAC-файла.
Теперь заново получим IP-адрес и снова проверим DNS-суффикс, также можно попробовать разрешить любое плоское имя (существующего хоста) командой nslookup.
Установим lighttpd:
Затем откроем его конфигурационный файл /etc/lighttpd/lighttpd.conf и добавим туда опцию:
Это ограничит работу веб-сервера только локальной сетью.
После чего следует убедиться, что в файле /etc/mime.types присутствует запись:
Если такой записи нет, то ее следует добавить.
На этом настройка сервера закончена, осталось разместить PAC-файл в директории /var/www и проверить работу браузеров.
Поскольку одноранговая сеть не предоставляет таких возможностей по управлению клиентскими ПК как ActiveDirectory, то следует предпринять меры по предотвращению обхода прокси. Это можно сделать через iptables, запретив форвардинг пакетов с назначением на 80-й порт. Но лучше поступить иначе.
В /etc/nat добавим следующее правило:
Данная конструкция перенаправит все запросы к веб-серверам или сторонним прокси на порт 80 нашего роутера, где работает собственный веб-сервер.
В конфигурацию lighttpd добавим опцию (не забудьте перезапустить веб-сервер):
Теперь в /var/www создадим файл index.html со следующим содержимым:
После чего при попытке обхода прокси пользователь увидит сообщение:
В качестве примера мы привели самый простой вариант странички запрета, вам же ничего не мешает сделать ее более информативной, например, разместив на ней краткие инструкции по самостоятельной настройке браузера.
Если вам нужно разрешить работу с некоторыми сайтами напрямую, минуя прокси, то перед запрещающим правилом добавьте:
Как видим, настроить автоматическое получение параметров прокси совсем несложно и можно эффективно применять данную технологию как в крупных, так и в небольших сетях.
Дополнительные материалы:
Помогла статья? Поддержи автора и новые статьи будут выходить чаще:
Или подпишись на наш Телеграм-канал: