Минутка философии

Если честно, то я не всегда понимаю разработчиков ПО. Нет, вернее так - я не всегда понимаю, почему мы, разработчики, принимаем те решения, которые принимаем. Довольно давно идут споры по поводу того, является ли программирование просто ремеслом, или же в нем есть какое-то творческое начало. Я не знаю ответа на этот вопрос. Но точно могу сказать, что для меня программирование - это не обезличенное массовое производство. Его пытаются сделать таким, ибо в таком виде им легко управлять, его легко посчитать, прогнозировать и использовать. Но, в большинстве своем, оно, программирование, до сих пор не такое.

Программа очень часто несет на себе отпечаток личности того, кто является ее автором. Даже если ее пишет не один десяток человек, все равно она отражает мировоззрение ее истинного идеолога. Да что уж говорить, даже если дать одно и тоже совсем небольшое и несложное задание нескольким разным разработчикам, можно с большой долей вероятности утверждать, что они решат ее хоть немного, но по-разному. Нет, конечно есть все эти best practices, шаблоны и прочая и прочая, и тем не менее.

Настройки proxy - базовая информация

С этих филосовских высот вернемся на бренную землю. Сегодня я хочу поговорить о настройках proxy для браузеров, построенных на базе Chromium. В это большое семейство входят и Chrome собственной персоной, и продукт "российского Гугла" - Яндекса - Яндекс.Браузер, а также Opera, Brave, а сейчас ещё и Microsoft Edge. А proxy - это такой инструмент, который может во многом определить путь, по которому браузер, в конечном итоге, добирается до затребованной пользователем информации.

Во многих операционных системах существует возможность задать параметры proxy, которые будут действовать для всей системы. Если такую настройку выполнить, то многие программы, использующие возможности операционных систем, совершенно прозрачным для себя образом будут использовать эту настройку, и это хорошо. Ведь в таком случае разработчикам софта не придется писать некий код, который будет, в большинстве случаев, дублировать уже написанный ранее код (или код, который будет написан позже 🤔). К тому же, это ведь очень удобно - выполнить настройку в одном месте и не думать о том, в какой программе и каким образом можно добиться нужного результата.

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

Браузеры и proxy

Вот и с настройками proxy такая же история. Мне кажется, что браузер - это первый кандидат в число программ, которые должны иметь возможность использовать, хотя бы иногда, собственные настройки proxy, отличные от системных. Хотя, не буду скрывать, не единожды у меня возникало желание иметь возможность указать proxy даже не для браузера в целом, а для его отдельно взятой вкладки.

Вообще, сценариев использовать proxy можно придумать довольно много, но, для начала, было бы неплохо хотя бы иметь возможность задать настройки для приложения в целом из самого приложения. Видимо, так думали разработчики Firefox, которые реализовали в настройках своего браузера возможность указать конфигурацию proxy. Почему такой возможности не было предусмотрено у Internet Explorer, примерно, понятно - долгое время он был неотделим от операционной системы, следовательно, его настройки были настройками системы и наоборот.

Ну а разработчики Chromium думали несколько иначе, поэтому у них получилось весьма оригинальное решение. С одной стороны, они, видимо, мечтали о лаврах Internet Explorer, поэтому в версии для Windows настройки proxy для системы и для браузера есть суть одно и тоже. В версии для Linux, если я правильно помню, настройка параметров proxy из интерейса невозможна вообще.

С другой стороны, Chromium обладает развитым API, позволяющим расширять возможности базового приложения. Используя его, сторонние разработчики смогли создать расширения, позволяющие, в частности, настраивать параметры proxy. Примером может служить Proxy SwitchyOmega.

Возможно, использование расширений для настройки параметров proxy - это, действительно, выход для различных инкарнаций Chromium. Я, если честно, не очень люблю все вот эти дополнения к основному софту, хотя и понимаю, что часто это удобно и практично, и, если без них - никуда, то что ж тут поделаешь. Но когда я знаю, что нужного мне функционала я могу добиться и без дополнительного ПО, то я всегда выберу именно этот путь, хотя бы для того, чтобы убедиться, что он никуда не годится.

Так вот, вернёмся к настройкам proxy. У Chromium и у его многочисленных наследников, нет интерфейса, с помощью которого можно настроить параметры proxy. Но зато при старте этих программ можно с помощью параметров командной строки задать те самые настройки, о которых мы сейчас ведем речь.

Теперь стало понятно, почему в самом начале я написал всю эту философскую лабуду ни о чем? Это тот самый случай, когда я действительно не понимаю, почему разработчики написали парсинг командной строки, наверняка создали модель, позволяющую хранить и использовать результат этого разбора, но не удосужились "навесить" хотя бы простейший пользовательский интерфейс на все это добро. Возможно, это моё недоумение произрастает из моего незнания самого продукта с точки зрения его разработчиков. Но, как бы то ни было, разве это не искусство, непостижимое и эмоциональное?!

