Hướng Dẫn Sử Dụng
Как правильно настроить NO_PROXY для localhost и внутренних API

Содержание
В корпоративной среде приложениям часто приходится выходить в Интернет через прокси для соблюдения сетевых политик и контроля трафика. Однако подключения к localhost, службам на той же машине или внутренним API обычно должны выполняться напрямую. Если не разграничить эти адреса назначения, запросы могут неожиданно направляться через прокси, вызывая ошибки подключения или нарушая схему взаимодействия между сервисами.
Настройка NO_PROXY позволяет указать адреса, для которых не следует использовать прокси, в HTTP-клиентах, поддерживающих этот механизм. Для правильной настройки необходимо понимать, как приложение считывает переменные окружения, как сопоставляются доменные имена и что означает localhost в каждой среде развертывания.
Как работает NO_PROXY?
NO_PROXY — это переменная окружения со списком адресов назначения, к которым HTTP-клиенту предписывается подключаться напрямую, а не через указанный прокси. Обычно этот список содержит имена хостов, доменные имена или IP-адреса, разделенные запятыми.
Распространенный набор переменных окружения для прокси включает:
- HTTP_PROXY: адрес прокси для HTTP-запросов, если клиент поддерживает эту переменную.
- HTTPS_PROXY: адрес прокси для HTTPS-запросов.
- NO_PROXY: список адресов назначения для прямого подключения.
При отправке запроса клиент принимает решение об использовании прокси на основе действующей конфигурации и правил сопоставления со списком исключений. Поэтому NO_PROXY не является правилом маршрутизации, автоматически действующим для всей операционной системы. Эта переменная влияет только на программы и библиотеки, в которых реализован соответствующий механизм.
В частности, HTTPS_PROXY не обязательно должна содержать URL, начинающийся с https://. Для HTTP-прокси с поддержкой метода CONNECT значение вида http://proxy.corp.example:8080 может использоваться для HTTPS-запросов. Протокол в URL описывает способ подключения к прокси, а не протокол целевого сайта.
Базовая настройка для localhost и внутренних API
Предположим, приложение должно выходить в Интернет через прокси организации и одновременно обращаться к локальному сервису и API по адресу api.corp.example. В POSIX-совместимой оболочке можно задать:
export HTTP_PROXY='http://proxy.corp.example:8080'
export HTTPS_PROXY='http://proxy.corp.example:8080'
export NO_PROXY='localhost,127.0.0.1,::1,api.corp.example'
Адреса и порты в примере приведены только для иллюстрации; их необходимо заменить значениями, предоставленными администратором. После задания переменных запустите приложение из того же сеанса оболочки, чтобы процесс получил эти переменные окружения.
Что нужно указать для обхода прокси при обращении к localhost?
Рекомендуется перечислить localhost, 127.0.0.1 и ::1, если приложение может использовать имя localhost, loopback-адрес IPv4 и loopback-адрес IPv6. Не следует предполагать, что указание localhost автоматически охватывает все запросы к loopback-адресам.
Обычно сопоставление выполняется по имени хоста или адресу, указанному в URL, а не по всем адресам, в которые DNS может разрешить это имя. Поэтому http://localhost и http://127.0.0.1 могут обрабатываться по-разному. Синтаксис IPv6 в NO_PROXY также необходимо проверить на реально используемом клиенте.
Задавайте исключения для внутренних API с подходящей областью действия
Если прямое подключение требуется только к одному API, начните с конкретного имени хоста, например api.corp.example. Если несколько сервисов в одном внутреннем домене используют общую политику подключения, можно рассмотреть исключение по доменному суффиксу.
Распространенный пример — NO_PROXY='localhost,127.0.0.1,::1,corp.example,.corp.example'. Однако разные клиенты неодинаково трактуют корневое доменное имя и начальную точку. Перед широким применением необходимо проверить как corp.example, так и поддомены, например api.corp.example.
Какие правила сопоставления нужно проверить
Имя хоста — не полный URL
В обычной конфигурации NO_PROXY содержит адреса назначения без протокола и пути. Следует использовать api.corp.example вместо https://api.corp.example/private. Эта переменная не предназначена для задания отдельных политик для каждого пути API.
Если необходимо разграничивать трафик по путям, используйте функции маршрутизации приложения или подходящий сетевой компонент. Не следует приписывать NO_PROXY возможности, которые клиент не поддерживает.
Не считайте, что подстановочные символы поддерживаются всегда
Синтаксис *.corp.example может интерпретироваться разными библиотеками неодинаково. Некоторые клиенты поддерживают отдельное значение * для прямого подключения ко всем адресам назначения, но это не означает, что они поддерживают шаблоны с подстановочными символами в доменных именах.
Не следует задавать NO_PROXY='*' для приложения, которое по-прежнему должно использовать прокси при выходе в Интернет. В клиентах, поддерживающих это значение, оно может полностью отключить действие настроек прокси.
Поддержка IP-адресов, CIDR и портов зависит от клиента
Не все библиотеки понимают диапазоны сетей в нотации CIDR в NO_PROXY. Кроме того, поддержка CIDR не означает, что клиент будет разрешать каждое имя хоста и затем проверять, входит ли полученный адрес в указанный диапазон.
Аналогично синтаксис имя_хоста:порт имеет смысл только в клиентах с поддержкой сопоставления по порту. Если особых требований нет, отдавайте предпочтение конкретным именам хостов или IP-адресам и проверяйте поведение перед добавлением сложных правил.
Регистр символов и порядок приоритета
Во многих средах используются как HTTP_PROXY, HTTPS_PROXY, NO_PROXY, так и соответствующие переменные в нижнем регистре. Их поддержка и порядок приоритета зависят от программы, поэтому единого правила для всех приложений нет.
Чтобы уменьшить различия между инструментами, можно синхронизировать переменные в оболочке:
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"
Не допускайте противоречащих друг другу значений у двух переменных с одинаковым назначением. Например, если NO_PROXY содержит внутренний API, а no_proxy пуста, разные клиенты могут вести себя по-разному.
В частности, curl принимает для настройки HTTP-прокси через переменные окружения только вариант http_proxy в нижнем регистре по соображениям безопасности, связанным со средой CGI. Этот пример показывает, почему необходимо читать документацию используемого инструмента, а не полагаться только на распространенные имена переменных.
Применение в приложениях и контейнерах
Приложение, работающее как системная служба
Задание переменных в терминале не изменяет окружение уже запущенной службы. При использовании менеджера служб необходимо задать переменные в конфигурации окружения службы, а затем выполнить перечитывание конфигурации или перезапуск в соответствии с используемым механизмом.
Проверяйте окружение именно процесса приложения. Наличие NO_PROXY в терминале доказывает только то, что эта переменная есть в текущем сеансе оболочки, но не то, что ее получила фоновая служба.
Контейнеры и Docker Compose
Переменные окружения хоста не появляются автоматически во всех контейнерах. Необходимо передать HTTP_PROXY, HTTPS_PROXY и NO_PROXY в окружение выполнения контейнера через механизм конфигурации развертывания.
Localhost внутри контейнера указывает на собственное сетевое пространство имен этого контейнера. Если API находится в другом контейнере, приложение обычно должно обращаться к нему по имени сервиса, например internal-api. В таком случае имя internal-api должно присутствовать в списке исключений, если клиент использует прокси.
Также необходимо различать окружение сборки образа и окружение выполнения приложения. Работа прокси при загрузке пакетов на этапе сборки не доказывает, что конфигурация во время выполнения верна.
Кластеры Kubernetes
В Kubernetes приложение может обращаться к сервису по короткому имени, имени с пространством имен или полному DNS-имени. Настройка исключений должна точно отражать те формы имен, которые приложение действительно использует.
Не следует без изменений копировать список доменов или диапазонов сетей из другого кластера. DNS-суффиксы и адресный план сети могут отличаться; кроме того, клиент может не поддерживать указанный синтаксис.
Различия между HTTP-библиотеками
Даже правильная настройка на уровне окружения может не действовать, если приложение использует собственный механизм работы с прокси. При настройке прокси для внутренних API проверяйте как среду выполнения, так и библиотеку, отправляющую запросы.
- Python Requests: обычно считывает настройки прокси из окружения. Однако настройки сессии или отключение trust_env могут изменить это поведение.
- Go: транспорт, использующий http.ProxyFromEnvironment, может считывать переменные окружения. Пользовательский транспорт может не использовать этот механизм.
- Node.js: не следует предполагать, что все версии, библиотеки или HTTP-агенты автоматически считывают один и тот же набор переменных прокси. Необходимо проверить конкретный компонент, отправляющий запросы.
- Java: многие приложения используют свойства JVM, такие как http.proxyHost и http.nonProxyHosts, вместо прямого обращения к NO_PROXY. Синтаксис списка исключений также отличается.
Если приложение задает прокси непосредственно в исходном коде, проверьте, учитывает ли эта конфигурация NO_PROXY. Явно заданный параметр прокси может изменить механизм обработки исключений.
Порядок проверки конфигурации NO_PROXY
- Подтвердите наличие переменных окружения: проверяйте их в нужном контейнере, сеансе выполнения или соответствующем процессе; скрывайте учетные данные при передаче результатов.
- Проверьте внешний адрес: используйте разрешенную конечную точку и по журналам или сведениям о соединении убедитесь, что запрос по-прежнему проходит через прокси.
- Проверьте localhost: обратитесь к тому же имени хоста и порту, которые использует приложение, затем проверьте, что соединение прямое.
- Проверьте внутренний API: выполните проверку с той же библиотекой и конфигурацией, которые использует приложение, а не только с помощью инструмента командной строки.
- Сопоставьте свидетельства: используйте журналы приложения, журналы прокси и наблюдение за сетевыми соединениями, если у вас есть соответствующие разрешения.
Для наблюдения за процессом подключения можно использовать curl -v https://api.corp.example/health. Подробный режим может выводить конфиденциальные данные, поэтому перед передачей журналов необходимо проверить их и скрыть такую информацию.
Успешный ответ сам по себе еще не доказывает, что запрос прошел напрямую. И наоборот, ошибка прямого подключения не обязательно связана с NO_PROXY: причиной могут быть DNS, межсетевой экран, маршрутизация или сертификаты TLS.
Типичные ошибки и принципы эксплуатации
К распространенным ошибкам относятся неверное имя переменной, использование URL вместо имени хоста, отсутствие передачи переменных в контейнер, непримененный перезапуск службы или обращение к API по имени, отличному от указанного в настройках. Перенаправление HTTP на другое имя хоста также может привести к тому, что к следующему запросу будут применены другие правила использования прокси.
С точки зрения безопасности следует ограничивать список исключений необходимыми адресами, не помещать пароли прокси в репозиторий исходного кода и не отключать проверку TLS для устранения ошибок подключения. NO_PROXY управляет только выбором прокси на стороне клиента; эта переменная не предоставляет доступ к сети и не заменяет политики межсетевого экрана.
Заключение
Чтобы эффективно настроить NO_PROXY, начните с localhost, необходимых loopback-адресов и конкретного имени хоста внутреннего API. Затем синхронизируйте переменные окружения, проверьте поддержку со стороны библиотеки и подтвердите фактический маршрут запросов. Такой подход позволяет приложению сохранять доступ в Интернет через прокси, обеспечивая при этом работу внутренних соединений в соответствии с задуманной схемой.
Похожие статьи
Хватит читать — пора подключить настоящий прокси?
Residential, ISP, Datacenter или Mobile прокси — готовы за пару минут.
Смотреть продукты