Инструкция по настройке Squid HTTP-proxy в корпоративной среде.

В данной инструкции решается задача по настройке прокси-сервера Squid для контроля интернет-доступа пользователей.

Что включает в себя статья:

  1. Подготовка OpenSSL и Squid.

  2. Настройка запуска через systemd.

  3. Настройка аутентификации пользователей на основе Kerberos и LDAP.

  4. Настройка SSL-Bump (MITM).

  5. Настройка лога и перенаправление на сборщик логов.

  6. Настройка дополнительных фич.

  7. Пример простого полного конфигурационного файла.

Squid будет устанавливаться не в стандартную директорию, а так же использовать OpenSSL установленный рядом (что бы не заморачиваться с уже установленным OpenSSL или не навредить системе + получим последнюю версию OpenSSL).

ВНИМАНИЕ: В статье часто используются блоки кода с командами. Перед выполнением рекомендуется просмотреть что вы делаете и обратить внимание на комментарии, в них могут содержаться важные замечания.


1) Подготовка OpenSSL и Squid.

В первую очередь необходимо определиться с модулями (ключами компиляции) Squid и OpenSSL.

Лучше использовать необходимый минимум, что бы уменьшить количество точек обхода защиты (Данная статься скорее о настройке, чем о безопасности…).

Загрузка, сборка и установка пакета OpenSSL.

Официальный репозиторий: https://github.com/openssl/openssl.

wget https://github.com/openssl/openssl/releases/download/openssl-3.6.1/openssl-3.6.1.tar.gz
tar -xzf openssl-3.6.1.tar.gz
cd openssl-3.6.1
	# apt install build-essential pkg-config # Установка компилятора C
./config shared --prefix=/opt/squid/openssl \
	--openssldir=/opt/squid/openssl \
	-Wl,-rpath=/opt/squid/openssl/lib64		# -Wl,... говорит компилятору: «передай всё, что после запятой, линковщику # -rpath=/opt/squid/openssl/lib опция для линковщика: «встрой в исполняемый файл путь к библиотекам» 
	
make 
make install

ldd /opt/squid/openssl/bin/openssl # Проверить зависимости и доустановить при их отсутствии

Загрузка, сборка и установка пакета Squid.

Официальный репозиторий: https://github.com/squid-cache/squid

# Нужны зависимости для пакета
apt install \
	libtirpc-dev \
	libldap2-dev \
	libsasl2-dev \
	pkg-config \
	libpam0g-dev \
	libkrb5-dev \
	libtdb-dev \
	libcap-dev \
	libnetfilter-conntrack-dev \
	libcppunit-dev \
	heimdal-clients

# GitHub - https://github.com/squid-cache/squid
# Вы можете использвоать последнюю всерию, а совместимость инструкций squid посмотреть на официальном файле в документации: https://www.squid-cache.org/Versions/v7/cfgman/index_all.html#toc_accept_filter
wget https://github.com/squid-cache/squid/releases/download/SQUID_7_5/squid-7.5.tar.gz
tar -zxf squid-7.5.tar.gz
cd squid-7.5


# Конфигурация может пройти успешно, но функционал будет недоступен из за нехватка какой то из библиотек
# Внимательно иследуйте ошибки и предупреждения
# КОММЕНТАРИИ УДАЛИТЬ перед применением
./configure \
  --prefix=/opt/squid \                          # Основной каталог установки Squid
  --sysconfdir=/opt/squid/etc \                  # Каталог для конфигурационных файлов (squid.conf и др.)
  --localstatedir=/opt/squid/var \               # Базовый каталог для переменных данных (логи, кэш, PID и т.д.)
  --libexecdir=/opt/squid/libexec \              # Каталог для вспомогательных исполняемых файлов (например, ssl_crtd)
  --with-swapdir=/opt/squid/var/cache/squid \    # Директория кэша на диске
  --with-logdir=/opt/squid/var/log/squid \       # Директория для лог-файлов
  --with-pidfile=/opt/squid/var/run/squid.pid \  # Путь к файлу PID процесса Squid
  --with-default-user=proxy \                    # Пользователь, от которого будет запускаться Squid
  --enable-auth-negotiate=kerberos \             # Поддержка аутентификации Negotiate/Kerberos
  --enable-auth-basic=LDAP,PAM \                 # Поддержка Basic-аутентификации через LDAP и PAM
  --enable-external-acl-helpers=time_quota,unix_group,SQL_session,file_userip,kerberos_ldap_group,LDAP_group \  # Внешние ACL-хелперы для расширенного контроля доступа
  --enable-icap-client \                         # Поддержка ICAP-протокола (интеграция с антивирусами и DLP)
  --enable-delay-pools \                         # Включение ограничения пропускной способности (traffic shaping)
  --enable-cache-digests \                       # Поддержка Cache Digests для кооперативного кэширования
  --enable-follow-x-forwarded-for \              # Учитывать заголовок X-Forwarded-For при определении IP клиента
  --enable-eui \                                 # Поддержка определения MAC-адреса клиента (EUI-48/EUI-64)
  --enable-esi \                                 # Поддержка Edge Side Includes (для кэширования динамических фрагментов)
  --enable-icmp \                                # Использовать ICMP для оценки сетевой задержки (pinger)
  --enable-wccp \                                # Поддержка Web Cache Communication Protocol (Cisco и др.)
  --enable-linux-netfilter \                     # Интеграция с Netfilter (для TPROXY и прозрачного проксирования)
  --enable-storeio=rock \                        # Использовать storeio "rock" — высокопроизводительный кэш-движок на основе SQLite
  --enable-removal-policies=heap,lru \           # включает все доступные политики удаления объектов из хранилища (например, heap, LRU‑производные и др.)
  --disable-arch-native \                        # Отключить оптимизации под конкретную архитектуру CPU (для переносимости)
  --disable-translation \                        # Отключить локализацию интерфейса (оставить только английский)
	# для ssl-dump:
  --enable-ssl \								 # включает поддержку ssl режима
  --enable-ssl-crtd \                            # Включить генерацию сертификатов для HTTPS-трафика (SSL Bump) # генерацией сертификатов занимается отдельный процесс, а не сам прокси сервер.
  --with-openssl=/opt/squid/openssl             # Указать собственную сборку OpenSSL (важно для SSL Bump)


make all
make install

# Проверить завивимости, скорее всего чего то будет не хватать
ldd /opt/squid/sbin/squid
# Установим необходимую зависимость для работы Squid и AD
sudo apt-get install libsasl2-modules-gssapi-mit 

2) Настройка запуска через systemd.

Создаем файл сервиса /etc/systemd/system/squid.service c содержимым:

[Unit]
Description=Squid Web Proxy Server (custom build)
Documentation=man:squid(8)
After=network.target network-online.target nss-lookup.target

[Service]
# Путь к файлу keytab можно указать здесь или напрямую в squid.conf > "auth_param negotiate program...-k <FullPath>", в моем случае укажу там
# Environment=KRB5_KTNAME=/opt/squid/etc/squid.keytab
Type=forking
PIDFile=/opt/squid/var/run/squid.pid
ExecStartPre=/opt/squid/sbin/squid -z                     # Инициализация кэша Squid
ExecStart=/opt/squid/sbin/squid
ExecReload=/opt/squid/sbin/squid -k reconfigure
ExecStop=/opt/squid/sbin/squid -k shutdown
User=root                                                                  # Squid запускается от root, для использования socket, потом переходит в режим пользователя указанного в конфигурации.
Group=root
LimitNOFILE=65536
# Restart=on-failure
# RestartSec=10

[Install]
WantedBy=multi-user.target

3) Настройка аутентификации пользователей на основе Kerberos и LDAP.

Потребуется: - Пользователь Active Directory (AD) для Kerberos и LDAP, создается в оснастке “Пользователи и компьютеры”. - Токен keytab сгенерированный на DC AD, для Kerberos аутентификации. - Настроить клиентскую часть Kerberos на сервере со Squid. - Настроить конфигурацию Squid на использование хелперов работы с Kerberos и LDAP. - Настройка аутентификации пользователей на основе Kerberos. - Настройка определения группы пользователя на основе LDAP.

