SHA-1 в корпоративном CA: как Chrome 56 и Firefox 51 устроили нам внеплановый аудит
Chrome 56 и Firefox 51 начали блокировать SHA-1 сертификаты. Несколько клиентов получили красную плашку на внутренних сервисах - разбираем аудит и план перехода на SHA-256.
Chrome 56 и Firefox 51 (январь 2017) начали блокировать сайты с SHA-1 сертификатами
В январе Chrome 56 и Firefox 51 вышли с одним неприятным для некоторых клиентов сюрпризом: оба браузера теперь показывают жёсткое предупреждение или вовсе блокируют сайты, сертификаты которых подписаны SHA-1. Не «небезопасный замочек» в углу, а красная плашка с текстом, которая пугает пользователей и заставляет звонить в поддержку.
У нас это проявилось конкретно: несколько клиентов написали в первые дни после обновления браузеров, что внутренние веб-сервисы стали «недоступны» или «небезопасны». Причина у всех одна - корпоративный CA, выписывающий сертификаты с SHA-1 по умолчанию. Публичные сервисы давно на SHA-256, а про внутренние как-то не думали: «там же корпоративный CA, там нет проблем».
Что именно сломалось
Внутренние сервисы - ESXi web client, Zabbix, GitLab, phpIPAM, разные веб-морды к железу. Всё это сидело за корпоративным CA, который несколько лет выдавал сертификаты с подписью SHA-1. Корень CA у клиентов был в доверенных, поэтому раньше всё работало тихо. После обновления браузеров SHA-1 перестал быть достаточным условием доверия - алгоритм подписи теперь тоже проверяется явно.
На самом деле предупреждения о SHA-1 в Chrome появлялись ещё с 2015 года, но тогда это был жёлтый треугольник, который мало кто замечал. Сейчас это уже не «предупреждение», а блокировка. Разница существенная.
Аудит: что и где
Первый шаг - инвентаризация. Нет смысла чинить наугад, если не знаешь масштаб. Мы запустили быстрый скрипт на bash поверх nmap/openssl, который прошёлся по известным хостам и выдернул алгоритм подписи из сертификата:
for host in $(cat hosts.txt); do
algo=$(echo | openssl s_client -connect "${host}:443" -servername "${host}" 2>/dev/null \
| openssl x509 -noout -text 2>/dev/null \
| grep "Signature Algorithm" | head -1)
echo "$host: $algo"
done
Простейшее, но за час дало полную картину по всему парку. Находки делились на три группы:
- SHA-256 - уже хорошо. Публичные сервисы и всё, что выпускалось через Let's Encrypt - чисто.
- SHA-1 от корпоративного CA - проблема. Внутренние сервисы, у которых сертификат живёт годами и никто не обновлял.
- Самоподписанные SHA-1 - отдельная история. Несколько хостов вообще без CA, просто openssl req -x509. Там алгоритм зависит от того, что было по умолчанию в момент выпуска.
Причина: CA не менял дефолты
Оказалось, что у двух клиентов корпоративный CA (Windows ADCS) был настроен с дефолтным шаблоном, который использует SHA-1. Настраивали его в районе 2010-2012 года, когда SHA-1 был нормой, и никто с тех пор не трогал. Всё работало, зачем трогать.
Это типичная история: настроил один раз - забыл. Криптографические дефолты не валятся с ошибкой, когда устаревают. Они тихо живут до момента, когда браузер или клиент начинает явно проверять алгоритм.
План перехода
Для каждого клиента из двух кейсов план примерно одинаковый:
- Первое - обновить дефолты CA. В ADCS это правка шаблонов сертификатов: выставить
Request Hashв SHA256, пересмотретьKey Sizeесли там 1024-битные ключи (такое тоже встречается). - Второе - перевыпустить сертификаты с SHA-1. Подписать новые с SHA-256, накатить на сервисы. Приоритет - всё, к чему ходят браузеры. ESXi-хосты с SHA-1 в веб-интерфейсе - тоже меняем, даже если туда ходят только через vSphere Client.
- Третье - промежуточный CA, если есть. Если в цепочке есть промежуточный CA с SHA-1 - он тоже попадает под замену. Корень CA с SHA-1 браузеры пока принимают отдельно (там логика доверия другая), но промежуточный - нет.
- Четвёртое - мониторинг. Добавить в Zabbix проверку алгоритма подписи в сертификате наряду со сроком жизни. Срок мы давно мониторим, алгоритм - нет. Теперь надо.
Что с самоподписанными
Самоподписанные сертификаты на внутренних сервисах - это отдельная боль. Там нет CA, которому можно просто поменять шаблон. Варианта два: либо завести нормальный корпоративный CA и перейти на него, либо перевыпускать каждый самоподписанный вручную с явным указанием алгоритма:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-sha256 -keyout server.key -out server.crt \
-subj "/CN=internal.example.local"
Минус -sha256 не прибивали к команде по умолчанию - а теперь придётся приучить команду всегда указывать явно.
Где мы сейчас
Аудит по обоим клиентам завершён, список сертификатов под замену есть. Перевыпуск идёт в рабочем порядке - там нет ничего срочного кроме самих браузерных плашек, которые уже мешают работе. Параллельно мы смотрим, где вообще разумно уйти от корпоративного CA на Let's Encrypt - для внешних публичных сервисов это аудит инфраструктуры даёт ответ почти сразу.
Для внутренних сервисов, как мы писали в посте про Let's Encrypt и корпоративный CA, LE не вариант - нет публичного DNS. Так что здесь ADCS с правильно настроенными шаблонами SHA-256 - рабочее решение.
Урок простой: криптографические дефолты стареют молча. Раз в год стоит прогонять аналогичную проверку по всему парку, не ждать пока браузер скажет «небезопасно» за тебя.