Настройка кеширующего squid-прокси

Table of Contents
В этой заметке разберемся, как поднять прокси для dnf/apt или в целом для http/https и направить траффик через него.
Для начала расскажу зачем вообще занялся этим, так как проксировать траффик можно кучей способов, почему именно симпл-димпл-прокси, а не просто VPN или что-то такое.
Вместо вступления #
У нас было:
- Компьютер, подключённый в локальную сеть через маршрутизатор и к внешней сети.
- Сервер, на котором крутятся базы данных, который подключён в локальную сеть и не имеющий доступ к внешней;
- Сервер, на котором крутятся приложения, который подключен в локальную сеть и не имеющий доступ к внешней.
Я просто в край ________ бегать с флешкой, подключать монитор к серверам и работать руками прям там, или же
заливать на какую-то шару необходимые пакеты, выкачивать их и возиться с установкой через SSH, а потом еще и какой-то
зависимости как обычно не хватит и ничего не поставить и тд. Короче, кто хоть раз сталкивался с автономно работающим
сервером, на который требуется установить какой-то пакет сейчас явно почувствовал жжение чуть ниже поясницы. Хочется
простого и понятного dnf install -y the-best-app-pkg.
Начальная конфигурация сети #
В моём примере будет несколько маршрутизаторов в одной локальной сети, это нужно будет в дальнейшем, чтобы проксировать траффик из одной “локальной” сети в другую.
На компьютере настроены маршруты, чтобы только определенный траффик шел в локальную сеть (запросы типа 192.168.ххх.ххх и похожие), а остальной траффик тёк через внешнюю сеть.
sudo ip route add 192.168.10.0/24 dev wlo1 via 192.168.90.1
sudo ip route add 172.15.0.0/24 dev wlo1 via 192.168.90.1
Где:
192.168.10.0/24локальная сеть до моего маршрутизатора;172.15.xxx.0/24локальная сеть до маршрутизатора сети192.168.10.0/24;192.168.90.0/24локальная сеть после моего маршрутизатора (в которой и находится мой компьютер);192.168.90.1gateway для маршрутов на моём компьютере.
Следите за руками, как говорится, потому что важно не запутаться на этом этапе из какой сети в какую мы будем двигать траффик.
Кто такой Squid #