Создание токена keytab - Windows AD DC

Keytab-файл - что это и зачем

Keytab-файл нужен ТОЛЬКО для самого Squid-сервера. Он не используется пользователями, а позволяет Squid проверять тикеты клиентов (временные пропуска)

Keytab — это файл с зашифрованными ключами службы, привязанный к SPN (Service Principal Name) вида: HTTP/servername.domain.ru@DOMAIN.RU Этот SPN зарегистрирован в Active Directory на уровне учётной записи сервера (например, UserAD_Squid или компьютерной учётной записи)

Логика работы: Шаг 1: Клиент получает тикет - Пользователь ivanov на Windows-машине в домене заходит на сайт через прокси. - Браузер автоматически запрашивает у DC (контроллера домена) тикет для службы HTTP/servername.domain.ru Шаг 2: Squid проверяет тикет - Squid получает тикет от клиента - Чтобы расшифровать его и узнать, кто пользователь, Squid использует свой keytab - Если расшифровка успешна, то пользователь подтверждён как ivanov@DOMAIN.RU

Keytab — это “приватный ключ” для службы HTTP/servername.domain.ru, Без него Squid не может проверить подлинность тикета

  1. Keytab не содержит паролей пользователей, он содержит только ключи для одной службы HTTP/servername.domain.ru

  2. Каждый клиент использует свой собственный тикет Keytab. Squid позволяет проверить любой тикет, выданный для HTTP/servername.domain.ru, но не генерирует тикеты для клиентов.

  3. Если украсть keytab - можно подделать прокси, поэтому его нужно хранить с правами 600 и владельцем службы Squid (в нашем случае proxy)

Регистрация на DC AD SPN аккаунта (создание keytab):

# Создать учетку пользователя в AD

# Регистрируем SPN для этой учётной записи AD
# setspn /S <Принцепал> <sAMAccountName пользователя>
setspn /S HTTP/servername.domain.ru ADUserSquid
# Проверяем
setspn /L squid
# Генерируем keytab
ktpass /princ HTTP/servername.domain.ru@DOMAIN.RU `
	/mapuser ADUserSquid@DOMAIN.RU `
	/crypto ALL ` # Для простоты можно добавить все кодировки в файл
	/ptype KRB5_NT_PRINCIPAL `
	/pass password_ADUserSquid `
	/out C:\squid.keytab
# Проверяем
setspn /L squid

### Если в keytab помещали толькуо одну кодировку, можно добавить в 1 файл keytab
### AES128 — ДОБАВЛЯЕМ к существующему файлу
# ktpass /princ HTTP/servername.domain.ru@DOMAIN.RU `
#   /mapuser ADUserSquid@DOMAIN.RU `
#   /crypto AES128-SHA1 `
#   /ptype KRB5_NT_PRINCIPAL `
#   /pass password_ADUserSquid `
#   /in C:\squid.keytab `
#   /out C:\squid.keytab

# Если нужно удалить SPN
# setspn /D HTTP/servername.domain.ru ADUserSquid

# Копируем C:\squid.keytab на сервер squid

# Зададим файлу следующие права:
chown proxy:proxy /opt/squid/etc/squid.keytab
chmod 600 /opt/squid/etc/squid.keytab

# Если нужно проверить, что keytab содержит нужный SPN (linux)
klist -kte squid.keytab
	# Keytab name: FILE:squid.keytab
	# KVNO Timestamp           Principal
	# ---- ------------------- ------------------------------------------------------
	#   11 01/01/1970 03:00:00 HTTP/servername.domain.ru@DOMAIN.RU

Должен быть ТОЛЬКО ОДИН пользователь, сопоставленный одной записью SPN (HTTP/<имя сервера с сервисом Squid в нижнем регистре>@<realm Active Directory в верхнем регистре>) Если несколько разных пользователей сопоставленных с записью SPN, то проверка подлинности Kerberos будет ВСЕГДА НЕУДАЧНОЙ

Настройка клиентской части Kerberos на сервере со Squid.

Установка:

### Подготовка
### ВЫПОЛНЯЙТЕ ОБДУМАННО!!!
# Остановить и удалить winbind, samba, если был установлен до этого squid с авторизацией в AD через NTLM
#	sudo systemctl stop winbind smbd nmbd
#	sudo apt purge winbind samba samba-common smbclient -y
#	sudo apt autoremove -y
# Удалить старые конфиги (если есть)
#	sudo rm -f /etc/samba/smb.conf
#	sudo rm -f /etc/krb5.conf

# Ставим нужные lib
sudo apt install -y \
    krb5-user \    # если не стало то проверить есть ли зависимость libkrb5-3 - может быть версия зависимости таже что нужна просто "патченная осью OS"
    libkrb5-dev \
    libldap2-dev \
    libsasl2-dev \
    ldap-utils

Содержимое файла /etc/krb5.conf

[libdefaults]
	default_realm = DOMAIN.RU          # Основной домен AD
	dns_lookup_realm = false                  # Не искать realm через DNS
	dns_lookup_kdc = true                     # Искать контроллеры через DNS SRV-записи
	ticket_lifetime = 24h                     # Время жизни билета
	renew_lifetime = 7d                       # Время обновления билета
	forwardable = true                        # Разрешить делегирование билета
	rdns = false                              # Не использовать обратный DNS (улучшает безопасность)
	
	# Используйте для отключения контроля кодировки 
	# (закоментируйте default_tgs_enctypes, default_tkt_enctypes, permitted_enctypes, что бы не переопределяли allow_weak_crypto)
	# allow_weak_crypto = true

# Установить определенный AES
	# - Default Ticket Granting Service encryption types. Определяет список шифров, которые клиент будет запрашивать по умолчанию, когда обращается к сервису (TGS) за билетом доступа к конкретной службе (например, к HTTP-сервису Squid).
	# Когда ваш браузер или утилита kinit запрашивает билет для HTTP/servername...`, она скажет контроллеру домена: «Пожалуйста, выдай билет, зашифрованный только через `aes256-cts-hmac-sha1-96`». Она даже не будет упоминать другие типы (AES128, RC4, DES).
	default_tgs_enctypes = aes256-cts-hmac-sha1-96  # aes128-cts-hmac-sha1-96
		# Default Ticket (TGT) encryption types. Определяет список шифров, которые клиент будет запрашивать по умолчанию при первоначальной аутентификации для получения TGT (Ticket Granting Ticket) — главного билета сессии пользователя.
		# При входе в домен система попросит контроллер выдать главный билет (TGT), зашифрованный только через `aes256`.
	default_tkt_enctypes = aes256-cts-hmac-sha1-96  # aes128-cts-hmac-sha1-96
		# Permitted encryption types. Он задает «белый список» шифров, которые системе разрешено использовать вообще.
	
	permitted_enctypes = aes256-cts-hmac-sha1-96    # aes128-cts-hmac-sha1-96 rc4-hmac

[realms]
	DOMAIN.RU = {
		kdc = DC1.domain.ru						# Контроллер домен
		kdc = DC2.domain.ru
		admin_server = DC1.domain.ru				# Сервер администрирования
		default_domain = domain.ru
	}

[domain_realm]
	.domain.ru = DOMAIN.RU				# Автоматическое сопоставление домена
domain.ru = DOMAIN.RU
# Проверяем keytab
# Пробуем получить билет
kinit -V -k -t /opt/squid/etc/squid.keytab HTTP/servername.domain.ru@DOMAIN.RU
# Смотрим билет
klist
# -----------------  Если не прошло
	### Проверьте кодировку. может AES не та 
	# очистите кэш
	kdestroy -A
# -----------------
Пример аутентификации пользователей на основе Kerberos в конфиге squid.conf:
visible_hostname servername.DOMAIN.RU
httpd_suppress_version_string on
cache_effective_user proxy

http_port 3128

debug_options ALL,1 33,2 28,2 50,2 # подробный лов для debug
access_log stdio:/opt/squid/var/log/squid/access.log
cache_log stdio:/opt/squid/var/log/squid/cache.log

