Перейти к содержимому

Squid: проброс интернета на удалённую ВМ

Бывает так: твоя ВМ в облаке не имеет публичного IP или доступ в интернет через NAT закрыт, а деплой требует wget/curl изнутри. Squid на промежуточном хосте с нормальным каналом решает проблему за десять минут.

Зачем это нужно

Пробрасываю интернет через Squid, когда ВМ в изолированном сегменте сети. Промежуточный хост с белым IP и доступом в сеть становится прокси-сервером. Приложение на удалённой машине ходит в интернет через туннель.

Реальные кейсы: тестовые стенды без внешней связности, CI/CD агенты в private subnet, временная маршрутизация трафика для отладки.

Установка и базовая настройка Squid

Ставлю на промежуточном хосте (Ubuntu/Debian):

apt update && apt install -y squid

Конфиг по умолчанию в /etc/squid/squid.conf. Минимальный рабочий конфиг:

# /etc/squid/squid.conf
http_port 3128

acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16

http_access allow localnet
http_access deny all

Запускаю и добавляю в автозагрузку:

systemctl enable --now squid

Проверяю, что слушает порт:

ss -tlnp | grep 3128

Настройка ACL и порта

Если нужен доступ только по SSH-туннелю с конкретного адреса, заменяю localnet на точный IP:

# Прокси доступен только с этого адреса
acl tunneled src 203.0.113.50

http_access allow tunneled
http_access deny all

Для смены порта:

http_port 8080

После изменения конфига применяю без рестарта:

squid -k reconfigure
Примечание

Если Squid не запускается после изменений, смотрю лог: journalctl -u squid -n 50.

SSH-туннель до ВМ

На удалённой машине поднимаю туннель к промежуточному хосту:

ssh -N -L 3128:localhost:3128 user@proxy-host

-N — не открывать shell, только проброс. -L привязывает локальный порт 3128 к localhost:3128 на удалённом хосте.

Для фона:

ssh -N -L 3128:localhost:3128 user@proxy-host &

Или через systemd user-сервис:

# ~/.config/systemd/user/proxy-tunnel.service
[Unit]
Description=SSH tunnel to proxy-host

[Service]
ExecStart=/usr/bin/ssh -N -L 3128:localhost:3128 user@proxy-host
Restart=always
RestartSec=10

[Install]
WantedBy=default.target
systemctl --user enable --now proxy-tunnel.service

Настройка прокси на клиенте

На удалённой ВМ ставлю переменные окружения для приложений с поддержкой http_proxy:

export http_proxy=http://localhost:3128
export https_proxy=http://localhost:3128

Или永久но в /etc/environment:

http_proxy=http://localhost:3128
https_proxy=http://localhost:3128

Для curl/wget достаточно переменных. Для apt — дополнительно:

echo 'Acquire::http::Proxy "http://localhost:3128";' | tee /etc/apt/apt.conf.d/99proxy

Проверяю:

curl -s --max-time 10 https://ifconfig.me

Если возвращает IP промежуточного хоста — работает.

Проверка и логирование

Лог обращений Squid:

tail -f /var/log/squid/access.log

Формат: время клиент/статус код размер метод URL

Пример строки:

1703123456.123  1024 192.168.1.100 TCP_MEM_HIT/200 5123 GET http://example.com/file.tar.gz

Коды ответа: TCP_HIT — взято из кэша, TCP_MISS — запрошено из сети, TCP_DENIED — доступ запрещён ACL.

Чтобы очистить кэш перед тестом:

squid -k shutdown && rm -rf /var/spool/squid/* && squid -z && systemctl start squid
ФлагОписание
http_portПорт прослушивания
acl name src IP/maskПравило доступа по IP
http_access allow|denyРазрешить или запретить ACL
-k reconfigureПеречитать конфиг
-k shutdownКорректно остановить
-zСоздать кэш-директории
Предупреждение

По умолчанию Squid кэширует ответы. Для отладки отключаю кэширование: cache deny all в конфиге, затем squid -k reconfigure.

Девять минут настройки — и изолированная ВМ ходит в интернет через прокси. Если нужен HTTPS-прозрачный режим с подменой сертификатов — это уже другая история с настройкой SSL-bump и генерацией CA.