Squid-proxy - это популярный, высокопроизводительный и бесплатный прокси-сервер с открытым исходным кодом, предназначенный для кэширования и фильтрации трафика. Он работает как посредник между пользователями и интернетом, поддерживая HTTP, HTTPS и FTP, что ускоряет загрузку сайтов, оптимизирует пропускную способность сети и повышает безопасность корпоративных сетей.
Настраиваем squid #
Устанавливаем пакет #
Будем настраивать прокси на машине с fedora. Нам требуется установить 5-ю версию squid:
sudo dnf install -y squid-7:5.8-1.fc38.x86_64
Возможно настройка адекватно будет работать и на 6 и на 7 версии, но мы проверили только на 5.
Генерируем сертификаты #
Для поддержки HTTPS нам требуется сгенерировать SSL-сертификаты.
Предварительно установим OpenSSL, если его не было в системе:
sudo dnf install -y openssl
Далее создадим папку для сертификатов, перейдем в нее и сгенерируем SSL-сертификат:
sudo mkdir /etc/squid/ssl_cert && \
sudo cd /etc/squid/ssl_cert && \
sudo openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout myCA.pem -out myCA.pem
В процессе генерации сертификата нас попросят заполнить регион, область, страну, организацию, домен и нашу почту, заполняем примерно так:
Country Name (2 letter code) [XX]:RU
State or Province Name (full name) []:Leningrad Oblast
Locality Name (eg, city) [Default City]:St. Petersburg
Organization Name (eg, company) [Default Company Ltd]:local
Organizational Unit Name (eg, section) []:local
Common Name (eg, your name or your server's hostname) []:proxy.local
Email Address []:proxy@server.local
Далее даем права на папку с сертификатами squid:
chown -R :squid /etc/squid/ssl_cert
Далее обновляем нашу базу ssl-сертификатов:
sudo rm -rf /var/lib/ssl_db /var/spool/squid/ssl_db
sudo /usr/lib64/squid/security_file_certgen -c -s /var/lib/ssl_db -M 4MB && \
sudo /usr/lib64/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB
На выходе должны получить:
Initialization SSL db...
Done
Проверяем какие права имеет эта папка:
sudo ls -lah /var/spool/squid | grep ssl_db
Если видим такую картину:
drwxr-xr-x. 1 root root 36 Oct 21 08:39 ssl_db
Следует поменять права:
sudo chown -R squid:squid /var/spool/squid/ssl_db
Если же:
drwxr-xr-x. 1 squid squid 36 Oct 21 08:39 ssl_db
То все впорядке, можно ничего не менять.
Настройка selinux для squid #
Добавим новые политики:
sudo semanage fcontext -a -t squid_conf_t '/var/spool/squidssl_db/index.txt' && \
sudo semanage fcontext -a -t squid_conf_t '/var/spool/squid/ssl_db/size' && \
sudo /sbin/restorecon -v /var/spool/squidssl_db/index.txt && \
sudo /sbin/restorecon -v /var/spool/squidssl_db/size
После этого требуется перезагрузить операционную систему, чтобы политики вступили в силу.
Конфигурация squid #
Можно сразу взять мой конфиг, заменить им свой и перейти к созданию каталогов для кеша.
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
http_access allow all
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localhost
http_access deny to_localhost
http_access deny to_linklocal
http_access deny all
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/ssl_cert/myCA.pem
ssl_bump peek all
ssl_bump bump all
cache_dir ufs /var/spool/squid 4096 32 256
coredump_dir /var/spool/squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
После блока acl Safe_ports разрешаем все соединения (эта настройка имеет самый высокий преоритет, так как находится выше всех остальных правил):
http_access allow all
Ищем строку http_port 3128 и меняем настройку на эту:
http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/ssl_cert/myCA.pem
ssl_bump peek all
ssl_bump bump all
Далее настроим размер кеша. Ищем строку cache_dir и меняем ее на:
cache_dir ufs /var/spool/squid 4096 32 256
Где:
4096– размер кеша в мегабайтах;32– количество каталогов первого уровня, которое будет создано для размещения кэша;256– количество каталогов второго уровня, которое будет создано для размещения кэша.
Сохраняем и останавливаем сервис, теперь нужно создать все нужные каталоги:
sudo systemctl stop squid && \
sudo squid -z
Запускаем сервис и смотрим логи, все должно завестись без ошибок:
sudo systemctl restart squid.service && \
sudo systemctl status squid.service
Пробрасываем порты на роутере #
Так как машина с прокси стоит в сети ЗА маршрутизатором (сеть 192.168.90.0/24), а наши целевые машины стоят в сети 192.168.10.0/24, на маршрутизаторе следует прокинуть порты. В нашем случае используется Mikrotik c RouterOS v7.6.
Для проброса портов идем в WebFig -> IP -> Firewall -> NAT, нажимаем Add New и добавляем новое правило, указав настройки:
Chain: dstnat
Protocol: 6 (tcp)
Dst. Port: 3128
In. Interface: ether1 #Это мой интерфейс, куда приходит сеть 192.168.10.0
Action: dst-nat
To Adresses: 192.168.90.250 #Это адрес машины с прокси в сети 192.168.90.0
To Ports: 3128
Проксируем трафик #
Настроим целевые машины, с которыз должен идти запрос на прокси и дальше в сеть до зеркал.
Наша машина, на которой крутится прокси, в сети 192.168.10.0/24 доступна по адресу 192.168.10.250 и порту 3128,
следовательно адрес нашей машины с прокси будет 192.168.10.250:3128. Если тут стало что-то непонятно, обратитесь к начальной конфигурации,
где освещалась схема сети.
Настройка пакетных менеджеров #
Логинимся по ssh или панель управления сервером, в терминале прокидываем переменную окружения:
export HTTP_PROXY="http://192.168.10.250:3128" && \
export HTTPS_PROXY="http://192.168.10.250:3128"
В случае с apt нужно дополнительно подкинуть прокси в файл настроек. Создаем файл proxy.conf:
sudo vim /etc/apt/apt.conf.d/proxy.conf
И вставляем конфиг:
Acquire::http::Proxy "http://192.168.10.250:3128";
Acquire::https::Proxy "http://192.168.10.250:3128";
Настройка Docker #
Добавляем настройку для сервиса:
sudo mkdir -p /etc/systemd/system/docker.service.d
Добавляем наш прокси в настройки сервиса:
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.10.250:3128"
Environment="HTTPS_PROXY=http://192.168.10.250:3128"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
Перезапускаем демоны и перезапускаем Docker:
sudo systemctl daemon-reload && \
sudo systemctl restart docker
Настройка Yarn #
По умолчанию Yarn не знает, что у вас используется прокси и вы будете получать ошибку, вроде:
➤ YN0000: · Yarn 4.9.1
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: ⠹ ==============------------------------------------------------------------------
at ClientRequest.<anonymous> (/home/<username>/.cache/node/corepack/v1/yarn/4.9.1/yarn.js:147:14258)
at Object.onceWrapper (node:events:622:26)
at ClientRequest.emit (node:events:519:35)
at c.emit (/home/armstrong/.cache/node/corepack/v1/yarn/4.9.1/yarn.js:142:14855)
at emitErrorEvent (node:_http_client:104:11)
at TLSSocket.socketErrorListener (node:_http_client:518:5)
at TLSSocket.emit (node:events:507:28)
at emitErrorNT (node:internal/streams/destroy:170:8)
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21)AggregateError [EHOSTUNREACH]:
at internalConnectMultiple (node:net:1139:18)
at internalConnectMultiple (node:net:1215:5)
at afterConnectMultiple (node:net:1714:7)
При этом, как в случае и с Docker, у вас уже были прокинуты все прокси…
Сами разработчики Yarn, по непонятной для меня причине, предлагают использовать глобальный или локальный (в проекте) файл настроек .yarnrc.yml, и в нем указывать нужные нам настройки. Это не совсем удобно, тем более у Yarn очень хорошая CLI. Мы просто сделаем так:
yarn config set httpProxy http://192.168.20.78:3128 && \
yarn config set httpsProxy http://192.168.20.78:3128
http-proxy и https-proxy соответственно.Благодарности серому волшебнику #
Если текст был полезен и ты не можешь усмирить желание быть благодарным, то можешь:
Воспользоваться моей реферальной ссылкой на DigitalOcean:
Или же закинуть монету в мой кошелёк (USDT и TRX кошельки одинаковые, да, это не ошибка):
Tether (TRC-20, USDT):
TYvFYUV3h5HwqfyTxskGQK7nDbUHTcwPn2
Tron (TRX):
TYvFYUV3h5HwqfyTxskGQK7nDbUHTcwPn2
Monero (XMR):
4AbxbT9vrNQTUDCQEPwVLYZq2zTEYzNr9ZzTLaq9YcwVfdxwkWjZ6FsewuXVDXPk7x2rE6FZACmLePPgJEcY4rm1GSHkwTZ