# Аутентификация Kerberos
auth_param negotiate program /opt/squid/libexec/negotiate_kerberos_auth 
    -d /
    -k /opt/squid/etc/squid.keytab /
    -s HTTP/servername.domain.ru@DOMAIN.RU
auth_param negotiate children 20
auth_param negotiate keep_alive on

# Доступ всем прошедшим аутентификацию
acl auth proxy_auth REQUIRED
http_access allow auth
Пример определения группы пользователя на основе LDAP в конфиге squid.conf:
visible_hostname servername.DOMAIN.RU
httpd_suppress_version_string on
cache_effective_user proxy

http_port 3128

access_log stdio:/opt/squid/var/log/squid/access.log
cache_log stdio:/opt/squid/var/log/squid/cache.log

auth_param negotiate program /opt/squid/libexec/negotiate_kerberos_auth \
    -d \
    -k /opt/squid/etc/squid.keytab \
    -s HTTP/servername.domain.ru@DOMAIN.RU

############################################################################
# АУТЕНТИФИКАЦИЯ LDAP. Поиск пользователя в группе AD
external_acl_type ldap_Squid_ADGroup_InternetAccess \
	ttl=300 negative_ttl=60 \
	%LOGIN /opt/squid/libexec/ext_kerberos_ldap_group_acl \
    -g ADGroup_InternetAccess \
    -D DOMAIN.RU \
    -u ADUserSquid@DOMAIN.RU \
	-p password_ADUserSquid \  # иной способ передачи пароля не пройдет, только в явном виде
	-l ldap://DOMAIN.RU
# Должно идти после инструкций external_acl_type
acl politics_Squid_ADGroup_InternetAccess_From_AD external ldap_Squid_ADGroup_InternetAccess

acl politics_authenticated proxy_auth REQUIRED
# Запрет для не авторизованных
http_access deny !politics_authenticated
# Доступ для групп AD - ADGroup_InternetAccess
http_access allow politics_Squid_ADGroup_InternetAccess_From_AD
# Запретить все остальное
http_access deny all
Если появляются ошибки, то для проверки хелперов можно использовать это:
# На сервере Squid

### Хелпер ext_kerberos_ldap_group_acl 
echo "ADUserSquid@DOMAIN.RU ADGroup_InternetAccess" | \
sudo -u proxy /opt/squid/libexec/ext_kerberos_ldap_group_acl \
    -n \
    -g ADGroup_InternetAccess \
    -D DOMAIN.RU \
    -u ADUserSquid@DOMAIN.RU\
    -p "$(cat /opt/squid/etc/ldap.pass)" \  # или сразу password_ADUserSquid
    # -p password_ADUserSquid \
    -l ldap://dc1.DOMAIN.RU # Можено указать конкретный DC
    
###################

### Хелпер negotiate_kerberos_auth 
sudo -u proxy /opt/squid/libexec/negotiate_kerberos_auth \
	-k /opt/squid/etc/squid.keytab \
	-s HTTP/servername.domain.ru@DOMAIN.RU
# Если просто ожидает (зависло) - то все OK, по крайней мере на уровке keytab и принцепала

Попробуйте поискать здесь: Исправление частых ошибок Squid при настройке Kerberos MS AD DC


4) Настройка SSL-Bump (MITM).

Немного полезной информации по работе SSL-Bump (Данный блок несет информационный характер, можно пропустить)

Server Name Indication (SNI) — расширение компьютерного протокола TLS, которое позволяет клиенту указывать имя хоста, с которым он пытается соединиться, во время процесса «рукопожатия» (первоначального установления соединения)

Цель SNI — позволить серверу предоставлять несколько сертификатов на одном IP-адресе и TCP-порту, что позволяет работать нескольким безопасным (HTTPS) сайтам (или другим сервисам поверх TLS) на одном IP-адресе без использования одного и того же сертификата на всех сайтах

Вскрытие HTTPs трафика Squid

Когда клиент (браузер) инициирует HTTPS-соединение через прокси, Squid не может просто так прочитать зашифрованный трафик. Ему нужно перехватить рукопожатие (Handshake), подменить сертификат сервера своим (который мы сгенерируем или PKI) и установить два отдельных TLS-туннеля

Этапы проверки соединения внутри Squid

Процесс ssl_bump разбит на три логических этапа. Директивы acl … at_step … позволяют тебе сказать Squid: «На этом конкретном этапе проверь вот эти условия и реши, что делать дальше»

SslBump1 - этап приветствия

  • Когда: Сразу после получения пакета ClientHello от клиента

    • Что известно Squid:

    • IP-адрес клиента

    • Порт назначения

    • SNI (Server Name Indication) — имя домена, которое клиент хочет посетить (например, google.com). Это критически важно, так как на этом этапе трафик еще не расшифрован полностью, но SNI передается в открытом виде

    • Версии протоколов и шифры, предложенные клиентом

  • Что НЕ известно: Полный URL (путь /path), заголовки HTTP, контент. Сертификат сервера еще не получен Squid’ом от удаленного хоста

  • Зачем нужен: Чтобы принять решение: блокировать ли соединение сразу по домену (SNI), пропустить ли его без проверки (bypass) или перейти к следующему этапу для глубокой инспекции

SslBump2 - этап серверного сертификата

  • Когда: После того как Squid связался с целевым сервером и получил от него сертификат (ServerHello + Certificate), но до того, как он отправил поддельный сертификат клиенту.

  • Что известно Squid:

    • Всё, что было на этапе 1.

    • Данные сертификата реального сервера: Subject, Issuer, даты validity, SAN (Subject Alternative Names), наличие EV-расширений.

    • Squid уже знает, совпадает ли сертификат с ожидаемым доменом.

  • Зачем нужен: Самый мощный этап для фильтрации. Ты можешь проверить: - Кто выпустил сертификат? (Блокировать самоподписанные или неизвестные CA). - Действителен ли сертификат? - Совпадает ли CN/SAN с SNI?

    • Если всё ок — Squid генерирует свой сертификат “на лету” (подписанный твоим локальным CA) и отдает его клиенту.

SslBump3 - этап установленного туннеля

  • Когда: После завершения рукопожатия с клиентом. Туннель установлен.

  • Что известно Squid:

    • Полностью расшифрованный поток данных (так как Squid теперь стоит посередине с двумя ключами).

    • Теперь это работает как обычный HTTP-трафик внутри туннеля. Доступны методы HTTP, полные URL, заголовки, куки.

  • Зачем нужен: Обычно используется для финальных проверок перед тем, как просто пропускать трафик (peek -> splice или окончание bump). В современных версиях Squid большая часть логики фильтрации контента делается уже после этого этапа стандартными ACL (url_regex, mime_type и т.д.), но здесь можно принять решение прервать соединение, если что-то пошло не так при установке туннеля.

Инструкция ssl_bump

ssl_bump <action> [!]acl ...
	# <action>: Что делать с трафиком (splice, bump, peek, stare, terminate).
	# [!]acl_name: Необязательное условие. Если указан ACL, действие применяется только если запрос соответствует этому ACL. Знак ! инвертирует условие («если НЕ соответствует»)

