Как заставить браузер доверять самоподписанному сертификату

Обновлено: 03.07.2024

Хотя есть similar вопросы и даже хорошие ответы, они либо не заботятся о локальном хосте. или спросите об одном конкретном варианте / решении (самоподписанный или CA).

Какие есть варианты? Как они сравниваются? Как мне это сделать?

3 ответа

tl; dr Создать сертификат, выданный собственным ЦС (см. сценарий ниже)

Вот что я нашел. Поправьте меня, где я ошибаюсь.

Есть ЦС (центры сертификации). Они выдают сертификаты (подписывают CSR) для других CA (промежуточных CA) или серверов (сертификаты конечных объектов). Некоторые из них являются корневыми авторитетами. У них есть самоподписанные сертификаты, выданные ими самими. То есть обычно существует цепочка доверия, которая идет от сертификата сервера к корневому сертификату. А за корневой сертификат не за что поручиться. Таким образом, ОС имеют хранилище корневых сертификатов (или хранилище политик доверия), общесистемный список доверенных корневых сертификатов. У браузеров есть собственные списки доверенных сертификатов, которые состоят из общесистемного списка и сертификатов, которым доверяет пользователь.

В Chromium вы управляете сертификатами в chrome: // settings / Certificates. В Firefox: Preferences > Privacy & Security > Certificates > View Certificates . У обоих есть вкладка Authorities, которая представляет собой список доверенных корневых сертификатов. И вкладка Серверы, список доверенных сертификатов серверов.

Чтобы получить сертификат, вы создаете CSR (запрос на подпись сертификата), отправьте его в CA. CA подписывает CSR, превращая его в доверенный сертификат в процессе.

Сертификаты и CSR - это набор полей с информацией и открытым ключом. Некоторые поля называются расширениями. Сертификат CA - это сертификат с basicConstraints = CA:true .

Вы можете проверить ошибки сертификата в Chromium в Developer Tools > Security .

Доверие к сертификатам в масштабах всей системы

Когда вы меняете хранилище корневых сертификатов ОС, вам необходимо перезапустить браузер. Вы меняете его с помощью:

trust помещает сертификаты CA в категорию "авторитетных" ( trust list ) или в категорию "другие записи" в противном случае. Сертификаты ЦС отображаются на вкладке "Авторитеты" в браузерах или на вкладке "Серверы".

Firefox не доверяет сертификатам сервера из корневого хранилища сертификатов ОС, в отличие от Chromium. Оба доверяют сертификатам CA из корневого хранилища сертификатов ОС.

Доверять сертификатам в браузере

В Chromium вы можете добавлять (импортировать) сертификаты на вкладке «Серверы». Но они попадают либо на вкладку «Центры» (сертификаты CA, и после выбора файла вам не открывается диалоговое окно настроек доверия), либо на вкладку «Другие» (если сертификат не CA).

В Firefox вы не можете точно добавить сертификат на вкладку «Серверы». Вы добавляете исключения. И там можно доверять сертификату без расширений (плохой).

Самозаверяющие расширения сертификатов

Моя система поставляется со следующими настройками по умолчанию (будут добавлены расширения) для сертификатов:

Кроме того, Chromium считает сертификат недействительным, если в нем нет subjectAltName = DNS:$domain .

Несамоподписанные расширения сертификатов

Когда браузеры доверяют самозаверяющему сертификату

Чтобы Chromium мог доверять самозаверяющему сертификату, он должен иметь basicConstraints = CA:true и subjectAltName = DNS:$domain . Для Firefox даже этого недостаточно:

Когда браузеры доверяют сертификату, выпущенному собственным ЦС

Firefox не нуждается в расширениях, но Chromium требует subjectAltName .

openssl шпаргалка

openssl genpkey -algorithm RSA -out "$domain".key - сгенерировать закрытый ключ (man)

openssl req -x509 -key "$domain".key -out "$domain".crt - создать самоподписанный сертификат (мужчина)

