Назад к блогу

Настройка прокси для curl и wget: практические примеры для системных администраторов и DevOps

Полное руководство по настройке прокси для curl и wget с практическими примерами кода, поддержкой SOCKS5, аутентификацией и автоматизацией в CI/CD пайплайнах.

📅3 апреля 2026 г.

Если вы администрируете серверы, пишете скрипты автоматизации или деплоите приложения в корпоративной инфраструктуре — рано или поздно столкнётесь с необходимостью пустить трафик curl или wget через прокси. Это может быть корпоративный прокси, обход гео-блокировок при скачивании пакетов, или ротация IP при массовых запросах к внешним API. В этой статье — только практика: команды, конфиги, примеры кода без воды.

1. Как curl и wget работают с прокси: базовые механизмы

Прежде чем лезть в конфиги, важно понять, что происходит под капотом. Оба инструмента поддерживают два основных протокола прокси: HTTP/HTTPS и SOCKS5. Механика у них разная, и это влияет на то, какой тип прокси выбирать под конкретную задачу.

HTTP-прокси работает как посредник на уровне прикладного протокола. Когда curl отправляет запрос через HTTP-прокси, он буквально говорит прокси-серверу: «сделай GET-запрос вот на этот URL вместо меня». Для HTTPS-трафика используется метод CONNECT — curl просит прокси установить туннель до целевого хоста, после чего TLS-рукопожатие происходит напрямую между клиентом и сервером назначения. Это важно: прокси в таком случае не видит содержимое HTTPS-трафика.

SOCKS5 работает на более низком уровне — он проксирует TCP/UDP-соединения без привязки к протоколу прикладного уровня. Это делает SOCKS5 универсальнее: через него можно пустить не только HTTP/HTTPS, но и другие протоколы. Кроме того, SOCKS5 поддерживает DNS-разрешение на стороне прокси-сервера — это критически важно для предотвращения DNS-утечек.

💡 Ключевое различие для практики:

Если нужно просто скачать файл или сделать API-запрос — HTTP-прокси достаточно. Если нужна полная анонимность, обход DNS-утечек или работа с нестандартными протоколами — используйте SOCKS5.

curl поддерживает оба протокола нативно начиная с очень ранних версий. wget исторически имел более ограниченную поддержку SOCKS5 — в старых версиях (до 1.19) поддержки SOCKS5 нет вообще, только HTTP-прокси. Это нужно учитывать при написании скриптов, которые должны работать на разных дистрибутивах.

Проверить версию wget можно командой wget --version. Для curl — curl --version, там же будет видно, с какими протоколами собрана библиотека libcurl.

2. Переменные окружения: самый быстрый способ настройки

Самый элегантный способ настроить прокси для curl и wget — через переменные окружения. Это работает системно: не нужно менять каждый скрипт, достаточно выставить переменные один раз в сессии или добавить их в профиль пользователя.

Оба инструмента читают одни и те же стандартные переменные:

# Для HTTP-трафика
export http_proxy="http://proxy.example.com:3128"

# Для HTTPS-трафика
export https_proxy="http://proxy.example.com:3128"

# Дублируем в верхнем регистре (некоторые программы читают только их)
export HTTP_PROXY="http://proxy.example.com:3128"
export HTTPS_PROXY="http://proxy.example.com:3128"

# Для FTP (если нужно)
export ftp_proxy="http://proxy.example.com:3128"

# Исключения — адреса, которые НЕ идут через прокси
export no_proxy="localhost,127.0.0.1,::1,192.168.0.0/16,.internal.company.com"

Важный нюанс: curl чувствителен к регистру переменных в зависимости от версии. Чтобы не было сюрпризов — всегда выставляйте обе версии: в нижнем и верхнем регистре. Это стандартная практика в DevOps.

Чтобы настройки применялись постоянно для конкретного пользователя, добавьте строки в ~/.bashrc или ~/.profile. Для системных скриптов и сервисов — в /etc/environment или в юнит-файл systemd через директиву Environment=.

# /etc/systemd/system/myservice.service
[Service]
Environment="http_proxy=http://proxy.example.com:3128"
Environment="https_proxy=http://proxy.example.com:3128"
Environment="no_proxy=localhost,127.0.0.1"
ExecStart=/usr/bin/myapp