Параметры командной строки для настройки proxy

Ладно, теперь о серьёзном. Как можно указать при запуске тому же Chrome, какой proxy он должен использовать. Есть страничка, посвященная разработчиками Chromium сетевым настройкам. На ней достаточно информативно описано, какие параметры и для чего следует использовать. Приведу краткую выжимку для тех, кому просто лень переходить. Итак:

  • --no-proxy-server - указывает браузеру не использовать proxy. Самый "сильный параметр" - если он указан, то все остальные параметры будут проигнорированы.
  • --proxy-auto-detect - указывает, что браузеру следует попытаться автоматически определить настройки proxy. Однако, этот параметр будет проигнорирован, если явно будет указан другой параметр - --proxy-server.
  • --proxy-server - самый, наверное, полезный параметр, так как он позволяет указать явную конфигурацию proxy, которую браузер должен использовать. Конфигурацию можно указать следующими способами:
    • указать разделенные символом ; пары соответствия схем и адресов с портами, например,
      --proxy-server="http=http_proxy:81;ftp=ftp_proxy",
      где первая пара http=http_proxy:81 определяет, что в качестве proxy для http запросов должен использоваться сервер http_proxy, слушающий на порту 81, а вторая пара (ftp=ftp_proxy) определяет, что для ftp запросов должен использоваться proxy на хосте ftp_proxy. Вообще, в качестве схем могут быть использованы: http, https, ftp, socks, socks4, socks5.
    • указать просто адрес с возможным портом, например,
      --proxy-server="super_proxy:3128",
      что будет указывать, что весь трафик должен идти через proxy сервер, работающий на хосте super_proxy и слушающий порт 3128
    • указать специальное значение "direct://", примерно, так:
      --proxy-server="direct://",
      что будет означать, что весь трафик должен идти напрямую, без использования proxy
  • --proxy-bypass-list - данный параметр позволяет указать, для каких адресов не надо использовать proxy, указанный с помощью параметра --proxy-server. Адреса, точнее, маски адресов, разделяются символом ; (если, конечно, их несколько), кроме того, могут быть указаны еще и порты, например:
    --proxy-bypass-list="*.yandex.com;*info.com;127.0.0.1:8080",
    что будет означать, что без proxy будет осуществляться доступ ко всем поддоменам yandex.com, ко всем доменам, оканчивающимся на info.com, и к хосту с IP 127.0.0.1 (localhost 😉) на порт 8080
  • --proxy-pac-url - данный параметр позволяет указать адрес PAC файла, например:
    --proxy-pac-url="http://some-url/proxy.pac",
    что будет означать, что браузер попытается загрузить с хоста some-url файл proxy.pac, в котором должна содержаться javascript функция
    function FindProxyForURL(url, host)
    определяющая proxy в зависимости от некоторого набора условий.

Есть еще один аспект, который следует учитывать. Параметр --proxy-server определяет proxy, через который направляются запросы и загружаются url-адреса. Однако, в Chromium есть отдельные модули, которые могут посылать запросы к DNS серверам напрямую, минуя proxy. Наиболее значимым таким модулем является DNS Prefetcher. Конечно, этот модуль можно отключить, но это не очень правильное решение, так как механизм может использоваться много где, и не совсем понятно, в каком месте вылезут последствия. Поэтому разработчиками Chromium предлагается использовать следующее решение - задать следующий параметр командной строки:

--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE proxy_server"

Эта настройка все DNS запросы увязывает с неверным адресом 0.0.0.0. Единственным исключением является хост (proxy_server) с работающим proxy (в противном случае сам proxy стал бы недоступен).

Практическое применение знаний

Теперь, когда, вслед за философской, завершена и теоретическая часть, приступим к части практической. И начнем, пожалуй, с Windows.

Открываем свойства ярлыка, отвечающего за запуск нужного браузера:

Контекстное меню Windows

и в поле Объект добавляем нужные нам параметры, разделяя их пробелами (командная строка приведена для запуска в Windows браузера Microsoft Edge, остнованного на Chromium):

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --proxy-server="socks5://127.0.0.1:1080" --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE 127.0.0.1"

Получаем примерно такую картинку:

Свойства ярлыка

После чего сохраняем изменения и, перезапустив браузер (если он работал на момент внесения изменений), наслаждаемся работой через указанный proxy.

Для Linux тоже все достаточно просто. Можно указать параметры в командной строке:

google-chrome --proxy-server="socks5://127.0.0.1:1080 --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE 127.0.0.1""

А можно отредактировать файл .bashrc (например, при помощи nano: nano ~/.bashrc), добавив в него алиас для вызова браузера уже с нужными параметрами, например, такой:

alias google-chrome='google-chrome --proxy-server="socks5://127.0.0.1:1080" --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE 127.0.0.1"'

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

google-chrome

Вот, пожалуй все, что хотел пока рассказать.