Ssl bump что это
Squid3 в режиме SSLBump с динамической генерацией сертификатов
Шифрованный веб-трафик вещь хорошая, но порой совершенно не ясно что пользователь там, внутри, делает. При заходе на любой https ресурс через squid, в логи записывается достаточно строк подобного вида:
Видно, что в определённое время пользователи зашли на gmail и яндекс. В принципе вот и всё что мы видим из логов. Но не понятно выполнялся ли GET или POST запрос, не видно полных урлов, ни размеров файлов. Так же нет возможности проверить ssl трафик антивирусной программой либо какими content inspection программами.
В этой статье я хочу описать возможность squid’а «разламывать» ssl соединение и иметь хоть какой-то обзор происходящего в https трафике.
Так как на CentOS стоит «усиленный» openssl, то сборка squid’а c необходимыми нам ключам не получается.
Есть два варианта решения данной проблемы.
Первый — это лезть в инклюд файлы установленного openssl, потом в исходники сквида и менять некоторые строки. И второй — это собирать сквид с кастомным openssl.
Первый вариант слишком хардкорный и оставим его в стороне.
1. openssl
Итак, для начала нам надо собрать свой openssl. Тут всё довольно просто и никакой магии:
Что бы не было конфликтов с уже установленной версией openssl, указываем новый путь:
2. squid
Сборка прокси сервера аналогична сборке любой программы (configure && make && make install), единственное это указание определённых ключей при компиляции:
—enable-ssl — включает поддержку ssl режима
—enable-ssl-crtd — генерацией сертификатов занимается отдельный процесс, а не сам прокси сервер.
—with-openssl — путь куда был установлен кастомный openssl
make all
make install
Так, squid прокси сервер собран.
3. Генерируем self-signed сертификат
Сертификат будет использоваться прокси сервером для создания динамических сертификатов веб сайтов.
Так как файл squidCA.pem содержит приватный ключ, делаем его читаемым только для пользователя root:
chmod 400 squidCA.pem
4.Настраиваем squid
Добавим следующие строки в squid.conf файл
данную настройку нежелательно использовать в продукционной системе, так как доступ разрешён на все https сайты с любыми сертификатами.
Стоит заметить, что если по какой-то причине вы поменяли ваш сертификат для squid’а, то надо полностью очистить каталог /opt/squid/var/lib/ssl_db и заново инициализировать сертификатную базу данных.
5. пользовательские проблемы
Так как в данном случае мы используем self-signed сертификат, любые посещения https сайтов через прокси будут показывать пользователям ошибку сертификата. Причина ошибки — Issuer нашего сертификата не находится в списке Trusted CA в браузере.
Что бы ошибок не было, выполняем следующее действие.
Теперь полученный файл squid.der надо импортировать в клиентский браузер.
Для Internet Explorer:
Tools->Internet Options->Content->Certificates
Выбираем закладку «Trusted Root Certificate Authorities»
Жмём Import, выбираем файл squid.der и завершаем импорт.
Для Firefox:
Tools->Options->Advanced->Encryption->View Certificates
Выбираем закладку «Authorities»
Жмём Import, выбираем файл squid.der и завершаем импорт.
Ну вот в общем то всё. В зависимости от ваших фантазий, теперь у вас есть возможность в https трафике запретить делать POST запросы, скачивать большие файлы, закрыть доступ к определённым файлам/папкам. Так же можно запретить доступ на сайты, сертификаты которых выданы не доверенными CA. Ну и возможность проверять на вирусы.
Прозрачный Squid с SSL-Bump для Gentoo с nft
Предыстория
Обозначения
Буквы равной ширины | Приказы оболочки и содержимое конфигурационных файлов. |
Полужирные буквы | Настройки, строго необходимые для прозрачного посредничества. |
Наклонные буквы | Настройки, специфичные для моей установки (номера выпусков ПО, адреса канального и сетевого уровня, названия сетевых интерфейсов и т. п.). В вашем случае значения, как правило, будут другими. |
Подчёркнутые буквы | Настройки, необходимые для работы разбора шифрованных соединений |
Операционная система | «Gentoo Linux» со службой запуска служб «OpenRC». Все дальнейшие настройки будут применимы к этой поставке |
Ядро | sys-kernel/gentoo-sources-5.3.1 USE=»» Здесь и далее снятые USE-флаги не показаны |
Прокси-сервер | net-proxy/squid-4.8 USE=»caps ssl ssl-crtd» |
Библиотека шифрования | dev-libs/openssl-1.1.1c-r1 USE=«asm test zlib» |
Приложение nft | net-firewall/nftables-0.9.2 USE=«doc gmp modern_kernel» |
Приложение ip | sys-apps/iproute2-5.2.0-r1 USE=«caps minimal» |
Служба записи в журнал | app-admin/ulogd-2.0.7-r1 USE=«nfct nflog» |
Настройка ядра
Для справки привожу выдержку из /usr/src/linux/.config:
Настройка сети
Если служба net.lo не добавлена в уровень выполнения «boot», то её следует туда добавить:
Подобным же образом созданы и настроены на запуск для уровня выполнения «default» службы net.br0 (мост для виртуальных машин и смартфона), net.enp0s25 (проводной интерфейс) и net.wlp3s0 (беспроводной интерфейс), например:
Итоговый конфигурационный файл /etc/conf.d/net в нашем примере выглядит так (за вычетом не относящихся к нашей задаче настроек):
Выделенные строки добавляют новую таблицу маршрутизации, в данном примере под номером 3128, и ворота — по умолчанию для неё (интерфейс «loopback»), и правило — по которому пакеты, помеченные межсетевым экраном меткой номер 3128 (десятичные числа в обоих случаях), будут обслуживаться этим расписанием.
Чтобы направляемые пакеты не были отброшены из-за несоответствия адресов сетевого уровня (при прозрачном проксировании пакеты сохраняются в первозданном виде!) необходимо добавить в /etc/sysctl.conf следующие строки (или изменить уже имеющиеся):
Если нужно применить эти настройки до перезагрузки, то следует дополнительно задать их для обоих сетевых интерфейсов с доступом в Интернет:
Настройка прокси-сервера
Поскольку обычный (непрозрачный) порт прокси-сервера у нас будет закреплён на адресе моста (192.168.120.1), добавим следующую строку в /etc/rc.conf:
Следующие настройки прокси-сервера в рамках этой статьи рассмотрены не будут:
Настройка межсетевого экрана
Настроим запуск на уровне выполнения «default» служб nftables и ulogd (последняя нужна для уведомления о пакетах):
Поскольку в настройках межсетевого экрана будет присутствовать мост, добавим следующую строку в /etc/rc.conf:
Для работы уведомления в /etc/sysctl.conf необходимо добавить следующую строку:
Чтобы конфигурационный файл находился в папке /etc/nftables, внесём такое изменение в /etc/conf.d/nftables:
Чтобы временные изменения не сохранялись в конфигурационном файле, внесём ещё одно изменение в /etc/conf.d/nftables:
Опишу задачи, поставленные перед межсетевым экраном:
Настройка потребителей
На самой РС
Для более основательных испытаний прозрачного прокси-сервера я решил использовать его и для всех приложений (за некоторыми исключениями, о чём дальше) на самой РС.
Добавим сертификат прокси-сервера в общее хранилище:
Приложения — веб-браузеры «Firefox» и «Chromium» не используют общее хранилище сертификатов, поэтому его следует добавлять в соответствующие хранилища этих приложений.
Создадим конфигурационный файл /etc/env.d/38proxy с такими строками:
Обновим переменные окружения:
После повторного входа настройки будут применены для всех приложений.
На виртуальных машинах с ОС «Red Hat Enterprise Linux» 6-го и 7-го выпуска
На виртуальной машине включаем работу с сертификатами PEM:
Переписываем с РС сертификат прокси-сервера на виртуальную машину:
На виртуальной машине обновляем сертификата:
На виртуальных машинах с ОС «Microsoft Windows» разных выпусков
Сертификат загружается в общее хранилище сертификатов машины (не пользователя!) в раздел «Доверенные корневые. ». Веб-браузер «Firefox» не использует общее хранилище сертификатов, поэтому сертификат следует добавлять в соответствующее хранилище этого приложения.
На РС «Raspberry Pi» с ОС «Raspbian»
Обновление приложений прошло успешно без установки сертификата.
На смартфонах с ОС «Android»
Сертификат предварительно загружается на устройство, затем устанавливается с помощью приложения по управлению сертификатами. После этого у пользователя будет запрошено усиление безопасности входа в устройство (если это ещё не сделано) с помощью графического ключа или пароля.
Вывод
Новый брандмауэр в линуксе (nft) представляет собой прекрасный образчик свободного ПО, хорошо сочетающийся со Squid’ом, де-факто стандартом свободного прокси-сервера.
Ssl bump что это
Шифрованный веб-трафик вещь хорошая, но порой совершенно не ясно что пользователь там, внутри, делает. При заходе на любой https ресурс через squid, в логи записывается достаточно строк подобного вида:
1330231066.104 10 172.26.27.8 TCP_MISS/200 390 CONNECT mail.google.com:443 — HIER_DIRECT/173.194.32.54 —
1330241192.883 9 172.26.27.97 TCP_MISS/200 390 CONNECT mc.yandex.ru:443 — HIER_DIRECT/213.180.193.119 —
Видно, что в определённое время пользователи зашли на gmail и яндекс. В принципе вот и всё что мы видим из логов. Но не понятно выполнялся ли GET или POST запрос, не видно полных урлов, ни размеров файлов. Так же нет возможности проверить ssl трафик антивирусной программой либо какими content inspection программами.
В этой статье я хочу описать возможность squid’а «разламывать» ssl соединение и иметь хоть какой-то обзор происходящего в https трафике.
Так как на CentOS стоит «усиленный» openssl, то сборка squid’а c необходимыми нам ключам не получается.
Есть два варианта решения данной проблемы.
Первый — это лезть в инклюд файлы установленного openssl, потом в исходники сквида и менять некоторые строки. И второй — это собирать сквид с кастомным openssl.
Первый вариант слишком хардкорный и оставим его в стороне.
1. openssl
Итак, для начала нам надо собрать свой openssl. Тут всё довольно просто и никакой магии:
Что бы не было конфликтов с уже установленной версией openssl, указываем новый путь:
2. squid
Сборка прокси сервера аналогична сборке любой программы (configure && make && make install), единственное это указание определённых ключей при компиляции:
—enable-ssl — включает поддержку ssl режима
—enable-ssl-crtd — генерацией сертификатов занимается отдельный процесс, а не сам прокси сервер.
—with-openssl — путь куда был установлен кастомный openssl
make all
make install
Так, squid прокси сервер собран.
3. Генерируем self-signed сертификат
Сертификат будет использоваться прокси сервером для создания динамических сертификатов веб сайтов.
Так как файл squidCA.pem содержит приватный ключ, делаем его читаемым только для пользователя root:
chmod 400 squidCA.pem
4.Настраиваем squid
Добавим следующие строки в squid.conf файл
данную настройку нежелательно использовать в продукционной системе, так как доступ разрешён на все https сайты с любыми сертификатами.
Стоит заметить, что если по какой-то причине вы поменяли ваш сертификат для squid’а, то надо полностью очистить каталог /opt/squid/var/lib/ssl_db и заново инициализировать сертификатную базу данных.
5. пользовательские проблемы
Так как в данном случае мы используем self-signed сертификат, любые посещения https сайтов через прокси будут показывать пользователям ошибку сертификата. Причина ошибки — Issuer нашего сертификата не находится в списке Trusted CA в браузере.
Что бы ошибок не было, выполняем следующее действие.
Теперь полученный файл squid.der надо импортировать в клиентский браузер.
Для Internet Explorer:
Tools->Internet Options->Content->Certificates
Выбираем закладку «Trusted Root Certificate Authorities»
Жмём Import, выбираем файл squid.der и завершаем импорт.
Для Firefox:
Tools->Options->Advanced->Encryption->View Certificates
Выбираем закладку «Authorities»
Жмём Import, выбираем файл squid.der и завершаем импорт.
Ну вот в общем то всё. В зависимости от ваших фантазий, теперь у вас есть возможность в https трафике запретить делать POST запросы, скачивать большие файлы, закрыть доступ к определённым файлам/папкам. Так же можно запретить доступ на сайты, сертификаты которых выданы не доверенными CA. Ну и возможность проверять на вирусы.
«Прозрачный» Squid с фильтрацией HTTPS ресурсов без подмены сертификатов (x86)
Не секрет, что в больших конторах тема фильтрации Интернета довольно актуальная. С этой задачей справляется немало программных и аппаратных решений. Но в настоящее время все те сайты, которые мы резали ранее, работают по протоколу HTTPS, т.е. порт 443. Как известно, данный протокол проследить, прослушать и т. п., невозможно. А любой кеширующий фильтрующий прокси-сервер, редиректор и т. п. фильтрует только HTTP, т.е. порт 80. Как же резать Вконтакте, Одноклассники, iphide.info и многие другие подобные сайты? Как блокировать доступ к личной почте в организации, если использование оной запрещено порядками в организации? Да, можно фильтровать по IP адресам, но они частенько меняются, да и на многих ресурсах несколько IP адресов. Блокировать их на уровне файрвола как-то совсем не православное решение, и не совсем удобное.
И вот, совсем недавно, мне один товарищ рассказал, что он поднимает у себя в конторе кеширующий прокси с фильтрацией HTTPS, меня это заинтересовало.
А поднимал он Squid 3.5.8. Как выяснилось, в нем переработана организация перехвата шифрованных HTTPS-сеансов (ssl_bump), вместо режимов перехвата («modes») введены в обиход действия («actions»), которые в том числе можно использовать в ACL. Режим «server-first», при котором вначале осуществляется соединение с целевым сервером, а потом создаётся защищённое соединение между клиентом и прокси, теперь доступен как действие «bump». Режим «none», при котором создаётся TCP-туннель без дешифровки трафика, теперь доступен как действие «splice».
Для обеспечения обратной совместимости добавлено действие «peek-and-splice», при котором решение о типе создаваемого вначале соединения (клиент-прокси или прокси-сервер) принимается на основе SSL hello-сообщений. Добавлены действия «peek» и «stare» для получения клиентского или серверного сертификата с сохранением возможности дальнейшего применения режимов «splice» и «bump» для соединений. Добавлено действие «terminate» для закрытия соединений к клиенту или серверу. Вот как раз SSL BUMP, PEEK-and-SPLICE и Terminate нам и нужны. Вообще, схема работы на самом деле довольно простая. Squid подключается к HTTPS ресурсу, получает его сертификат, и может «посмотреть» некоторые данные о ресурсе, в частности имя сервера, которое нам как раз и нужно для блокировки! Все мануалы, которые есть в Интернете, то и дело описывают Man in the middle (MITM) атаку с подменой сертификатов, при которой в принципе не работают некоторые сайты и банк-клиенты, да и юзеры явно видят, что за ними следят. Мы же с товарищем совместными усилиями добились сбособа фильтрации и отслеживания HTTPS без подмены сертификатов, без MITM и прочего, и все это в прозрачном режиме без настройки браузеров!
Впоследствии я столкнулся с некоторыми сложностями, в частности Squid начинал сегфолтиться на большой нагрузке. Но проблема была решена. Дело в том, что в Openssl имеются кое какие баги, которые исправлены в библиотеке Libressl. Поэтому необходимо сначала интегрировать в систему Libressl, потом уже после внесения патча в файл bio.cc в исходниках Squid приступать к компиляции последнего. Поехали! Оговорюсь, что у меня используется дистрибутив Debian Jessie x86, и Squid я в итоге собрал версии 3.5.9 (последняя на данный момент версия), и статья рассчитана на более-менее опытного пользователя Linux, так как некоторые моменты опускаются, а говорится лишь самое главное, так как мне лень все разжевывать.
Для начала, подготовимся к сборке пакетов:
Не забудьте перейти в ту папку, где вы будете собирать исходники, чтобы не засрать себе Хоум. Далее скачаем, скомпилируем и установим Libressl:
Собираем и устанавливаем, после чего перечитаем хеши библиотек:
Ну и надо настроить использование LibreSSL по-умолчанию:
Проверим, получилось ли поставить Libressl:
После выполнения этих действий, необходимо отредактировать sources.list, включив туда исходники из ветки testing (это необходимо, так как нам нужно компилировать новый libecap, который в свою очередь необходим для сборки Squid):
Обновим кеш пакетов:
А теперь скачаем из Testing нужные исходники:
Далее соберем libecap:
Удалим старье, и установим новье:
Качаем последний самый свежий и работающий снэпшот Squid’a:
Обновим полученные ранее исходники Squid’a до новых, и далее будем работать уже в директории с новоиспеченными исходниками:
Чтобы все нужные нам плюшки заработали, надо компилировать Squid с нужными опциями, поэтому внесем в debian/rules следующие опции компиляции:
Скачаем патч для bio.cc, который нужен для корректной работы с Libressl, отсюда bugs.squid-cache.org/attachment.cgi?id=3216 и применим его
Теперь можно приступать к компиляции и сборке Squid’а. Но не так быстро! Все скомпилируется без проблем, по крайней мере на х86 архитектуре, но в самом конце, на этапе сборки пакетов deb, вам любезно скажут в консоли: «ай ай ай, не могу понять, какие зависимости нужны для libssl.so.32» (это версия библиотеки из Libressl). Оно и понятно, откуда Debian’у знать о ней. Мы обманем систему, указав опцию «не проверять зависимости», вот так:
А вот теперь приступим к компиляции и сборке:
После сборки установим пакет с языками для Squid’a:
Далее установим новоиспеченные пакеты:
Если система заматерилась на неудовлетворенные зависимости, сделаем:
Почти готово. Перейдем в каталог /etc/squid, кое-что там изменим. Создадим pem файлик, необходимый для SSL-Bump’инга:
И приведем squid.conf к следующему виду:
Немного расскажу про конфиг. Документация по ssl_bump, peek-n-splice довольно обширная, но для нашей задачи необходимо знать следующее. Есть несколько этапов «handshaking» (т.е. рукопожатие, взаимодействие с сервером). Описаны они в оф.документации. Нас интересует пример Peek at SNI and Bump. То есть, как следует из названия, мы смотрим SNI-информацию и бампим соединение. Перед этим, мы указываем опцией DONT_VERIFY_PEER, что необходимо принимать сертификаты даже, если они не прошли проверку и опцией sslproxy_cert_error указываем, что нужно отключить проверку сертификатов на сервере. Указанное правило «acl step1 at_step SslBump1» — это есть первый из трех возможных шагов ssl_bump’а. При выполнении этого шага мы получаем только SNI, и ничего более. Нам этого достаточно. Дальше мы используем этот ACL строкой ssl_bump peek step1, то есть непосредственно смотрим SNI, а уже после этого блокируем соединение, если в SNI найден server_name из списка blocked.
Далее завернем файрволом нужные порты на Squid:
Все готово! Можно торжественно запускать Squid:
Посмотрим, все ли со Squid’ом нормально:
Если ошибок нет, можно работать. К сожалению, при блокировке HTTPS ресурсов, не появляется сообщение Squid’a «Доступ запрещен», а вместо этого браузер выдает ошибку о невозможности создания соединения. Если кто-то подскажет, как это сделать, буду очень рад.
UPD: в версии Кальмара, которую компилировал я изначально, т.е. 3.5.9, найден досадный баг (или фича), из-за которого спустя время перестают открываться некоторые HTTPS сайты. Решение: компилировать версию 3.5.8.
UPD2: создал очередной багрепорт по проблеме в 3.5.9, тему буду обновлять, если что-то прояснится.
UPD3: вышла версия 3.5.10 с исправленными багами, по крайней мере, патч на файл bio.cc там уже применен. Не тестировал пока-что
UPD4: подредактировал статью немного.
UPD5: прямая ссылка для скачивания архива со всеми нужными пакетами (SQUID 3.5.8), пока-что это единственная рабочая версия! Остальные, которые версиями выше, имеют баг, из-за которого Squid перестает работать при прозрачном проксировании HTTPS. ВЕРСИЯ ДЛЯ Х86.
ВНИМАНИЕ. Во избежание недоразумений, ставьте версию 3.5.8! На ней нет никаких проблем, и если сделано все точно по статье, то все будет работать! Если ставите версию выше, то я не гарантирую правильной работы прозрачной фильтрации!
Очередное Update. в src-репозитарии Debian Testing теперь 3.5.10. добавляйте в sources.list src-репозитарий squeeze. Там версия 3.1, но ничего страшного, все обновится до версии 3.5.8 как надо, только пути к каталогам измените в соответствии с версией скачанных исходников!
UPD 02.12.15: Я прошу прощения, если заставил кого-то костылить. Перезалил архив squid 3.5.8, там не хватало одного deb пакета! squid 3.5.8_all.
UPD 02.12.15: Внимание! Если у вас проблема с установкой libressl, то нужно сделать так: сначала поставить openssl, а затем уже ставить libressl (если ставите версию из архива с пакетами, то не забывайте сделать замену openssl на libressl, как в статье!). Это решит проблему «невидения» библиотеки libssl.so.32
UPD 10.12.15: Появилась следующая версия статьи, с немного другим подходом к компиляции Кальмара и сборке пакетов. Вот тут
UPD 14.12.15: спешу поделиться с коллегами отличной новостью! Я нашел способ заставить работать новые версии Squid’а без особых танцев с бубном! Необходимо, чтобы у клиентов и в настройках Squid’а были одинаковые DNS! В моем случае, на шлюзе с Кальмаром крутится Bind. Назначил клиентам именно его, и Кальмару директивой:
. После чего все успешно заработало. Проверено на Squid 4.0.3, собрана БЕЗ Libressl!
UPD 14.12.15: не знаю почему, но в данный момент на Debian 8.2 при сборке Squid’a описанным выше способом выдается сообщение о том, что файл mime.conf не найден. И действительно, ведь в исходниках Кальмара есть mime.conf.default. Я нашел решение. Необходимо отредактировать два файлика:
1) debian/squid-common.install, и привести строку
2) Также необходимо сделать так, чтобы после установки пакета файл переименовался автоматом в «сквидочитаемый вид», т.е. в mime.conf. Для этого отредактируем файл debian/squid-common.postinst, приведя его в такой вид:
То есть добавим строку переименования файла, а остальное оставляем, как есть, не трогаем.
Все, после этого формируем пакеты, они сформируются и поставятся.
UPD 19.06.17: так как у меня спёрли домен linux-admin.tk, пришлось создать новый, уже «нормальный» домен, соответственно ссылку на скачивание архива изменил.
UPD 04.05.18: написал новую статью, где решается проблема глюков новых версий Squid + в логах красивые доменные имена вместо ip адресов + обход блокировок РКН.
Хочу сказать спасибо товарищу Дмитрию Рахматуллину, без него бы не получилось сделать то, что написано выше. Также, отдельное спасибо разработчикам Squid’а, которые оперативно ответили на мой баг-репорт об ошибке в libssl. И спасибо ребятам Nadz Goldman и gmax007 с Тостера, которые направили в нужное русло мои идеи по переносу Squid’а на физически отдельный от основного шлюза сервер.