Action

  1. splice - Стать TCP-туннелем без расшифровки трафика. Действие по умолчанию

    • Клиент общается напрямую с сервером. Squid не видит содержимое, не видит URL, не видит заголовки. Видит только IP и порт.

    • Клиент получает настоящий сертификат от целевого сервера. Цепочка доверия не нарушается. Когда использовать:

    • Для сайтов, где запрещена подмена сертификатов (Banking, Google, некоторые корпоративные порталы с Certificate Pinning).

    • Для повышения производительности (нет нагрузки на CPU для шифрования/расшифровки).

    • Для приватных доменов, которые ты не хочешь инспектировать. Нюанс этапов:

    • На SslBump1: Туннель создается сразу после получения SNI. Сертификат сервера даже не запрашивается Squid’ом.

    • На SslBump2/3: Если мы уже сделали peek или stare, то splice завершает процесс инспекции и превращает соединение в простой туннель для остальной сессии.

  2. bump - Полноценная атака MITM. Расшифровка, инспекция и повторное шифрование Как работает:

    • На SslBump1: Squid завершает рукопожатие с клиентом, используя свой сертификат (подписанный твоим локальным CA). Только после этого он идет к реальному серверу.

    • На SslBump2: Squid уже получил сертификат реального сервера, проверяет его, генерирует новый сертификат «на лету» (клонируя Subject, SAN, но подписывая своим ключом) и отдает его клиенту.

    • На SslBump3: Обычно здесь bump уже не имеет смысла, так как туннель установлен. Но технически это подтверждение продолжения расшифровки. Два независимых TLS-канала: Клиент<->Squid и Squid<->Сервер. Squid видит всё в открытом виде (URL, cookies, контент). Клиент видит сертификат, выпущенный твоим локальным CA. Требуется установка этого CA в доверенные корни на всех клиентах, иначе браузер выдаст ошибку NET::ERR_CERT_AUTHORITY_INVALID. Когда использовать:

    • Для полной фильтрации контента (антивирус, блокировка категорий, DLP).

    • Для аудита трафика. Риски: Ломает приложения с жестким пиннингом сертификатов (HPKP, хотя сейчас редко, или app-specific pinning).

  3. peek - Посмотреть данные рукопожатия, но оставить возможность позже стать простым туннелем (splice). Это гибридный режим, введенный для гибкости.

Как работает:

- На `SslBump1`: Squid читает `ClientHello` (видит SNI), но не завершает рукопожатие с клиентом сразу. Он переходит к шагу 2.

- На `SslBump2`: Squid соединяется с сервером, получает его настоящий сертификат, анализирует его (можно проверить ACL по имени в сертификате, issuer, сроку действия), но еще не отправляет клиенту поддельный сертификат.

Ключевая особенность: После peek на следующем этапе ты можешь выбрать splice. Если ты выберешь splice после peek на шаге 2, Squid передаст **оригинальный **сертификат сервера клиенту и станет прозрачным туннелем.

Зачем нужно: Чтобы принять решение о подмене (bump) на основе данных сертификата сервера, но если условия не подходят — честно пробросить трафик (splice), не ломая доверие клиента.

  • Пример: «Посмотри сертификат (step2). Если он выпущен известным CA — сделай splice (не ломай). Если самоподписанный — сделай bump (инспектируй, так как всё равно доверия нет)».

Это значит: если ты сделал peek на шаге 2, а потом на шаге 3 решил делать bump, это может не сработать корректно или быть неэффективным, так как момент для инициирования подмены с клиентом мог быть упущен. Обычно цепочка peek -> bump используется реже, чем peek -> splice. Чаще peek используют, чтобы решить: bump или splice.

  1. stare - Посмотреть данные рукопожатия, но оставить возможность позже сделать полную подмену (bump). Тоже гибридный режим, но с противоположной целью по сравнению с peek.

Ключевая особенность: После stare ты планируешь сделать bump. Это позволяет принять решение о подмене на основе информации, полученной от сервера.

  • Пример: «Посмотри сертификат сервера (step2). Если в нем есть определенное расширение или он от конкретного Issuer — тогда делай bump. Иначе — splice».

Это значит: если ты сделал stare на шаге 2, путь назад к честному splice (передача оригинального сертификата) может быть закрыт или сложен. Протокол предполагает, что ты готовишься к активной подмене.

  1. terminate - Немедленно закрыть соединение с обеих сторон.

Как работает:

  • Squid рвет TCP-соединение. Клиент получает ошибку соединения (часто ERR_CONNECTION_RESET или ERR_SSL_PROTOCOL_ERROR).

  • Когда использовать:

    • Блокировка доступа к запрещенным ресурсам (черный список доменов через SNI на шаге 1).

    • Обнаружение недопустимых сертификатов (например, истекший срок, несоответствие имени, отзыв CRL/OCSP) на шаге 2.

    • Защита от атак или подозрительного поведения при рукопожатии.

Пример использования команд:

# 1. Определяем этапы
acl step1 at_step SslBump1 # ClientHallo
acl step2 at_step SslBump2 # ClientHallo + Certificate
acl step3 at_step SslBump3 # как обычный HTTP-трафик внутри туннеля. Доступны методы HTTP, полные URL, заголовки, куки.

# 2. Списки доменов
acl sites_to_bypass ssl_dom_regex (google\.com|bank\.ru|.*\.local$)
# Тоже самое только через файл 
acl sites_to_bypass regex "/etc/squid/lists/bypass_regex.txt"
	# Каждая строка - это отдельное регулярное выражение
	# Экранировать точки нужно обязательно
	# google\.com
	# bank\.ru
	# .*\.local$
acl sites_to_bypass dstdomain "/etc/squid/lists/bypass_sites.txt" 
	# для файла Один домен на строку
	# Чтобы охватить домен и все его поддомены, ставь точку в начале (.domain.com).
	# Комментарии начинаются с `#`.

# ssl_cert_error - Aвтоматически попадает в категорию «плохих», если **проверка сертификата сервера выявила ошибку**.
	# Это встроенный механизм Squid для валидации SSL-сертификатов на этапе `SslBump2` (когда Squid уже получил сертификат от целевого сайта, но еще не отдал свой клиенту).
acl bad_certs ssl_cert_error

# 3. Логика Step 1 (SNI)
# Если домен в списке исключений - сразу делаем туннель (splice), даже не смотрим сертификат сервера.
# Это экономит ресурсы и гарантирует 100% совместимость.
ssl_bump splice step1 sites_to_bypass

# Если домен в списке блокировки - рвем сразу.
# ssl_bump terminate step1 blacklisted_domains

# Для всех остальных - смотрим дальше (peek), чтобы получить сертификат сервера.
# Смотрим на ClientHello всех соединений (чтобы узнать SNI/домен)
ssl_bump peek step1

# 4. Логика Step 2 (Сертификат сервера)
# Если сертификат вызывает ошибки (истек, неверное имя) - рвем.
ssl_bump terminate step2 bad_certs

# Если сертификат от доверенного публичного CA и сайт не требует инспекции - можно сделать splice.
# (Здесь мы используем преимущество peek: мы видели сертификат, решили не ломать и пробросили оригинал).
ssl_bump splice step2 trusted_public_sites

# Для всего остального - применяем полную подмену (bump).
# Мы уже видели сертификат (благодаря peek на шаге 1 и переходе сюда), теперь генерируем свой.
ssl_bump bump step2

# 5. Логика Step 3
# Если мы дошли сюда, значит туннель с подменой установлен. Просто продолжаем работу.
ssl_bump splice step3

Подготовка Системы и Squid для SSL-Bump

# openssl # Добавьте следующую строку в раздел [v3_ca] файла конфигурации openssl.cnf 
	# Разрешает использовать этот сертификат для подписи других сертификатов
	# Разрешает использовать этот ключ для подписи списков отозванных сертификатов
	keyUsage = cRLSign, keyCertSign

# Подготовьте среду для хранения SSL-сертификатов
mkdir /opt/squid/etc/ssl -p
chown proxy:proxy /opt/squid/etc/ssl -R
chmod 700 /opt/squid/etc/ssl -R
cd /opt/squid/etc/ssl
# Создаем самоподписанный сертификат
openssl req -new -newkey rsa:4096 -sha256 -days 365 -nodes -x509 -extensions v3_ca -keyout squid_ca.pem -out squid_ca.pem
# Преобразуйте созданный сертификат в формат DER
openssl x509 -in squid_ca.pem -outform DER -out squid_ca.der
	# Экспортируйте сгенерированный сертификат на клиентские компьютеры и установите его на них как сертификат центра сертификации. Способ выполнения этого действия зависит от браузера и операционной системы клиента

# Создайте новую базу данных SSL для сервера Squid:
# Обатитье внимание, директория ssl_db должна создаваться сама при выплнении команды
mkdir /opt/squid/var/lib -p
/opt/squid/libexec/security_file_certgen -c -s /opt/squid/var/lib/ssl_db -M 4MB
chown proxy:proxy /opt/squid/var/lib -R
Пример конфигурации с SSL-Bump - squid.conf