Без -subj он будет задавать вопросы относительно отличительного имени (DN), например, общего имени (CN), организации (O), населенного пункта (L). Вы можете ответить на них «заранее»: -subj "/CN=$domain/O=$org" .

Чтобы добавить расширение subjectAltName , вы должны либо иметь конфигурацию, в которой все это указано, либо добавить раздел в конфигурацию и указать openssl его имя с помощью переключателя -extensions :

openssl req -new -key "$domain".key -out "$domain".csr - генерировать CSR, может принимать опцию -subj (мужчина)

openssl x509 -req -in "$ домен" .csr -days 365 -out "$ домен" .crt \ -CA ca.crt -CAkey ca.key -CAcreateserial - подписать CSR (мужчина)

Не работает без -CAcreateserial . Он создает файл ca.srl , в котором хранится серийный номер последнего сгенерированного сертификата. Чтобы добавить subjectAltName , вам понадобится переключатель -extfile :

openssl req -in $domain.csr -text -noout - просмотреть CSR ( man )

openssl x509 -in $domain.crt -text -noout - просмотреть сертификат ( man )

Создать самоподписанный сертификат

(вам понадобится исключение в Firefox, чтобы оно работало)

Сгенерировать сертификат, выданный собственным ЦС

Конфигурация веб-сервера

P.S. Я использую Chromium 65.0.3325.162, Firefox 59.0 и openssl-1.1.0.g .

Windows

Очевидно, в Windows нет утилиты trust . В Windows есть два хранилища: хранилища локальных компьютеров и сертификатов текущего пользователя. Нет смысла использовать хранилище сертификатов Local Machine, поскольку мы работаем только для нашего текущего пользователя. Затем есть магазины. Два предопределенных из них представляют наибольший интерес: доверенные корневые центры сертификации и промежуточные центры сертификации. Обычно упоминается в командной строке как root и CA.

Вы можете получить доступ к Диспетчеру сертификатов Chrome, выполнив команду chrome: // settings /? Search = Manage% 20certificates и нажав Управление сертификатами. Наибольший интерес представляют вкладки «Доверенные корневые центры сертификации» и «Промежуточные центры сертификации».

Одним из способов управления сертификатами является командная строка :

Результаты следующие (для хранилищ локальных компьютеров и сертификатов текущего пользователя):

Другими вариантами могут быть двойной щелчок по сертификату в проводнике, импорт сертификатов из диспетчера сертификатов Chrome, использование оснастки MMC «Сертификаты» (запуск certmgr.msc ) или использование CertMgr.exe .

Для тех, у кого установлено grep , вот как быстро проверить, где находится сертификат:

Таким образом, установка сертификата CA в хранилище Current User> Trusted Root Certification Authorities кажется лучшим вариантом. И убедитесь , что не забыли перезапустить браузер.


На production нет проблем с сертификатами. Обычно хостинг провайдер предоставляет удобный интерфейс для подключения сертификата. Выпуск сертификата тоже дело не сложное. Но во время работы над проектом каждый разработчик должен позаботиться о сертификате сам.
В этой статье я расскажу, как выпустить самоподписанный SSL сертификат и заставить браузер доверять ему.

Чтобы выпустить сертификат для вашего локального домена, понадобится корневой сертификат. На его основе будут выпускаться все остальные сертификаты. Да, для каждого нового top level домена нужно выпускать свой сертификат. Получить корневой сертификат достаточно просто.
Сначала сформируем закрытый ключ:


Затем сам сертификат:


Нужно будет ввести страну, город, компанию и т.д. В результате получаем два файла: rootCA.key и rootCA.pem

Переходим к главному, выпуск самоподписанного сертификата. Так же как и в случае с корневым, это две команды. Но параметров у команд будет значительно больше. И нам понадобится вспомогательный конфигурационный файл. Поэтому оформим все это в виде bash скрипта create_certificate_for_domain.sh

Первый параметр обязателен, выведем небольшую инструкцию для пользователя.


