Задача администратора в этом уроке - поставить между клиентами и внешним вебом промежуточное звено, которое решает кто и куда ходит, кэширует то, что можно переиспользовать, и оставляет лог для разбора инцидентов. Squid - это classic forward-прокси: запросы идут от клиентов наружу через него. Разберём squid.conf, списки доступа ACL и правила http_access, кэш, аутентификацию, прозрачный режим, логи и диагностику. И честно поговорим, где Squid в 2026 ещё уместен, а где его вытеснили.

Как это работает
Forward-прокси - это посредник для исходящего трафика. Клиент явно знает адрес прокси (например 192.168.1.10:3128) и отправляет ему HTTP-запрос целиком, включая строку GET с полным URL. Squid сам резолвит имя, открывает соединение к серверу назначения, тянет ответ, при необходимости кладёт копию в кэш и отдаёт клиенту. Это противоположность reverse-прокси (nginx перед бэкендом), где посредник работает от имени сервера, а не клиента.
Кэш экономит трафик и ускоряет повторные обращения. Squid опирается на HTTP-заголовки кэширования: Cache-Control, Expires, ETag, Last-Modified. Если объект свежий (не истёк), Squid отдаёт его из кэша без обращения наружу - это HIT. Если объект устарел, Squid делает условный запрос (If-None-Match / If-Modified-Since) и при ответе 304 освежает копию. Если объекта нет или он запрещён к кэшированию - MISS, идём в сеть. Кэш бывает в памяти (cache_mem) и на диске (cache_dir).
Контроль доступа - это сердце конфига. Сначала вы описываете ACL - именованные множества (диапазоны IP, порты, домены, методы, регулярки на URL, время суток). Сами по себе ACL ничего не разрешают и не запрещают, это просто метки. Решения принимают директивы http_access allow и http_access deny, которые проверяются СВЕРХУ ВНИЗ и срабатывают на первом совпадении. Правила ниже сработавшего уже не смотрятся. Важнейшее следствие: порядок строк определяет логику, а в самом конце всегда стоит неявный deny all противоположный последнему явному правилу.
Прозрачный (intercept) режим - это когда клиент НЕ настроен на прокси, а трафик заворачивается на Squid фаерволом (в 2026 это nftables, исторически iptables через REDIRECT/TPROXY). Squid слушает порт со специальным флагом intercept и достаёт адрес назначения из перехваченного соединения. Минус режима известен: для HTTPS он честно работать не может без подмены сертификата, потому что клиент думает что говорит напрямую с сайтом, а внутри TLS никакого заголовка Host для прокси нет.
Команды и примеры
Установка. В Debian 13 / Ubuntu 24.04 пакет и конфиг в /etc/squid/, в RHEL 10 / Fedora 41+ аналогично, но управление через dnf:
Код: Выделить всё
# Debian / Ubuntu
apt install squid
systemctl enable --now squid
# RHEL / Fedora
dnf install squid
systemctl enable --now squid
Код: Выделить всё
# порт прокси
http_port 3128
# ACL - это просто именованные множества
acl localnet src 192.168.1.0/24
acl SSL_ports port 443
acl Safe_ports port 80 21 443 70 210 1025-65535
acl CONNECT method CONNECT
# запрещаем CONNECT куда угодно кроме 443
http_access deny CONNECT !SSL_ports
http_access deny !Safe_ports
# доступ к менеджеру только локально
acl localhost src 127.0.0.1/32
http_access allow localhost manager
http_access deny manager
# разрешаем своей сети, остальным запрет
http_access allow localnet
http_access deny all
Код: Выделить всё
cache_mem 512 MB
maximum_object_size_in_memory 1 MB
# каталог 10 ГБ, 16 каталогов 1-го и 256 2-го уровня
cache_dir aufs /var/spool/squid 10000 16 256
maximum_object_size 256 MB
Код: Выделить всё
systemctl stop squid
squid -z # инициализация swap-каталогов
systemctl start squid
Код: Выделить всё
squid -k parse # проверить синтаксис, ничего не запуская
squid -k reconfigure
Код: Выделить всё
# Debian: htpasswd из apache2-utils, RHEL: из httpd-tools
htpasswd -c /etc/squid/passwd ivan
Код: Выделить всё
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm Proxy CyberLake
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
http_access deny all
Код: Выделить всё
http_port 3129 intercept
Код: Выделить всё
# nftables (актуально 2026)
nft add rule ip nat prerouting ip saddr 192.168.1.0/24 tcp dport 80 redirect to :3129
# iptables (наследие, для экзамена)
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3129
Код: Выделить всё
tail -f /var/log/squid/access.log
# поля: время длит. клиент HIT/MISS статус байты метод URL ...
# живая статистика через cache manager
squidclient -h 127.0.0.1 mgr:info
squidclient mgr:5min
Частые грабли
- Порядок http_access. Если allow localnet стоит выше deny на запрещённый домен - запрет не сработает, потому что решение принято на первом совпадении.
- Забыли deny all в конце. Неявное правило инвертирует последнее явное, и поведение становится неочевидным. Всегда ставьте явный http_access deny all последней строкой.
- Не сделали squid -z. Демон стартует, но кэш на диск не пишется, всё мимо. Сначала остановить службу, потом инициализировать.
- SELinux на RHEL/Fedora блокирует нестандартный cache_dir или порт. Симптом - permission denied в cache.log при правильных правах. Чините через semanage port -a и контексты, не отключением SELinux.
- Ждать кэширования HTTPS в прозрачном режиме без SSL-bump. Внутри TLS прокси ничего не видит, объекты не кэшируются, только CONNECT-туннель.
- Правка squid.conf без squid -k parse. Опечатка валит демон при reconfigure, и вы узнаёте об этом, когда сеть уже встала.
- Думать что Squid сам себя обновит при reload. После смены cache_dir или auth_param чаще нужен полный restart, reconfigure не всё подхватывает.
- Поставьте squid, запустите squid -k parse - убедитесь что дефолтный конфиг валиден.
- Опишите acl localnet на свою подсеть, разрешите её, в конце поставьте deny all. Перечитайте конфиг через squid -k reconfigure.
- На клиенте пропишите прокси и откройте дважды одну статичную страницу. В access.log найдите TCP_MISS и затем TCP_HIT.
- Добавьте acl badsite dstdomain .example.com и http_access deny badsite ВЫШЕ allow localnet. Проверьте TCP_DENIED в логе.
- Включите basic-аутентификацию, заведите пользователя htpasswd, убедитесь что без логина прокси отдаёт 407.
- Через squidclient mgr:info посмотрите Request Hit Ratio и число клиентов.
- В каком порядке Squid проверяет правила http_access и что происходит при первом совпадении?
- Чем отличается определение ACL от директивы http_access и может ли ACL сам по себе что-то разрешить?
- Зачем нужна команда squid -z и почему её делают при остановленном демоне?
- Почему прозрачный режим не кэширует HTTPS без SSL-bump и в чём тут принципиальная проблема?
- Какой код в access.log говорит, что объект отдан из кэша, а какой - что запрос зарезан правилом доступа?
- Чем basic_ncsa_auth отличается по безопасности от digest или внешнего LDAP-хелпера и где это критично?