Для добавления инспекции заменяется одна строка http_port 3128 на это:

# Прослушиваемый порт
http_port 3128 ssl-bump cert=/opt/squid/etc/ssl/squid_ca.pem generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

# Этапы проверки SSL
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3

# Политика доменов без SSL-инспекции
acl politics_sites_no-inspection dstdomain "/opt/squid/etc/sites_no-inspection"

# Проверяем сертификат сервера на ошибки (истек, самоподписанный, имя не совпадает и т.д.)
# Создаем ACL, который истинен, если есть ЛЮБАЯ из перечисленных ошибок
# Squid объединяет строки с одинаковым именем acl по OR
acl politics_bad_certs ssl_error certHasExpired		# Срок действия сертификата истек ERR_CERT_DATE_INVALID
acl politics_bad_certs ssl_error certNotYetValid	# Сертификат еще не начал действовать
acl politics_bad_certs ssl_error certUntrusted		# Издатель сертификата (Certificate Authority, CA) не доверяется Squid'ом
acl politics_bad_certs ssl_error certSelfSigned		# Сертификат подписан самим же владельцем сайта, а не независимым центром
acl politics_bad_certs ssl_error certDomainMismatch	# Имя домена, к которому ты обращаешься, не совпадает с именем, указанным в сертификате

# Пропускать без SSL-инспекции SNI из списка
ssl_bump splice step1 politics_sites_no-inspection

# Смотрим SNI и переходим к шагу 2, чтобы получить сертификат сервера.
ssl_bump peek step1

# Теперь у нас есть сертификат сервера. Проверяем его валидность.
# Если сертификат плохой -> рвем соединение.
# ssl_bump terminate step2 politics_bad_certs

# вскрываем (bump) все остальные соединения
# Сюда попадут все, кроме банков и сайтов с плохими сертификатами
ssl_bump bump step2
# Просто продолжаем работу
ssl_bump splice step3

# Укажите расположение и параметры исполняемого файла для генератора сертификатов. security_file_certgen -h #help
sslcrtd_program /opt/squid/libexec/security_file_certgen -s /opt/squid/var/lib/ssl_db -M 4MB

5) Настройка лога и перенаправление на сборщик логов.

Для настройки стоит обратиться к документации официального сайта Там можно найти подробное описание как:

  • не писать лог для нужных ACL.

  • писать лог в файл.

  • отправлять лог по UDP/TCP.

  • писать лог в системный журнал.

Пример с отправкой лога доступа через syslog:

  • Лог расширен и праведен к формату JSON

Более подробно: примеры приведения формата лога к JSON

Проверялись не все, поэтому могут быть ошибки

"timestamp": "%ts.%03tu",          # Время: Unix-timestamp с миллисекундами (основа для таймлайна)
"time_human": "%tl"           # Для человека (стандартный вид: 25/Oct/2023:14:30:05 +0300)
"time_iso": "%tl{%Y-%m-%dT%H:%M:%S %z}" # Для человека и сортировки (2023-10-25T14:30:05 +0300)
"date": "%tl{%Y-%m-%d}" # Для человека
"time": "%tl{%H:%M:%S}" # Для человека
"tz": "%z"


"client_ip": "%>a",           # IP-адрес клиента (источник запроса)
"client_port": "%>p",         # Порт клиента (источник)
"client_mac": "%>eui",        # MAC-адрес клиента (EUI-48/64), если доступен в сети
"user": "%[un",               # Имя пользователя (из Auth, External ACL или SSL Cert)
"auth_user": "%ul",           # Имя пользователя строго из аутентификации (Basic/NTLM/Kerberos)
"external_user": "%ue",       # Имя пользователя из external_acl helper
"ssl_user": "%us",            # Имя из Subject SSL-сертификата клиента
"http_method": "%rm",         # Метод запроса (GET, POST, CONNECT и т.д.)

"url": "%ru",                 # Полный URL запроса (после редиректов и адаптации)
"raw_url": "%>ru",            # URL точно так, как прислал клиент (до изменений Squid)
"upstream_url": "%<ru",       # URL, который фактически ушел на сервер назначения

#"domain": "%{host}ru",       # Домен из URL (удобно для фильтрации по сайтам)
"path": "%rp",                # Путь к ресурсу без домена и протокола

"http_version": "%rv",        # Версия HTTP протокола (1.0, 1.1, 2)
"http_status": "%>Hs",        # HTTP код ответа, отправленный клиенту (200, 403, 502)
"upstream_status": "%<Hs",    # HTTP код ответа, полученный от сервера/родителя

"squid_status": "%Ss",        # Статус кэша/действия Squid (TCP_HIT, TCP_MISS, TCP_DENIED, ERR_...)
"hierarchy": "%Sh",           # Откуда взяты данные (DEFAULT_PARENT, FIRST_PARENT, NONE)

"size_response": "%<st",      # Размер тела ответа, отправленного клиенту (байты)
"size_request": "%>st",       # Размер тела запроса от клиента (байты)
"size_total_traffic": "%st",  # Общий трафик сделки (запрос + ответ)

"response_time_ms": "%tr",    # Общее время обработки запроса (мс)
"dns_time_ms": "%dt",         # Время, затраченное на DNS-резолвинг (мс)
"peer_time_ms": "%<pt",       # Время ответа от вышестоящего прокси/сервера (мс)
"forwarding_time_ms": "%<tt", # Общее время форвардинга (включая DNS, ACL, retries)

"mime_type": "%mt",           # MIME-тип контента (text/html, image/jpeg, application/json)

"referer": "%{Referer}>h",    # Заголовок Referer (откуда пришел пользователь)
"user_agent": "%{User-Agent}>h", # Заголовок User-Agent (браузер/бот/ОС)
"content_range": "%<sH",      # Смещение конца переданного объекта (для частичного контента)
"upstream_obj_size": "%<sS",  # Полный размер объекта на источнике (даже если отдана часть)
"req_attempts": "%[http::]request_attempts", # Количество попыток пересылки (ретраи)

"conn_id": "%transport::>connection_id",   # Уникальный ID транспортного соединения (для корреляции) # Чтобы связать строки, относящиеся к одному физическому TCP-соединению (Keep-Alive)
"master_xid": "%master_xaction",             # ID мастер-транзакции (монотонный счетчик внутри воркера) # Чтобы связать части одного файла (Range requests) или запросы в рамках одной вкладки браузера

"local_ip": "%>la",           # Локальный IP, на который подключился клиент (важно при мульти-IP)
"local_port": "%>lp",         # Локальный порт, на который подключился клиент

"server_ip": "%<a",           # IP адреса сервера назначения (последний хоп)
"server_fqdn": "%<A",         # FQDN сервера назначения или имя пира
"server_port": "%<p",         # Порт сервера назначения

"QoS_value": "%>qos",         # Значение TOS/DSCP пакета клиента (Quality of Service)
"netfilter_mark": "%>nfmark", # Netfilter MARK пакета (если используется интеграция с iptables/nftables)
"ssl_bump_mode": "%ssl::bump_mode",       # Режим SSL Bump (peek, bump, splice, stare, terminate)
"ssl_sni": "%ssl::>sni",                  # SNI (Server Name Indication) от клиента
"ssl_client_subject": "%ssl::>cert_subject", # Subject сертификата клиента (если есть mTLS)
"ssl_client_issuer": "%ssl::>cert_issuer",   # Issuer сертификата клиента
"ssl_server_subject": "%ssl::<cert_subject", # Subject сертификата сервера назначения
"ssl_server_issuer": "%ssl::<cert_issuer",   # Issuer сертификата сервера назначения
"ssl_cert_errors": "%ssl::<cert_errors",     # Список ошибок валидации сертификата сервера
"ssl_tls_version": "%ssl::>negotiated_version", # Согласованная версия TLS (TLSv1.2, TLSv1.3)
"ssl_cipher": "%ssl::>negotiated_cipher",     # Согласованный шифр (ECDHE-RSA-AES256-GCM-SHA384)

