Как установить HTTPS локально без надоедливых уведомлений в браузере

Дата публикации:Май 17, 2017

Локальная настройка 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        = test@example.com

[ 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

  1. В Chrome открываем разрабатываемый сайт, который вы сконфигурировали для использования сертификата
  2. Щелкаем Cmd-Alt-I, чтобы открыть инструменты разработчика
  3. Щелкаем по вкладке Security
  4. Щелкаем по кнопке View certificate

Вы должны увидеть следующий экран.

Теперь перетаскиваем иконку сертификата в папку в приложении Finder.

Сертификат будет создан в данной папке. Делаем двойной щелчок по файлу. Если у вас имеются многочисленные keychain’ы, вы должны увидеть следующее окно:

Щелкаем Add. Если у вас только один keychain, то в таком случае ваш сертификат будет добавлен без какого-либо уведомления. Вне зависимости от того, появлялось ли уведомление или нет, у вас должно открыться окно Keychain Access. Найдите там свой сертификат:

Сделайте по нему двойной щелчок. Откроется окно с информацией о сертификате. Раскройте секцию Trust. Смените поле «When using this certificate:» на «Always Trust».

Закройте окно сертификата. Он попросит вас ввести пароль (или просканировать ваш палец), сделайте это. Теперь снова зайдите на свой разрабатываемый сайт.

Вы можете удалить файл сертификата из папки, в которую вы его перетащили, поскольку теперь он добавлен в keychain системы.

Если вам требуется SSL-сертификат для активного сайта, вы можете всегда приобрести его в магазине LeaderSSL.

Источник: https://deliciousbrains.com

Поделиться

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.