Локальная настройка HTTPS может стать достаточно сложной задачей. Даже если вы успешно решите вопрос с самоподписанными сертификатами, вы все равно столкнетесь с ошибками приватности в браузере. В этой статье я расскажу вам про создание самоподписанных сертификатов, а также покажу вам интересный трюк, который поможет справиться с ошибками приватности в браузере.
В течение примерно года я работал с HTTPS в своей локальной среде разработки. На прошлой неделе я обновился до Google Chrome 58, и что-то изменилось, моя среда разработки перестала правильно функционировать – я стал получать уведомления о приватности в браузере.
В отличие от прошлых ошибок приватности, здесь уже не было варианта «Add Exception». Я проверил Firefox, и его поведение было таким же. В Safari пока все по-прежнему работало.
Поиск по ERR_CERT_COMMON_NAME_INVALID практически не дал никаких результатов, однако в конечном счете я обнаружил решение в трекере багов Chromium. Оказалось, что Chrome и Firefox отказались от поддержки commonName соответствия в сертификатах.
Мне удалось исправить мою сборку, воспользовавшись предложениями в комментарии Chromium (я расскажу об этом далее). В этой статье я покажу вам, как избавиться от ошибок приватности в браузере. Я буду обновлять эту статью, если что-то поменяется в будущем.
Зачем устанавливать HTTPS локально?
Почему бы просто не использовать обычный протокол HTTP локально? Причина проста: если ваш работающий сайт перенесен на HTTPS, и вы ведете разработку локально на HTTP, ваши среды разработки и продакшна будут отличаться. К примеру, моя среда разработки представляет собой Ubuntu сервер на виртуальной машине VMware на Mac. Продакшн-среда – это Ubuntu-сервер, работающий на Linode с практически аналогичной конфигурацией.
Естественно, среда разработки должна быть максимально похожа на вашу продакшн-среду. Если этого не происходит, вы получаете массу проблем, возникающих в продакшне, которые не были видны в среде разработки. Разработка HTTP-сайта, когда ваш продакшн представляет собой HTTPS-сайт – это лишний риск.
Создание самоподписанного сертификата
Как и в случае с включением HTTPS в продакшне, вам сначала понадобится сертификат. Для работающего сайта вы обычно запрашиваете сертификат у удостоверяющего центра, такого как Let’s Encrypt, Comodo и т.д. Для локальной среды разработки можно вполне обойтись самоподписанным сертификатом, генерируемым в командной строке. Делается это просто:
openssl req -new -sha256 -newkey rsa:2048 -nodes \ -keyout dev.deliciousbrains.com.key -x509 -days 365 \ -out dev.deliciousbrains.com.crt
Выполнив эту команду, вы получите ряд вопросов:
Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:dev.deliciousbrains.com Email Address []:
Большинство из этих вопросов не так важны для среды разработки. Ответы будут отображаться при просмотре информации в сертификате, но это никак не повлияет на то, будет ли браузер считать ваш сайт защищенным или нет. В действительности единственный вопрос, на который нужно дать ответ – это Common Name (CN). Ответ на этот вопрос определяет, для какого домена сертификат будет действителен.
Однако сейчас вопрос про CN также является неважным. Что касается Chrome 58 и Firefox 48, в них Common Name игнорируется при сопоставлении доменного имени с сертификатом. По этой причине я и начал получать ошибки приватности, когда обновился до Chrome 58.
«В RFC 2818 описаны два метода сопоставления доменного имени с сертификатом – использование доступных имен в расширении subjectAlternativeName, или, в случае отсутствия расширения SAN, откат к commonName. Откат к commonName был признан устаревшим в RFC 2818 (опубликован еще в 2000 году), однако поддержка по-прежнему оставалась в разных TLS-клиентах, зачастую некорректно».
Устарел аж с 2000 года. Определено, пришло время для удаления поддержки.
Поэтому теперь доменное имя должно определяться в расширении Subject Alternative Name (SAN) сертификата:
При создании самоподписанного сертификата нам нужно предоставить конфигурационный файл в OpenSSL и определить SAN в этом конфигурационном файле. Команды будут следующими:
openssl req -config dev.deliciousbrains.com.conf -new -sha256 -newkey rsa:2048 \ -nodes -keyout dev.deliciousbrains.com.key -x509 -days 365 \ -out dev.deliciousbrains.com.crt
Для конфигурационного файла dev.deliciousbrains.com.conf я использовал код со Stack Overflow, связанный с комментарием в Chromium, который я уже упоминал ранее.
Единственное изменение, которое я сделал, это заменил строку DNS.1 = example.com на DNS.1 = dev.deliciousbrains.com и удалил остальные строки DNS под ней. Вот полный конфиг с удаленными комментариями и очисткой форматирования:
[ req ] default_bits = 2048 default_keyfile = server-key.pem distinguished_name = subject req_extensions = req_ext x509_extensions = x509_ext string_mask = utf8only [ subject ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = NY localityName = Locality Name (eg, city) localityName_default = New York organizationName = Organization Name (eg, company) organizationName_default = Example, LLC commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = Example Company emailAddress = Email Address emailAddress_default = [email protected] [ x509_ext ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" [ req_ext ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" [ alternate_names ] DNS.1 = dev.deliciousbrains.com
Если вы используете MAMP, у вас может возникнуть соблазн создать свои самоподписанные сертификаты через MAMP UI:
Я пробовал это с MAMP 4.1.1, но, к сожалению, он не определяет SAN, и потому вы получите ошибку приватности ERR_CERT_COMMON_NAME_INVALID в браузере. Пока разработчики MAMP не обновят программу для определения SAN, вам придется создавать сертификаты в командной строке и затем добавлять их в MAMP.
Установка сертификата
Затем вам нужно будет установить сертификат в Nginx, Apache или на любой другой веб-сервер, который вы используете. Я не буду описывать этот процесс, поскольку он зависит от вашей среды. В моем случае я просто следовал инструкциям Hosting WordPress Yourself. Если вы используете MAMP, вы можете выбрать сертификат и файлы ключей через интерфейс, как показано на скриншоте.
После того, как вы обновите конфиг вашего веб-сервера и перезапустите его (не забудьте это сделать), загрузка вашего сайта все равно приведет к появлению ошибки приватности в браузере.
Вы можете заметить, что теперь возникает другая ошибка — ERR_CERT_AUTHORITY_INVALID. Браузер не доверяет сертификату, потому что мы подписали его самостоятельно, а не получили от удостоверяющего центра. Однако мы можем добавить сертификат в систему macOS Keychain и указать, что сертификат всегда должен быть доверенным.
Добавляем сертификат в macOS Keychain
- В Chrome открываем разрабатываемый сайт, который вы сконфигурировали для использования сертификата
- Щелкаем Cmd-Alt-I, чтобы открыть инструменты разработчика
- Щелкаем по вкладке Security
- Щелкаем по кнопке View certificate
Вы должны увидеть следующий экран.
Теперь перетаскиваем иконку сертификата в папку в приложении Finder.
Сертификат будет создан в данной папке. Делаем двойной щелчок по файлу. Если у вас имеются многочисленные keychain’ы, вы должны увидеть следующее окно:
Щелкаем Add. Если у вас только один keychain, то в таком случае ваш сертификат будет добавлен без какого-либо уведомления. Вне зависимости от того, появлялось ли уведомление или нет, у вас должно открыться окно Keychain Access. Найдите там свой сертификат:
Сделайте по нему двойной щелчок. Откроется окно с информацией о сертификате. Раскройте секцию Trust. Смените поле «When using this certificate:» на «Always Trust».
Закройте окно сертификата. Он попросит вас ввести пароль (или просканировать ваш палец), сделайте это. Теперь снова зайдите на свой разрабатываемый сайт.
Вы можете удалить файл сертификата из папки, в которую вы его перетащили, поскольку теперь он добавлен в keychain системы.
Источник: https://deliciousbrains.com