"ssl_client_hello_ver": "%ssl::>received_hello_version", # Версия TLS в ClientHello
"ssl_max_supported_ver": "%ssl::>received_supported_version", # Макс. версия TLS, поддерживаемая клиентом
"handshake_data": "%>handshake", # Сырые байты рукопожатия (Base64), полезно для детекции протоколов
"error_code": "%err_code",      # Внутренний код ошибки Squid (если запрос не успешен)
"error_detail": "%err_detail",  # Детальное описание ошибки (разделено '+')
"busy_time_ns": "%busy_time",   # Время CPU, затраченное Squid на эту транзакцию (нс, экспериментально)
"adapt_total_ms": "%adapt::sum_trs", # Суммарное время работы ICAP/eCAP сервисов (мс)
"adapt_times_list": "%adapt::all_trs", # Список времени каждого ICAP/eCAP вызова отдельно
"proxy_src_addr": "%{proxy_protocol::>h{:src_addr}", # Реальный IP из заголовка PROXY Protocol (если используется балансировщик)
"proxy_dst_addr": "%{proxy_protocol::>h{:dst_addr}", # Реальный IP назначения из PROXY Protocol
"note_annotation": "%note",    # Пользовательские аннотации (метаданные) от адаптеров или скриптов
# Определение формата лога
logformat squid_json {"datetime":"%tl{%Y-%m-%d} %tl{%H:%M:%S}","client_ip":"%>a","client_port":"%>p","auth_user":"%ul","http_method":"%rm","url":"%ru","http_version":"%rv","http_status":"%>Hs","squid_status":"%Ss","hierarchy":"%Sh","size_response":"%<st","size_request":"%>st","mime_type":"%mt","user_agent":"%{User-Agent}>h","conn_id":"%transport::>connection_id","master_xid":"%master_xaction","server_ip":"%<a","server_fqdn":"%<A","server_port":"%<p","QoS_value":"%>qos","ssl_bump_mode":"%ssl::bump_mode","ssl_sni":"%ssl::>sni","ssl_tls_version":"%ssl::>negotiated_version","ssl_cipher":"%ssl::>negotiated_cipher"}

# Записывает каждый запрос, обработанный Squid, в файл access.log
# Cтандартный шаблон
access_log stdio:/opt/squid/var/log/squid/access.log
# Дополнительно отправляет каждый запрос, обработанный Squid, в файл access.log
# Шаблон JSON
access_log udp://10.0.0.41:5141 squid_json

# Служебные сообщения Squid ошибки, предупреждения, отладочная информация
cache_log stdio:/opt/squid/var/log/squid/cache.log

Если не используется SSL-Bump, то некоторые поля могут быть пустыми или ‘-’


6) Настройка дополнительных фич.

6.1) Настройка кэширования.

Уровень

Где хранится

Для чего

Настройка

RAM-кэш

Оперативная память

Быстрый доступ к маленьким/частым объектам

cache_mem

Дисковый кэш

Жёсткий диск/SSD

Хранение больших объектов (картинки, обновления)

cache_dir

Объект сначала попадает в RAM → если долго не запрашивается — перемещается на диск → если место заканчивается — удаляется

# cache_mem <объём>
# Использовать до 1 ГБ RAM для кэша
cache_mem 1024 MB
	# Объекты ≤ cache_mem → хранятся только в RAM
	# Объекты > cache_mem → сразу идут на диск
# cache_dir <тип> <путь> <размер_МБ> [L1] [L2]
	# - <L1> — количество каталогов первого уровня (обычно 16) - В старых Unix-файловых системах (ext2, UFS) было жёсткое ограничение: содержание файлов в 1 каталоге
	# - <L2> — количество каталогов второго уровня (обычно 256) - 

#### Один кэш на SSD (рекомендуется)
# Squid рассматривает все cache_dir как единое пространство хранения
# Rock — современный движок для SSD/NVMe
cache_dir rock /opt/squid/var/cache/rock1 20000  # 20 ГБ
Пример использования в конфиге squid.conf
# ACL для обновлений
acl ubuntu dstdomain .archive.ubuntu.com
acl security_ubuntu dstdomain security.ubuntu.com
acl windows_update dstdomain .windowsupdate.com .update.microsoft.com
# Кэшировать ТОЛЬКО эти домены
cache allow ubuntu
cache allow security_ubuntu
cache allow windows_update
cache deny all

############

# ACL для внутренних ресурсов
acl intranet dstdomain .dd.local .yourcompany.local
# Запретить кэширование внутренних сайтов
cache deny intranet
# Разрешить кэширование всего остального
cache allow all

############

### Кэшировать только картинки и CSS
# ACL для статики
acl static_content urlpath_regex -i \.(jpg|jpeg|png|gif|css|js)$
# Кэшировать только статику
cache allow static_content
cache deny all

############

### Разные кэши для разных сетей
# Сети
acl office src 10.0.1.0/24
acl warehouse src 10.0.2.0/24
# Office: кэшировать всё
cache allow office
# Warehouse: кэшировать только обновления
acl updates dstdomain .windowsupdate.com
cache allow warehouse updates
# Остальное — не кэшировать
cache deny all

Дополнительные параметры:

### Максимальный размер объекта в кэше
# Не кэшировать файлы больше 100 МБ
maximum_object_size 100 MB
# Минимальный размер (по умолчанию 0)
minimum_object_size 0 KB

### Время хранения объектов
# Обновления ОС — кэшировать дольше
refresh_pattern -i \.(deb|rpm|msi|exe)$ 10080 90% 43200 override-expire
# Обычные страницы — стандартное время
refresh_pattern . 0 20% 4320

6.2) Настройка ограничения скорости.

Возможно вы захотите использовать группы AD для ограничения скорости, но как говорит официальная инструкция, директива delay_class работает только с acl типа “fast”.

Если вы знаете способ обойти это ограничение, прошу подсказать как… Пробовал так же вариант с добавлением пользовательского header для группы, и после определять в пул по наличию этого заголовка header, но столкнулся с ошибкой (увы, уже не вспомню с каклй именно)

В Squid delay_parameters указываются в байтах в секунду, а не в битах.

# Формула: Мбит/с → байты/сек
# (Мбит × 1_000_000) ÷ 8 = байты/сек

# Примеры:
# 10 Мбит/с  → (10 × 1_000_000) ÷ 8 = 1_250_000 байт/сек
# 50 Мбит/с  → (50 × 1_000_000) ÷ 8 = 6_250_000 байт/сек
# 100 Мбит/с → (100 × 1_000_000) ÷ 8 = 12_500_000 байт/сек
# 1 Гбит/с   → (1000 × 1_000_000) ÷ 8 = 125_000_000 байт/сек

Squid проверяет пулы по порядку номеров (сначала 1, потом 2). Первый пул, где запрос получает allow, применяется. Если получает deny — переходит к следующему пулу

# Проверяем Пул 1
delay_access 1 deny politics_Squid_InternetAccess_speed-full  # Группе ЗАПРЕЩЕН Пул 1
delay_access 1 allow all                                      # Остальным РАЗРЕШЁН Пул 1

# Проверяем Пул 2 (если не попали в Пул 1)
delay_access 2 allow politics_Squid_InternetAccess_speed-full # Группе РАЗРЕШЁН Пул 2
# (остальным доступ к Пулу 2 неявно запрещён)
Немного теории про классы delay

Алгоритм “Token Bucket” (ведро с токенами)

Squid использует алгоритм, где “байты” — это “токены”, которые:

  • Накапливаются в “ведре” до размера макс (burst)

  • Тратятся при передаче данных

  • Пополняются со скоростью восст (байт/сек)

delay_parameters <пул> <aggregate_max/aggregate_restore> <individual_max/individual_restore>
	# aggregate_max - Общий "буст" на всех пользователей (3750000) 
	# aggregate_restore - Общая пропускная способность пула (~30 Мбит/с) (3750000)
	# individual_max - Макс. "буст" для одного пользователя (640000)
	# **individual_restore - Скорость для одного пользователя (~5.12 Мбит/с) (640000)

Больше информации по классам delay в оф. документации

delay_class - Class 1

delay_class 1 - одно общее ведро на всех.