Создадим новый приватный ключ, если он не существует или будем использовать существующий:


Запросим у пользователя название домена. Добавим возможность задания “общего имени” (оно используется при формировании сертификата):


Чтобы не отвечать на вопросы в интерактивном режиме, сформируем строку с ответами. И зададим время действия сертификата:


В переменной SUBJECT перечислены все те же вопросы, который задавались при создании корневого сертификата (страна, город, компания и т.д). Все значение, кроме CN можно поменять на свое усмотрение.

Сформируем csr файл (Certificate Signing Request) на основе ключа. Подробнее о файле запроса сертификата можно почитать в этой статье.


Формируем файл сертификата. Для этого нам понадобится вспомогательный файл с настройками. В этот файл мы запишем домены, для которых будет валиден сертификат и некоторые другие настройки. Назовем его v3.ext. Обращаю ваше внимание, что это отдельный файл, а не часть bash скрипта.


Да, верно, наш сертификат будет валидным для основного домена, а также для всех поддоменов. Сохраняем указанные выше строки в файл v3.ext

Возвращаемся в наш bash скрипт. На основе вспомогательного файла v3.ext создаем временный файл с указанием нашего домена:


Переименовываем сертификат и удаляем временный файл:


Скрипт готов. Запускаем его:


Получаем два файла: mysite.localhost.crt и device.key

Теперь нужно указать web серверу пути к этим файлам. На примере nginx это будет выглядеть так:

nginx ssl


Браузер не доверяет этому сертификату. Как быть?

Нужно отметить выпущенный нами сертификат как Trusted. На Linux (Ubuntu и, наверное, остальных Debian-based дистрибутивах) это можно сделать через сам браузер. В Mac OS X это можно сделать через приложение Keychain Access. Запускаем приложение и перетаскиваем в окно файл mysite.localhost.crt. Затем открываем добавленный файл и выбираем Always Trust:


Обновляем страницу в браузере и:


Успех! Браузер доверяет нашему сертификату.

Сертификатом можно поделиться с другими разработчиками, чтобы они добавили его к себе. А если вы используете Docker, то сертификат можно сохранить там. Именно так это реализовано на всех наших проектах.

Можно, никаких ограничений на испольщование сертификатов от letsencrypt нет.

А если внутри корпоративной сети только нужно?
Для сетей с MS AD можно развернуть CA и все клиенты будут доверять через GPO

Для тех кто не понял:
Нужно купить самый дешевый понравившийся домен (цена 200 р. и меньше на год), ну и пофиг что продление будет стоить дороже, через год можно купить опять новый домен.
Чтобы получить сертификат, нужен комп, который торчит в интернет. Если на работе проблематично получить доступ к такому компу, то можно использовать домашний комп (мы же разработчики, у всех есть домашний комп). Получаем сертификат от letsencrypt (теперь уже даже wildcard можно получить), далее копируем к себе куда надо все это добро, в hosts прописываем локальный ip для этого домена. Такая схема работает и на винде и в линукс, сам лично пользуюсь. Можно даже обойтись без hosts: у регистратора домена прописываешь в dns локальный ip, тогда в локальной сети работает как будто комп торчит в интернет.
Чтобы получить сертификат, нужен комп, который торчит в интернет.
Не очень понятно как такой подход использовать если тестовых локальных машин много. Это нужно, получается каждые 3 месяца обновлять сертификат и рассылать его всем разрабочикам для ручного обновления?

Сертификат обновляется скриптом (где-нибудь на digital ocean) и выкладывается куда-то, откуда всего его могут скачать, в т.ч. другой скрипт. Например, у нас собирается для тестов докер с nginx вместе с сертификатом, поэтому достаточно обновить контейнер. Есть тестовый сервер, где nginx установлен непосредственно, но там копеечный скрипт из 2-х строк: wget… и nginx -s reload.
Я свой личный сертификат (использую только для разработки), обновляю руками 4 раза в год. Мне удобнее пользоваться личным сертификатом, т.к. можно управлять ДНС (от регистратора домена) единолично.

