[personal profile] klink0v

Есть такой древний и местами незаслуженно забытый прокси-север под названием "Squid". Забыли его в основном потому, что в эпоху тотального TLS что-либо кешировать не представляется возможным. Но можно побыть немножечко "человеком посередине" (Man-in-the-Middle, MitM). И тогда снова становится реально кешировать. И контролировать-логировать.

Самая очевидная сфера применения — когда условный босс или бизапасник хочет проверять, не смотрят ли его сотрудники на рабочем месте прон вместо выполнения своих прямых обязанностей. Подвариант — когда на весь офис приходят условные 10 МБит/с, и надо их раздать так, чтобы все худо-бедно могли работать и не забивали бы ютупчиком / рутупчиком весь аплинк. Но конкретно в моём случае актуальнее другое: чтобы сборочные пайплайны не выкачивали бы из интернетов каждый раз заново все требующиеся им фреймворки и библиотеки. И каналы экономятся, и сборка ускоряется, и увеличивается предсказуемость в эпоху тотальных блокировок. Удобно.

В принципе, в интернетах полно мануалов как настроить Squid в таком режиме (он называется SSL Bumping). Не пишут, однако, что есть некоторые нюансы, связанные с алгоритмом проверки цепочек X509-сертификатов. Вкратце, если у них отсутствуют X509v3-расширения, то цепочка выстраивается по регистронезависимому сравнению строковых полей Issuer дочернего сертификата и Subject родительского сертификата согласно RFC5280. Если же присутствуют v3-расширения "Authority Key Identifier" (AKI) и "Subject Key Identifier" (SKI), то сравнение идёт именно по ним.

Так вот, "из коробки" Squid производит динамическую генерацию серверных сертификатов именно без v3-расширений, причём заполняет только характеристики CN и DNS Alternative Name. И записывает в них один-единственный хост — тот, к которому обратился клиент. Так делается ради упрощения и ускорения, ведь на тот момент когда клиент приходит на прокси-сервер, последний ещё не связался с "настоящим" веб-сервером и не знает что тот вернёт в ответ. Поэтому отдает клиенту самый примитивный сертификат "лишь бы зохавал", а дальше сам начинает общение с внешним ресурсом. Но есть проблема. Этот самый "мега-примитивный" динамически сгенерированный сертификат не содержит в себе AKI (Authority Key Identifier). А Python начиная с версии 3.13 его прям очень-очень хочет, аж кушать не может. И это нигде не отключается.

Вот непонятно в чём проблема динамически сгенерировать какой-нибудь "левый" AKI, но я нашёл только один способ отдать его клиенту. Это задействовать другую фичу Squid-а: мимикрия серверного сертификата (Sever Certificate Mimic). В этом режиме Squid запрашивает у "настоящего" сервера его "настоящий" сертификат, копирует из него все поля, а потом подписывает результат своим ключом. Таким образом, клиенту приезжает сертификат максимально похожий на "настоящий", но только с другими ключами-подписями. И в нём уже будет присутствовать AKI.

Чтобы включить этот режим, однако, надо заморочиться. Документации мало и написано она довольно корявым языком. Самый полезный фолиант на тему, пожалуй, вот. Из него мы узнаем, что сам процесс SSL Bumping-а Squid для себя подразделяет на три шага, из которых всегда выполняется только первый, а два последующих "как повезёт". Следуют они именно в таком порядке. И пресловутый "bump" может произойти или не произойти на любом из них.

  1. Смотрим что клиент прислал в запросе CONNECT и/или определяем IPшник куда он хочет пойти.
  2. Общаемся с клиентом и запрашиваем у него Client Hello. На этом этапе становится известен SNI (если есть).
  3. Общаемся с сервером и запрашиваем у него Server Hello. На этом этапе становится известен серверный сертификат.

Таким образом, для "мимикрии" обязательно требуется пройти все три шага. То есть bump должен случиться именно на последнем, третьем. А по умолчанию он происходит на первом. Так что необходимо подшаманить конфигурацию Squid-а. Например, вот так.

На первых двух шагах делаем "stare", и только на третьем "bump". Впрочем, всё то же самое можно записать сильно короче, но менее человекочитаемо. Вот так.

Тут прикол в том, что на первом шаге мы явно приказываем Squid-у уйти на второй ("stare all"), где он снова делает "stare" всё по той же причине "stare all" и таким образом провоцирует необходимость третьего шага. Где действием по умолчанию после stare на предыдущем шаге является именно bump, так как в третий раз сделать stare уже нельзя. Неочевидно, но такая у кальмара логика. Некстати, весьма запутанная. Несколько часов потратил прежде чем догнал.

Недостатком подобной конфигурации является то, что если клиент или сервер используют какие-то TLS-расширения, которые непонятны или не реализованы Squid-ом, то TLS-сессия просто не установится. Клиент получит отлуп. Тут поможет разве что только перечислить такие "проблемные" сервера в отдельной ACL-ке и не делать им bump, а туннелировать напрямую без кеширования и влезания вовнутрь TLS-сессии (splice). Наподобие вот такого.

Такое вот кеширование нонче пошло непростое.

... И вот, значит, только победил я эту проблему с мимикрией и AKI, как выяснилось, что питону оно всё равно невкусно потому что "CA CERT does not include key usage extension". Но это уже совсем другая история. ©

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

Sergeich

February 2026

S M T W T F S
123456 7
8910 11121314
1516 1718 1920 21
22232425 262728

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 27th, 2026 03:54 pm
Powered by Dreamwidth Studios