delay_pools 1
delay_class 1 1                     # Пул №1 использует Class 1
delay_access 1 allow all            # Применить ко всем клиентам
delay_parameters 1 3750000/3750000  # Только общий лимит
  1. Все клиенты делят одно ведро.

  2. Когда любой пользователь передаёт данные — токены списываются из общего пула.

  3. Если ведро пусто — все пользователи ждут, пока оно не пополнится.

  4. Нет понятия “мой личный лимит” — только “наш общий лимит”.

delay_class - Class 2

delay_class 2 - двухуровневое ограничение: общий пул + индивидуальные лимиты

Синтаксис для Class 2

delay_class <пул> 2

delay_parameters 1 3750000/3750000 640000/640000

# Умножаем на 8, чтобы перевести байты в биты.

Правила передачи данных:

  1. Когда пользователь запрашивает данные, Squid проверяет оба ведра:

    • Есть ли токены в его индивидуальном ведре?

    • Есть ли токены в общем ведре пула?

  2. Если хотя бы одно ведро пусто → передача приостанавливается до пополнения.

  3. Токены списываются из обоих вёдер одновременно.

# Один пользователь
Пользователь А качает файл
→ Тратит из своего individual (640 КБ/сек) 
→ И из aggregate (3.75 МБ/сек)
→ Фактическая скорость: ~5 Мбит/сек (лимит individual)

# Пять пользователей одновременно
Каждый хочет 5 Мбит/с → сумма 25 Мбит/с
→ Aggregate лимит: 30 Мбит/с → все получают ~5 Мбит/с

Но если 7 пользователей:
→ 7 × 5 = 35 Мбит/с > 30 Мбит/с (aggregate)
→ Начинается "дележка": каждый получит ~4.3 Мбит/с

# Короткий всплеск (burst)
Пользователь начинает загрузку:
→ Может мгновенно использовать до 640 КБ из индивидуального "бака"
→ И до 3.75 МБ из общего "бака"
→ После исчерпания — работает только на скорости восстановления

Если хотите ограничить только по индивидууму

# Общий пул делаем "бесконечным" (очень большое значение)
delay_parameters 1 -1/-1 640000/640000
# -1 = без лимита (только individual). отключает лимит для соответствующего параметра.

delay_class - Class 3

Class 3 — это самый гибкий и сложный тип. Он объединяет логику Class 1 и Class 2, добавляя третий уровень ограничений, который обычно привязывается к сетевым подсетям (CIDR).

Это идеально подходит для провайдеров или крупных офисов, где нужно ограничивать:

  1. Весь канал целиком.

  2. Отдельных пользователей внутри канала.

  3. Целые отделы/подсети (например, “Бухгалтерия” или “Гостевой Wi-Fi”).

delay_class <пул> 3
delay_parameters <пул> <net_max/net_restore> <individual_max/individual_restore> <connection_max/connection_restore>

В вашем случае параметры интерпретируются так:

  1. Network (Сеть/Подсеть) — лимит для группы IP-адресов (подсети).

  2. Individual (Индивидуальный) — лимит для одного IP/пользователя.

  3. Connection (Соединение)Примечание: В старых версиях Squid третий параметр мог называться иначе, но в современной реализации Class 3 обычно использует структуру: Network / Individual / Connection или Aggregate / Network / Individual в зависимости от версии и патчей. Однако стандартная документация Squid для Class 3 описывает три уровня:

Пример конфигурации:

delay_pools 1
delay_class 1 3
delay_access 1 allow all

# Лимиты:
# 1. Для всей подсети (Network): 10 Мбит/с
# 2. Для одного пользователя (Individual): 2 Мбит/с
# 3. Для одного соединения (Connection): 500 Кбит/с
delay_parameters 1 1250000/1250000 250000/250000 62500/62500

7) Пример простого полного конфигурационного файла.

  • Аутентификация пользователей Kerberos + LDAP

  • Списки запрещенных сайтов

  • Настройки лога, кэша

  • Ограничение скорости (3 пула)

  • SSL-Bump

  • Log format JSON

  • Log отправка на Graylog

############################################################################
###### Squid обрабатывает правила доступа последовательно сверху вниз ######
######               Применяется первое найденное правило             ######
############################################################################

visible_hostname testproxy.DOMAIN.RU     # имя хоста, которое Squid будет использовать в HTTP-заголовках, страницах ошибок, при логировании (в некоторых форматах лога)
httpd_suppress_version_string on            # Отключает отображение версии Squid HTTP-заголовках, Страницах ошибок
cache_effective_user proxy                  # От какого пользователя Squid будет работать после запуска


############################################################################
# SSL-Bump

# Прослушиваемый порт
http_port 3128 ssl-bump cert=/opt/squid/etc/ssl/squid_ca.pem generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

# Этапы проверки SSL
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3

# Политика доменов без SSL-инспекции
acl politics_sites_no-inspection dstdomain "/opt/squid/etc/sites_no-inspection"

# Проверяем сертификат сервера на ошибки (истек, самоподписанный, имя не совпадает и т.д.)
# Создаем ACL, который истинен, если есть ЛЮБАЯ из перечисленных ошибок
# Squid объединяет строки с одинаковым именем acl по OR
acl politics_bad_certs ssl_error certHasExpired         # Срок действия сертификата истек ERR_CERT_DATE_INVALID
acl politics_bad_certs ssl_error certNotYetValid        # Сертификат еще не начал действовать
acl politics_bad_certs ssl_error certUntrusted          # Издатель сертификата (Certificate Authority, CA) не доверяется Squid'ом
acl politics_bad_certs ssl_error certSelfSigned         # Сертификат подписан самим же владельцем сайта, а не независимым центром
acl politics_bad_certs ssl_error certDomainMismatch     # Имя домена, к которому ты обращаешься, не совпадает с именем, указанным в сертификате

# Пропускать без SSL-инспекции SNI из списка
ssl_bump splice step1 politics_sites_no-inspection

# Смотрим SNI и переходим к шагу 2, чтобы получить сертификат сервера.
ssl_bump peek step1

# Теперь у нас есть сертификат сервера. Проверяем его валидность.
# Если сертификат плохой -> рвем соединение.
ssl_bump terminate step2 politics_bad_certs

# вскрываем (bump) все остальные соединения
ssl_bump bump step2
# Просто продолжаем работу
ssl_bump splice step3

# Генератор сертификатов
sslcrtd_program /opt/squid/libexec/security_file_certgen -s /opt/squid/var/lib/ssl_db -M 4MB


############################################################################
# ЛОГИ

# Интерфейсы сервера # Коды ошибок
error_directory /opt/squid/share/errors/en

# Отключить сбор статистики сетевых задержек (файл ...squid/netdb.state)
netdb_low 0
netdb_high 0

# Определение формата лога
logformat squid_json {"datetime":"%tl{%Y-%m-%d} %tl{%H:%M:%S}","client_ip":"%>a","client_port":"%>p","auth_user":"%ul","http_method":"%rm","url":"%ru","http_version":"%rv","http_status":"%>Hs","squid_status":"%Ss","hierarchy":"%Sh","size_response":"%<st","size_request":"%>st","mime_type":"%mt","user_agent":"%{User-Agent}>h","conn_id":"%transport::>connection_id","master_xid":"%master_xaction","server_ip":"%<a","server_fqdn":"%<A","server_port":"%<p","QoS_value":"%>qos","ssl_bump_mode":"%ssl::bump_mode","ssl_sni":"%ssl::>sni","ssl_tls_version":"%ssl::>negotiated_version","ssl_cipher":"%ssl::>negotiated_cipher"}


# Записывает каждый запрос, обработанный Squid, в файл access.log
access_log stdio:/opt/squid/var/log/squid/access.log squid_json
access_log udp://10.0.0.7:5141 squid_json

# Служебные сообщения Squid ошибки, предупреждения, отладочная информация
cache_log stdio:/opt/squid/var/log/squid/cache.log

############################################################################
# КЭШ

# максимальный объем памяти для кэширования объектов
cache_mem 2048 MB
# Определяет место, где Squid будет хранить закэшированные данные
# Используется тип кэша rock, который оптимизирован для быстрого доступа
# Путь, где будет храниться кэш
# размер кэша в 10 ГБ (размер в мегабайтах)
cache_dir rock /opt/squid/var/cache/rock1 10000  # 10 ГБ
# Отвечает за управление объектами в дисковом кэше
# Помогает решать, какие объекты следует удалить из кэша при его заполнении, основываясь на частоте их использования
cache_replacement_policy lfuda
# Определяет, как Squid будет управлять заменой объектов в оперативной памяти
# Оптимизирует управление памятью, минимизируя фрагментацию и обеспечивая более быстрый доступ к данным
memory_replacement_policy heap

### Ограничения времени для обновления кэша и управления терминами, в течение которых объекты будут считаться "свежими".
# Этот шаблон применяет правило к FTP-ресурсам (все URL, начинающиеся с ftp:)
        # 9 - минимальное время, через которое объект может быть обновлён (в минутах).
        # 10% - процент изменения, необходимый для повторного обновления кэшированного объекта.
        # 10 - максимальное время, в течение которого объект может оставаться в кэше (в минутах).
refresh_pattern -i ^ftp:           9    10%     10
        # 0 - объекты не будут предоставляться из кэша по умолчанию.
        # 0% - не используется, так как минимальное время равно 0.
        # 0 - нехранить в кэше
refresh_pattern -i (/cgi-bin/|\?)  0     0%      0       # Для динамических страниц | уникальный контент для каждого пользователя
refresh_pattern .                  0     20%     2160    # все остальное 0 минут / 1.5 дня

############################################################################
# Ограничения скорости

delay_pools 1 # Создать 1 пул ограничения скорости
delay_class 1 2 # Пул №1 использует класс 2
delay_access 1 allow all # Применить пул №1 ко всем клиентам
delay_parameters 1 3750000/3750000 640000/640000 # (потому что 3750000 × 8 = 30 000 000 бит)

############################################################################
# Другое

# Заглушка для email, имя пользователя по умолчанию для анонимного доступа к FTP-серверам через Squid
ftp_user anonymous@

############################################################################
###### Раздел ACL- создание правил доступа
############################################################################
# пример имени acl # politics_Squid_<NameADGroup>_From_AD
# пример имени acl # politics_Squid_<Name>
############################################################################

# Не кэшировать направления на локальный домен .domain.ru
acl politics_no_cache_local dstdomain .domain.ru
cache deny politics_no_cache_local
# Кэшировать картинки и CSS
acl politics_static_content urlpath_regex -i \.(jpg|jpeg|png|gif|css|js)$ # кэшировать картинки
cache allow politics_static_content
cache deny all # Остальное не кэшировать

############################################################################
# auth_param - параметры аутентификации пользователей

###### АУТЕНТИФИКАЦИЯ Kerberos
# Аутентификация пользователья в AD через Kerberos
auth_param negotiate program /opt/squid/libexec/negotiate_kerberos_auth \
    -d \
    -k /opt/squid/etc/squid.keytab \
    -s HTTP/testproxy.domain.ru@DOMAIN.RU
###### АУТЕНТИФИКАЦИЯ LDAP. Поиск пользователя в группе AD
# politics_ldap_Squid_<NameADGroup> - идентификация группы внутри squid
# InternetFullAccess - группа AD

external_acl_type external_ldap_Squid_InternetFullAccess \
        ttl=300 negative_ttl=60 \
        %LOGIN /opt/squid/libexec/ext_kerberos_ldap_group_acl \
    -g InternetFullAccess \
    -D DOMAIN.RU \
    -u squid@DOMAIN.RU \
        -p passwordUser \
        -l ldap://DOMAIN.RU

acl politics_Squid_InternetFullAccess_From_AD external external_ldap_Squid_InternetFullAccess

external_acl_type external_ldap_Squid_InternetAccess \
        ttl=300 negative_ttl=60 \
        %LOGIN /opt/squid/libexec/ext_kerberos_ldap_group_acl \
    -g InternetAccess \
    -D DOMAIN.RU \
    -u squid@DOMAIN.RU \
        -p passwordUser \
        -l ldap://DOMAIN.RU

acl politics_Squid_InternetAccess_From_AD external external_ldap_Squid_InternetAccess

# обязательная аутентификацию для всех пользователей
# REQUIRED - это ключевое слово означает: «Пользователь считается частью этого списка только если он успешно предоставил логин и пароль»
# Должно идти после инструкций auth_param
acl politics_authenticated proxy_auth REQUIRED

############################################################################

###### ПОРТЫ
acl politics_Safe_ports port 80          # http
acl politics_politics_Safe_ports port 21 # ftp
acl politics_Safe_ports port 443         # https
acl politics_Safe_ports port 444         # https альтернативный
acl politics_Safe_ports port 70          # gopher
acl politics_Safe_ports port 210         # wais
acl politics_Safe_ports port 1025-65535  # unregistered ports
acl politics_Safe_ports port 280         # http-mgmt
acl politics_Safe_ports port 488         # gss-http
acl politics_Safe_ports port 591         # filemaker
acl politics_Safe_ports port 777         # multiling http

acl politics_SSL_ports port 443          # https
acl politics_SSL_ports port 444          # https альтернативный

###### МЕТОДЫ подключения

# Метод CONNECT используется клиентами для установления туннеля через сервер посредник (чаще всего для HTTPS трафика).
acl politics_CONNECT method CONNECT

###### ПРОТОКОЛЫ

# Протокол ftp
acl politics_ftp proto FTP

############################################################################

###### ЧЕРНЫЕ/БЕЛЫЕ СПИСКИ

# black список. Запрет сайтов для ВСЕХ и для пользователей без авторизации (без ЛОГИНА и ПАРОЛЯ)
acl politics_black_list_ALL_andGuest url_regex -i "/opt/squid/etc/black_list_ALL_andGuest"

# white список. Для доступа к сайтам для ВСЕХ и для пользователей без авторизации (без ЛОГИНА и ПАРОЛЯ)
acl politics_white_list_ALL_andGuest url_regex -i "/opt/squid/etc/white_list_ALL_andGuest"

# black список. Запрет сайтов для группы InternetAccess
acl politics_black_list_for_InternetAccess url_regex -i "/opt/squid/etc/black_list_for_InternetAccess"

############################################################################
###### Раздел http_access - Применение правли доступа
############################################################################

# доступ к служебным страницам мониторинга и управления
# acl manager proto cache_object  # В Squid 7+ manager уже определён по умолчанию
http_access deny manager !localhost # Только для него самого

# Запретить небезопасные порты
http_access deny !politics_Safe_ports
# Запретить CONNECT к не-SSL портам
#http_access deny CONNECT !politics_SSL_ports

# acl politics_black_list_ALL_andGuest
http_access deny politics_black_list_ALL_andGuest

# acl politics_white_list_ALL_andGuest
# http_access allow politics_white_list_ALL_andGuest

# Запретить доступ пользователям без логина и пароля
http_access deny !politics_authenticated

# Доступ для групп AD - InternetFullAccess
http_access allow politics_Squid_InternetFullAccess_From_AD

# black_list - InternetAccess
http_access deny politics_Squid_InternetAccess_From_AD politics_black_list_for_InternetAccess
# Доступ для групп AD - InternetAccess
http_access allow politics_Squid_InternetAccess_From_AD


# ftp
http_access allow politics_ftp  # allow ftp

# Разрешить остальное с localhost
http_access allow localhost
# Запретить все остальное
http_access deny all

Если статья будет многим интересна, то возможно сделаю архив с примером конфигурации основанной на include (вложенности конфигов) и опубликую через GitHub. Имеется в виду конфигурация позволяющая типизировать изменения параметров Squid на основе разбитого squid.conf на отдельные файлы. Что то подобно структуре изображенной на скриншоте:

Комментарии (1)


  1. VovaUzh
    19.07.2026 18:14

    сделаю архив с примером конфигурации основанной на include (вложенности конфигов) и опубликую через GitHub

    бьіло бьі интересно глянуть на такое :-)