Если вебдев, то скорей всего установлены туча браузеров, где надо каждому настроить доверие. А как насчет доверия со стороны системы? А если curl/wget? Как сказанно выше — зачем городить костыли, если есть доступные методы получения сертификатов.

Достаточно добавить корневой сертификат в хранилище сертификатов на уровне ОС. Для Java есть оговорки. И сразу удалить/спрятать его, чтобы самому себе бэкдор не устроить :)

Так это понятно. Это риторические вопросы к статье, а не к Вам. Статья учит новичков антипатернам, которые им потом аукнутся. Вполне настраивается всё. Главное, что один раз настроить доверие к корневому, а потом плоди сколько хочешь. И всё на localhost, никому не нужно давать доступ к нему.

Вот для ubuntu рецепт:

А вот так называемые "доступные методы" не очень хорошо подходят для условий локальной разработки без прямого доступа из интернета к защищаемому хосту (NAT, прокси). В общем случае с 4 сторонними лицами надо взаимодействовать:

  • администратор локальной сети, который пробросит порт с внешнего адреса на внутренний, а потом уберёт проброс, если он вообще согласится. "Локальной сетью" вполне может оказаться сеть оператора, например мобильного, который даже временно, динамические публичные адреса не даёт
  • регистратор доменов
  • DNS-сервис, адреса которого нужно дать регистратору домена
Чтобы получить сертификат, подойдет любой комп, который торчит в интернет, в самом плохом случае можно использовать домашний комп. Далее полученный сертификат и секретный ключ копируешь куда надо, для использования доступ из интернета не нужен.
А вот просить всех добавить свой левый сгенеренный сертификат к себе в доверенные так себе идея с точки зрения безопасности.

Домашний комп тоже нередко в локалке: или роутер с NAT на входе в квартиру, или провайдер белых адресов не даёт, равзе что за отдельную плату, а по дефолту пуская через NAT, или и то, и другое, разве что админские права могут быть на роутер дома у разработчика. А могут и не быть, например сын — разработчик, а папа — админ :)

Если речь идёт не о локальной разработке, а о, например, QA-сервере в корпоративной сети, то там хорошим вариантом может быть поднятие своего CA полноценного, особенно если активно используются локальные домены, которые в принципе не резолвятся публичными DNS. И с точки зрения безопасности вариант отличный — сертификат корпоративного CA добавляется на все сервера и рабочие станции, подписывать им можно сертификаты для любых целей, а не только для сайтов, вносить в проверенную любую информацию, например, отдел.

Домашний комп тоже нередко в локалке: или роутер с NAT на входе в квартиру, или провайдер белых адресов не даёт

Лучше, да, часть кейсов для разработки закрывает.

Именно! Это исключительно для dev. А шпаргалка хорошая, спасибо. Можно просто купить хостинг на Бегет и установить бесплатный сертификат, да и все, непонимаю к чему такой гемор

зачем нужен хостинг при локальной разработке?

Еще проще можно сделать через ngrok, и показать за натом тоже можно.

1. Можно выпустить сертификат (wildcard использую letsencrypt)
2. Можно выпустить сертификат самому. (тоже вайлдкард)
2.1 сгенерировать рутовый сертификат
2.2 сгенерировать сертификат
2.3 добавить рутовый сертификат как доверенный в браузер. (после этого все сертификаты сгенерированные с помошью рутового — будут валидны.)

Я в общим-то 2й вариант использую для дев окружение. Если интересно могу написать шпаргалку по этому поводу.

Генерация корневого сертификата:
openssl genrsa -des3 -passout pass:qwerty -out RootCA.key.pem 2048;
openssl req -x509 -new -nodes -key RootCA.key.pem \
-passin pass:qwerty \
-sha256 -days 1024 -out Root.cert.pem \
-subj "/C=AU/ST=NSW/L=Sydney/O=CompanyName/OU=Company Description/CN=www.company-name.com"