Если прокси требует аутентификацию, логин и пароль вставляются прямо в URL переменной:

export http_proxy="http://username:[email protected]:3128"
export https_proxy="http://username:[email protected]:3128"

⚠️ Безопасность:

Не храните пароли в открытом виде в .bashrc или в переменных окружения на продакшн-серверах. Используйте vault-решения (HashiCorp Vault, AWS Secrets Manager) или как минимум ограничьте права на файл с переменными.

3. Флаги curl для работы с прокси: полный разбор

curl предоставляет богатый набор флагов для управления прокси прямо из командной строки. Это удобно, когда нужно сделать разовый запрос через прокси, не меняя системные настройки.

Основной флаг — -x или --proxy:

# Базовый HTTP-прокси
curl -x http://proxy.example.com:3128 https://api.example.com/data

# Короткая форма
curl -x proxy.example.com:3128 https://api.example.com/data

# С явным указанием протокола
curl --proxy http://proxy.example.com:3128 https://api.example.com/data

# Проверить внешний IP через прокси
curl -x http://proxy.example.com:3128 https://api.ipify.org

Для игнорирования переменных окружения и прямого соединения (обход настроенного прокси) используется флаг --noproxy:

# Игнорировать прокси для конкретного хоста
curl --noproxy "internal.company.com" https://internal.company.com/api

# Игнорировать прокси полностью (даже если выставлены env-переменные)
curl --noproxy "*" https://api.example.com/data

Полезные флаги для отладки прокси-соединений:

# Verbose-режим: видно все заголовки, включая CONNECT к прокси
curl -v -x http://proxy.example.com:3128 https://api.example.com/data

# Только заголовки ответа
curl -I -x http://proxy.example.com:3128 https://api.example.com/data

# Показать время соединения через прокси
curl -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" \
  -x http://proxy.example.com:3128 \
  -o /dev/null -s https://api.example.com/data

Настройка прокси через конфиг-файл ~/.curlrc — удобно, если не хочется каждый раз прописывать флаги:

# ~/.curlrc
proxy = http://proxy.example.com:3128
proxy-user = username:password
noproxy = localhost,127.0.0.1,.internal.company.com

Для системных скриптов можно создать отдельный конфиг и указывать его явно через curl -K /path/to/config — это позволяет иметь разные профили прокси для разных задач.

4. Настройка прокси в wget: флаги и конфиг-файл

wget менее гибок, чем curl, но для типичных задач — скачивание файлов, рекурсивное зеркалирование сайтов — его возможностей вполне достаточно. Прокси в wget можно настроить тремя способами: через переменные окружения (рассмотрели выше), через флаги командной строки и через конфиг-файл ~/.wgetrc.

Флаги командной строки wget для прокси:

# HTTP-прокси через флаг
wget -e use_proxy=yes \
     -e http_proxy=http://proxy.example.com:3128 \
     https://example.com/file.tar.gz

# HTTPS через прокси
wget -e use_proxy=yes \
     -e https_proxy=http://proxy.example.com:3128 \
     https://example.com/file.tar.gz

# С аутентификацией
wget -e use_proxy=yes \
     -e http_proxy=http://username:[email protected]:3128 \
     https://example.com/file.tar.gz

# Отключить прокси для конкретной команды (если выставлены env-переменные)
wget --no-proxy https://internal.company.com/file.tar.gz

Конфиг-файл ~/.wgetrc — предпочтительный способ для постоянной настройки:

# ~/.wgetrc
use_proxy = on
http_proxy = http://proxy.example.com:3128
https_proxy = http://proxy.example.com:3128
ftp_proxy = http://proxy.example.com:3128
no_proxy = localhost,127.0.0.1,.internal.company.com

# Если прокси требует аутентификацию
proxy_user = username
proxy_password = secretpassword

Для системного применения (все пользователи) используется /etc/wgetrc — тот же формат, но применяется глобально. Удобно для серверов, где все операции скачивания должны идти через корпоративный прокси.

Практический пример: рекурсивное скачивание сайта через прокси с ограничением глубины и скорости:

wget -e use_proxy=yes \
     -e http_proxy=http://proxy.example.com:3128 \
     --recursive \
     --level=2 \
     --limit-rate=500k \
     --wait=1 \
     --random-wait \
     --user-agent="Mozilla/5.0 (compatible; Googlebot/2.1)" \
     https://example.com/docs/

5. SOCKS5 прокси в curl и wget: настройка и примеры

SOCKS5 — более предпочтительный протокол для задач, где важна анонимность или работа с нестандартными портами. Для системных администраторов и DevOps-инженеров SOCKS5 часто используется при работе через SSH-туннели, а также при подключении к резидентным прокси, которые имитируют трафик реальных пользователей.

В curl SOCKS5 поддерживается через специальный префикс в URL прокси:

# SOCKS5 с DNS-разрешением на стороне клиента (может быть DNS-утечка!)
curl --socks5 proxy.example.com:1080 https://api.example.com/data

# SOCKS5 с DNS-разрешением на стороне прокси (рекомендуется!)
curl --socks5-hostname proxy.example.com:1080 https://api.example.com/data

# Через флаг -x с явным указанием протокола
curl -x socks5h://proxy.example.com:1080 https://api.example.com/data

# С аутентификацией
curl -x socks5h://username:[email protected]:1080 https://api.example.com/data

# SOCKS5 через переменную окружения
export all_proxy="socks5h://proxy.example.com:1080"
curl https://api.example.com/data

📌 socks5 vs socks5h — в чём разница?

socks5 — DNS-запрос выполняется локально, через прокси идёт только TCP-соединение по IP. Возможна DNS-утечка.
socks5h (h = hostname) — DNS-запрос выполняется на стороне прокси-сервера. Полная анонимность. Рекомендуется для большинства задач.

Популярный сценарий в DevOps — использование SSH как SOCKS5-прокси для туннелирования трафика через бастион-хост:

# Открываем SSH-туннель с SOCKS5 на локальном порту 1080
ssh -D 1080 -f -C -q -N [email protected]

# Теперь используем этот туннель в curl
curl -x socks5h://localhost:1080 https://internal-api.private.network/data

# Или через переменную окружения для всех запросов в сессии
export all_proxy="socks5h://localhost:1080"
wget https://internal-resource.private.network/file.tar.gz

wget поддерживает SOCKS5 начиная с версии 1.19. В более старых версиях (CentOS 7, Ubuntu 16.04) придётся использовать обходные решения: proxychains, tsocks, или переходить на curl для задач, требующих SOCKS5.

6. Аутентификация на прокси: логин и пароль

Большинство коммерческих прокси и корпоративные прокси-серверы требуют аутентификации. Есть несколько способов передать учётные данные — каждый со своими плюсами и минусами с точки зрения безопасности.

Способ 1: Учётные данные в URL — просто, но небезопасно (пароль виден в списке процессов):

curl -x http://user:p%[email protected]:3128 https://api.example.com/data
# Спецсимволы в пароле нужно URL-кодировать: @ → %40, : → %3A

Способ 2: Флаг --proxy-user в curl — пароль можно не указывать в командной строке, curl запросит его интерактивно:

# Логин и пароль в флаге (всё ещё виден в ps aux)
curl -x http://proxy.example.com:3128 \
     --proxy-user "username:password" \
     https://api.example.com/data

# Только логин — curl спросит пароль интерактивно
curl -x http://proxy.example.com:3128 \
     --proxy-user "username" \
     https://api.example.com/data

Способ 3: Через .netrc файл — наиболее безопасный для скриптов:

# ~/.netrc
machine proxy.example.com
login username
password secretpassword

# Ограничиваем права доступа к файлу
chmod 600 ~/.netrc

# Используем в curl
curl -x http://proxy.example.com:3128 --proxy-netrc https://api.example.com/data

Способ 4: Через переменные окружения из секретного хранилища — рекомендуется для CI/CD и продакшн-окружений:

# В скрипте читаем учётные данные из переменных (которые задаёт CI/CD)
#!/bin/bash
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@proxy.example.com:3128"
curl -x "${PROXY_URL}" https://api.example.com/data

Таблица сравнения методов аутентификации:

Метод Удобство Безопасность Подходит для
URL (user:pass@host) ⭐⭐⭐ Тестирование
--proxy-user флаг ⭐⭐⭐ ⭐⭐ Разовые команды
.netrc файл ⭐⭐ ⭐⭐⭐ Локальные скрипты
Env переменные из vault ⭐⭐ ⭐⭐⭐⭐⭐ CI/CD, продакшн

7. Исключения и no_proxy: как обойти прокси для локальных адресов

В корпоративных и облачных окружениях часто нужна тонкая настройка: внешний трафик — через прокси, внутренний — напрямую. Переменная no_proxy (или NO_PROXY) позволяет задать список исключений.

# Базовые исключения
export no_proxy="localhost,127.0.0.1,::1"

# Исключение по домену (с точкой — все поддомены)
export no_proxy="localhost,127.0.0.1,.internal.company.com,.corp.local"

# Исключение по IP-диапазону (CIDR нотация работает не везде!)
export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

# Для AWS: исключаем metadata endpoint и внутренние адреса
export no_proxy="localhost,127.0.0.1,169.254.169.254,.amazonaws.com.internal"

⚠️ Важная особенность no_proxy:

CIDR-нотация (10.0.0.0/8) поддерживается не всеми инструментами. curl поддерживает её начиная с версии 7.86.0. wget — не поддерживает вообще. Для совместимости лучше перечислять конкретные IP или маски типа 10. (всё, что начинается с 10.).

Практический пример для Kubernetes-окружения, где нужно исключить API-сервер и внутренние сервисы:

export no_proxy="localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc,.default"
export NO_PROXY="${no_proxy}"

8. Прокси в CI/CD: GitHub Actions, GitLab CI, Docker

Настройка прокси в CI/CD-пайплайнах — одна из самых частых задач DevOps-инженеров, работающих в корпоративных сетях или с ограниченным доступом в интернет. Разберём конкретные конфигурации для популярных платформ.

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      http_proxy: ${{ secrets.PROXY_URL }}
      https_proxy: ${{ secrets.PROXY_URL }}
      no_proxy: "localhost,127.0.0.1,.github.com"
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Download dependencies
        run: |
          curl -x "${http_proxy}" https://external-api.example.com/config.json -o config.json
          wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://releases.example.com/app-v1.0.tar.gz

GitLab CI

# .gitlab-ci.yml
variables:
  http_proxy: "http://proxy.company.com:3128"
  https_proxy: "http://proxy.company.com:3128"
  no_proxy: "localhost,127.0.0.1,.gitlab.company.com"

build:
  stage: build
  script:
    - curl -x "${http_proxy}" https://registry.npmjs.org/package -o package.json
    - wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://example.com/resource.tar.gz

Docker: прокси при сборке образов

# Передача прокси через build args
docker build \
  --build-arg http_proxy=http://proxy.example.com:3128 \
  --build-arg https_proxy=http://proxy.example.com:3128 \
  --build-arg no_proxy=localhost,127.0.0.1 \
  -t myapp:latest .

# В Dockerfile используем ARG для получения переменных
# Dockerfile
FROM ubuntu:22.04

ARG http_proxy
ARG https_proxy
ARG no_proxy

ENV http_proxy=${http_proxy}
ENV https_proxy=${https_proxy}
ENV no_proxy=${no_proxy}

RUN apt-get update && apt-get install -y curl wget

RUN curl -x "${http_proxy}" https://example.com/setup.sh | bash

# Очищаем прокси-переменные в финальном образе (опционально)
ENV http_proxy=""
ENV https_proxy=""

Глобальная настройка прокси для Docker daemon (для docker pull через прокси):

# /etc/systemd/system/docker.service.d/proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=http://proxy.example.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.internal.registry.com"

# Перезапускаем docker
systemctl daemon-reload
systemctl restart docker

9. Ротация прокси в bash-скриптах

Если вам нужно делать большое количество запросов к внешним API или сервисам — ротация прокси позволяет распределить нагрузку и избежать блокировок по IP. Это особенно актуально при мониторинге цен, сборе данных или тестировании доступности ресурсов из разных регионов.

Для таких задач хорошо подходят прокси дата-центров — они обеспечивают высокую скорость и стабильность при массовых запросах.

#!/bin/bash
# rotate_proxy.sh — ротация прокси из списка

PROXY_LIST=(
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
)

URLS_FILE="urls.txt"
OUTPUT_DIR="./results"
mkdir -p "${OUTPUT_DIR}"

PROXY_COUNT=${#PROXY_LIST[@]}
INDEX=0

while IFS= read -r url; do
  PROXY="${PROXY_LIST[$INDEX]}"
  FILENAME=$(echo "${url}" | md5sum | cut -d' ' -f1)
  
  echo "Requesting: ${url} via proxy $((INDEX + 1))/${PROXY_COUNT}"
  
  curl -x "${PROXY}" \
       --max-time 30 \
       --retry 3 \
       --retry-delay 2 \
       --silent \
       --output "${OUTPUT_DIR}/${FILENAME}.html" \
       "${url}"
  
  if [ $? -eq 0 ]; then
    echo "  ✓ Success"
  else
    echo "  ✗ Failed, trying next proxy..."
    INDEX=$(( (INDEX + 1) % PROXY_COUNT ))
    curl -x "${PROXY_LIST[$INDEX]}" \
         --max-time 30 \
         --silent \
         --output "${OUTPUT_DIR}/${FILENAME}.html" \
         "${url}"
  fi
  
  # Переходим к следующему прокси
  INDEX=$(( (INDEX + 1) % PROXY_COUNT ))
  
  # Небольшая пауза между запросами
  sleep 0.5
  
done < "${URLS_FILE}"

echo "Done! Results saved to ${OUTPUT_DIR}"

Более продвинутый вариант — проверка работоспособности прокси перед использованием:

#!/bin/bash
# check_proxy.sh — проверка доступности прокси

check_proxy() {
  local proxy_url="$1"
  local test_url="https://api.ipify.org"
  
  result=$(curl -x "${proxy_url}" \
                --max-time 10 \
                --silent \
                --write-out "%{http_code}" \
                --output /dev/null \
                "${test_url}")
  
  if [ "${result}" -eq 200 ]; then
    echo "ALIVE"
  else
    echo "DEAD"
  fi
}

# Получаем внешний IP через прокси
get_proxy_ip() {
  local proxy_url="$1"
  curl -x "${proxy_url}" --max-time 10 --silent https://api.ipify.org
}

PROXY="http://user:[email protected]:3128"
STATUS=$(check_proxy "${PROXY}")
echo "Proxy status: ${STATUS}"

if [ "${STATUS}" == "ALIVE" ]; then
  EXTERNAL_IP=$(get_proxy_ip "${PROXY}")
  echo "External IP via proxy: ${EXTERNAL_IP}"
fi

10. Отладка и типичные ошибки

Работа с прокси неизбежно сопровождается ошибками — особенно при первоначальной настройке. Разберём самые распространённые проблемы и способы их диагностики.

Диагностика с помощью verbose-режима

# Максимально подробный вывод curl
curl -vvv -x http://proxy.example.com:3128 https://api.example.com/data 2>&1 | head -50

# Что смотреть в выводе:
# * Connected to proxy.example.com — соединение с прокси установлено
# CONNECT api.example.com:443 — запрос на туннель
# HTTP/1.1 200 Connection established — туннель открыт
# * SSL connection using TLS — TLS работает

# Отладка wget
wget -d -e use_proxy=yes -e http_proxy=http://proxy.example.com:3128 https://api.example.com/data

Типичные ошибки и решения

Ошибка Причина Решение
407 Proxy Authentication Required Не переданы учётные данные Добавить user:pass в URL прокси или флаг --proxy-user
Connection refused Неверный порт или прокси недоступен Проверить порт: nc -zv proxy.host 3128
SSL certificate error Корпоративный прокси с SSL-инспекцией Добавить корпоративный CA: --cacert /path/to/ca.crt
Could not resolve proxy DNS не резолвит имя прокси Использовать IP вместо имени или проверить DNS
Timeout Прокси медленный или перегружен Увеличить таймаут:

📚 Доступные языки