Выпускаем сертификат:
openssl req -new -sha256 -nodes -out server.csr.pem \
-newkey rsa:2048 -keyout server.key.pem \
-config <( cat server.csr.cnf );
openssl x509 -req \
-in server.csr.pem \
-passin pass:qwerty \
-CA Root.cert.pem \
-CAkey RootCA.key.pem -CAcreateserial -out server.cert.pem \
-days 500 -sha256 -extfile v3.ext;

v3.ext:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

В какой-то момент у меня снова возникли ошибки в браузерах: NET::ERR_CERT_AUTHORITY_INVALID (Google Chrome), MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT (Firefox). И снова мне пришлось разбираться, как решить эту проблему. Я написал новую статью о том, как добавить доверенный SSL-сертификат для локальной среды в Nginx на Debian/Ubuntu. На этот раз мы будем использовать корневой центр сертификации (ЦС).

Эта инструкция была выполнена на операционных системах: Debian 10, Debian 9, Ubuntu 20.10, Ubuntu 20.04, Ubuntu 19.10.

Создание конфигурации OpenSSL

Давайте начнем с этого важного раздела. Нам нужно создать файл конфигурации для OpenSSL, выполнив команду в терминале:

Скопируйте и вставьте следующую подготовленную конфигурацию в новый файл, где DNS.1 — это название вашего сервера (укажите DNS.2, если вам нужна поддержка поддоменов):

Сохраняем изменения и закрываем файл.

Создание доверенного самоподписанного SSL-сертификата

Теперь давайте создадим самоподписанный SSL-сертификат с приватным ключом, используя наш файл конфигурации:

  • req — это команда, которая указывает на использование X.509 (управление запросом подписи сертификата);
  • -x509 — это команда управления данными сертификата, указывающая на создание самоподписанного сертификата;
  • -nodes — это команда, которая пропускает использование парольной фразы;
  • -days 3650 — это команда, которая устанавливает срок действия сертификата в днях (мы установили его на десять лет);
  • -newkey rsa: 2048 — это команда, которая генерирует новый приватный ключ с использованием алгоритма RSA с длиной ключа 2048 бит;
  • -keyout /etc/ssl/private/localhost.key — это путь для размещения файла приватного ключа;
  • -out /etc/ssl/certs/localhost.crt — это путь для размещения файла сертификата;
  • -config /tmp/openssl.cnf — это путь к файлу конфигурации.

В процессе генерации сертификата будет задано несколько вопросов. Вы можете пропустить их:

Создание доверенного самоподписанного SSL-сертификата

Настройка Nginx для использования SSL

Сохраняем изменения и закрываем файл. Проверим конфигурацию на валидность, выполнив команду в терминале:

Теперь применим изменения конфигурации, выполнив команду в терминале:

Установка утилиты certutil

Теперь нам необходимо добавить сгенерированный SSL-сертификат в базу данных, которую использует браузер. Для управления этой базой данных используется утилита certutil, которая входит в состав пакета libnss3-tools. Если у вас нет этого пакета в системе, тогда установим его.

Перед любой установкой программного обеспечения рекомендуется обновить список пакетов репозитория, выполнив команду в терминале:

Установим пакет libnss3-tools, выполнив команду в терминале:

Добавление сертификата в базу данных

Давайте добавим сгенерированный SSL-сертификат в базу данных с помощью утилиты certutil, выполнив команду в терминале:

Эта инструкция была протестирована на браузерах: Google Chrome и Opera.

Браузер Mozilla Firefox не хочет доверять сертификату, он использует базу данных cert8.db, которую я редактировал следующим образом:
certutil -d sql:$HOME/.mozilla/firefox/xqck5xx8.default -A -t "P,," -n localhost.crt -i /etc/ssl/certs/localhost.crt

Тестирование шифрования

Чтобы браузер мог прочитать обновленную базу данных сертификатов, вам необходимо перезапустить свой браузер (закрыть и снова открыть).

Читайте также: