Перейти к содержимому

Как сделать localhost https

  • автор:

Сертификаты для localhost

Иногда разработчикам нужен сертификат для доменного имени “localhost” — для локальной разработки, или для распространения внутри нативных приложений для взаимодействия с web-приложением. Let’s Encrypt не предоставляет сертификатов для “localhost”, т.к. во-первых, у этого доменного имени нет определённого владельца, и во-вторых, нет домена первого уровня — например, “.com” или “.net”. Теоретически, возможно настроить доменное имя так, чтобы оно указывало на адрес 127.0.0.1 , и выпустить для него сертификат после прохождения проверки DNS. Тем не менее, есть более удачные решения. Тем не менее, есть более удачные решения.

Для локальной разработки

При разработке web-приложения обычно запускают локальный web-сервер (Apache, Nginx), настроенный на http://localhost:8000/ . Однако, браузеры по-разному обрабатывают HTTP- и HTTPS-запросы. На HTTPS-странице попытка загрузить Javascript по HTTP-протоколу будет заблокирована. Поэтому, при локальной разработке, используя HTTP, скрипты будут загружаться нормально, но после выкладки на рабочие HTTPS-серверы возникнут проблемы. Чтобы избежать такой ситуации, нужно настроить доступ по HTTPS на локальном web-сервере. Но как избавиться от постоянных сообщений об ошибке сертификата? Как увидеть “зелёный замОк” в адресной строке?

Лучшим решением будет создание собственного сертификата — самоподписанного, или подписанного локальным корневым сертификатом. После создания сертификата — просто добавьте его в доверенное хранилище операционной системы. Подробности см.ниже.

Для нативных приложений, взаимодействующих с web-приложениями

Время от времени, разработчики вынуждены выпускать загружаемые нативные приложения, для расширения функциональности и совместного использования с web-приложениями. Например, десктоп-приложения Dropbox и Spotify умеют сканировать файлы на дисках компьютера, что невозможно для web-приложений. Общий подход в реализации таких нативных приложений состоит в запуске локального web-сервера, и обмену данными с web-приложением через XMLHTTPRequest (XHR) или WebSockets. Web-приложения, как правило, используют HTTPS, поэтому XHR- или WebSockets-запросы по небезопасному протоколу HTTP будут отклонены. Это называется “блокировка смешаного контента” (Mixed Content Blocking). Для взаимодействия с web-приложением, нативное приложение должно быть безопасным.

С одной стороны, современные браузеры считают http://127.0.0.1:8000/ “потенциально заслуживающим доверие” URL-ом, потому что он локальный. Отправленный на 127.0.0.1 трафик гарантированно не уйдёт за пределы компьютера, соответственно, считается безопасным для перехвата по сети. Это означает, что если web-приложение использует HTTPS, а нативное приложение запущено на 127.0.0.1 , то обе программы могут успешно взаимодействовать по XHR. С другой стороны, для localhost это ещё не работает. А WebSocket-ы игнорируют и 127.0.0.1 , и localhost .

Возможно, вы захотите обойти эти ограничения, настроив указание произвольного доменного имени в глобальном DNS на адрес 127.0.0.1 (например, localhost.example.com ), выпустив сертификат для этого домена, распространяя сертификат и соответствующий ему закрытый ключ внутри нативного приложения, и настроив взаимодействие по https://localhost.example.com:8000/ вместо http://127.0.0.1:8000/ . Не делайте этого! Это подвергнет пользователей риску, и сертификат может быть отозван.

Используя доменное имя вместо IP-адреса, вы позволяете злоумышленникам запустить атаку Man in the Middle (MitM) в процессе поиска IP-адреса по доменному имени (DNS Lookup), и внедрить ответ, который укажет на другой IP-адрес. Атакующий может притвориться нативным приложением, подделывая запросы к веб-приложению, что может скомпрометировать ваш аккаунт в веб-приложении, в зависимости от того, как оно разработано.

Успех атаки MitM в этой ситуации возможен, так как для реализации этого, вам придётся отправить закрытый ключ к вашему сертификату с помощью нативного приложения. Это означает, что любой, кто загружает ваше нативное приложение, получает копию закрытого ключа, включая атакующего. Этим вы скомпрометируете закрытый ключ, и Удостоверяющий Центр (УЦ) отзовёт сертификат, как только узнает об этом. У множества нативных приложений были отозваны их сертификаты из-за распространения закрытого ключа.

К сожалению, это сужает список хороших и безопасных способов взаимодействия нативных приложений и соответствующих веб-сайтов. И ситуация может ещё больше усложниться в недалёком будущем, если браузеры продолжат затруднять доступ к localhost.

Так же нужно отметить, что web-сервисы с доступом к нативному API изначально небезопасны, потому что сайты, которые вы не намеревались авторизовать, могут получить доступ к этому API. Если решите углубиться в изучение проблемы, обратите внимание на Cross-Origin Resource Sharing, использование заголовка ответа Access-Control-Allow-Origin, и надёжного HTTP-парсера. Потому как даже серверы, не прошедшие подтверждение, могут посылать предварительные запросы, эксплуатирующие уязвимости в HTTP-парсере.

Создание и поверка собственных сертификатов

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

Простейший способ сгенерировать закрытый ключ и самоподписанный сертификат для localhost — выполнить следующую команду из пакета openssl:

openssl req -x509 -out localhost.crt -keyout localhost.key \ -newkey rsa:2048 -nodes -sha256 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") 

Вы можете сконфигурировать локальный web-сервер, используя файлы localhost.crt и localhost.key, добавив localhost.crt в список доверенных корневых сертификатов.

Если вам требуется чуть больше реализма в сертификатах для локальной разработки, попробуйте minica для создания собственного корневого сертификата, и выпуска конечных сертификатов, подписанных корневым. В итоге вы будете импортировать корневой сертификат вместо самоподписанных конечных сертификатов.

Также, вы можете использовать доменное имя с точками внутри, например, www.localhost , добавив его в файл /etc/hosts как маску 127.0.0.1 . Этот подход чуть изменит способ обработки браузерами хранилища для cookie.

Let's Encrypt - это бесплатный, автоматизированный и открытый Центр Сертификации, созданный для вас некоммерческой организацией Internet Security Research Group (ISRG).

548 Market St, PMB 77519 , San Francisco , CA 94104-5401 , USA

Все письма и запросы отправляйте по адресу:

PO Box 18666 , Minneapolis , MN 55418-0666 , USA

  • GitHub
  • Twitter
  • Mastodon

Как подружить docker, localhost и HTTPS

Когда разрабатываешь веб-сервис, который крутится на проде по HTTPS, есть большой соблазн не запариваться и работать локально по HTTP. Потому что так проще, да и в целом же всё работает плюс-минус одинаково. Если сервис простой, то скорее всего никаких проблем не всплывёт, но если сервис не монолитный и зависит от внешних сервисов или сам предоставляет АПИ клиентам, то проблемы с CORS неизбежны. И обычно эти проблемы обнаруживаются слишком поздно — либо на стейджинге, либо даже после релиза на продакшен.

Браузер начинает ругаться, что запросы с HTTPS на HTTP или наоборот не безопасны, сторонние сервисы перестают отвечать, так как по HTTP работали только тестовые стенды, с которыми вы и работали.

Решение простое — нужно не лениться и максимально приблизить локальную среду к боевой. Благо это задача из серии один раз сделал и используешь для всех последующих проектов.

Docker на продакшене

В этой статье я рассматриваю только локальную сборку через docker-compose, потому что на продакшене, как ни странно, это немного проще. Достаточно выполнить понятную инструкцию по настройке Certbot и/или добавить соответствующий докер-образ с Docker Hub.

Docker на localhost

См. как запустить сайт через docker-compose на примере докеризации Эгеи.

На локалхосте Certbot не подойдёт, так как ему нужно реально существующее доменное имя и доступный через интернет сайт. Поэтому прописать локальный адрес в /etc/hosts не поможет. Решение — выпустить свой самоподписанный сертификат. Да, он не будет приниматься никем, кроме нашей системы, но для локальной разработки этого и не нужно.

Создаём доменное имя

Во-первых, создадим локально доменное имя, чтобы оно было похожим на боевое, а не обычный и скучный localhost. Например, docker.loc для основного сайта и api.docker.loc для API:

$ sudo vim /etc/hosts 127.0.0.1 localhost 127.0.0.1 docker.loc 127.0.0.1 api.docker.loc . 

Если для вашего сервиса необходимо несколько доменов, то пропишите их ниже по аналогии.

Выпускаем свой SSL-сертификат

Для реальных сайтов SSL-сертификаты выдаются специальными сертификационными центрами за деньги. За это они потом могут подтвердить верность домена по запросу любого браузера. Мы же выпустим свой сертификат и сами его подтвердим.

SSL-сертификат создаётся одной командой и состоит из двух частей: публичного сертификата и секретного ключа.

openssl req -x509 -out docker.loc.crt -keyout docker.loc.key \ -newkey rsa:2048 -nodes -sha256 \ -subj '/CN=docker.loc' -extensions EXT -config <( \ printf "[dn]\nCN=docker.loc\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:docker.loc\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

Файлы docker.loc.crt и docker.loc.key будут сохранены в той папке, откуда вы запускаете команду.

Добавляем сертификаты в ОС

Ниже пример, как это сделать на Mac OS X.

  1. Найдите сертификат docker.loc.crt в Finder (или можно в нужной папке консоли ввести «open .»)
  2. Дважды кликните по нему, появится окно.

  1. Введите пароль администратора
  2. Теперь нужно найти этот сертификат в Keychain Access и выбрать Trust Always

Добавляем сертификаты в docker-compose сборку

Сертификаты нужно положить в контейнер с веб-сервером. Я приведу пример для Nginx и сборки по типу https://github.com/pluseg/e2-docker.

Расположение сертификатов и конфигов

В этой сборке папки из app/docker/nginx монтируются прямо в nginx-контейнер. Поэтому удобно расположить файлы так:

 - app --- docker ----- nginx ------- conf.d --------- docker.loc.conf ------- ssl --------- docker.loc.crt --------- docker.loc.key

Пример docker.loc.conf (проект на PHP + Symfony)

# лучше с php соединять через socket upstream php-upstream < server web:9000; ># Редиректим HTTP на HTTPS server < listen 80; listen [::]:80; server_name docker.loc; return 301 https://$server_name$request_uri; >server < listen 443 ssl; listen [::]:443 ssl; root /var/www/html/docs; server_name docker.loc; ssl_certificate /etc/nginx/ssl/docker.loc.crt; ssl_certificate_key /etc/nginx/ssl/docker.loc.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; location / < try_files $uri /index.php$is_args$args; >location ~ ^/(index|app|app_dev|config)\.php(/|$) < fastcgi_pass php-upstream; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; fastcgi_read_timeout 300; >error_log /var/log/nginx/docker.loc-error.log; access_log /var/log/nginx/docker.loc-access.log; >

Пример docker-compose.yml

Добавляем 443 порт и несколько volume с конфигами и сертификатами.

version: '3.2' services: . nginx: image: nginx:latest ports: - 80:80 - 443:443 volumes: - ./app/docker/nginx/conf.d:/etc/nginx/conf.d - ./app/docker/nginx/ssl:/etc/nginx/ssl - ./:/var/www/html - ./var/logs/nginx:/var/log/nginx command: /bin/bash -c "exec nginx -g 'daemon off;'"

Запускаем и проверяем

docker-compose up -d --build

Локальный https. Сертификаты для localhost

Иногда необходимо чтобы какой-нибудь локальный сервер с каким-нибудь локальным доменом можно было использовать через https. Для этого можно использовать приложение mkcert.

Установка

Варианты установки описаны в репозитории mkcert (https://github.com/FiloSottile/mkcert)

Вариант установки на Ubuntu

  1. Установка certutil
sudo apt install libnss3-tools
git clone https://github.com/FiloSottile/mkcert && cd mkcert go build -ldflags "-X main.Version=$(git describe --tags)"

Генерация сертификатов

mkcert -install
Created a new local CA ? The local CA is now installed in the system trust store! ⚡️ The local CA is now installed in the Firefox trust store (requires browser restart)! ?
mkcert example.com "*.example.com" example.test localhost 127.0.0.1 ::1
Created a new certificate valid for the following names ? - "example.com" - "*.example.com" - "example.test" - "localhost" - "127.0.0.1" - "::1"

The certificate is at "./example.com+5.pem" and the key at "./example.com+5-key.pem" ✅

Сертификаты будут сгенерированы в папке запуска mkcert. В дальнейшем эти файлы будут использованы

Корневой сертификат

Расположение корневого сертификата: /home/user/.local/share/mkcert либо можно найти выполнив команду

mkcert -CAROOT

Включение сертификатов в Apache, Ngxinx

Apache

a2enmod ssl
 ServerName example.com SSLCertificateFile /path/to/certs/example.com+4.pem SSLCertificateKeyFile /path/to/certs/private/example.com+4-key.pem . 

Примечание: в Apache сертификаты лучше ставить внутри проверки модуля сертификатов, например в файле default-ssl или внутри проверки модуля IfModule mod_ssl.c>

Включить сертификаты (может не понадобиться)

a2ensite default-ssl.conf
systemctl restart apache2

Nginx

Сертификаты лучше скопировать в папку сертификатов в nginx, либо указать путь до сертификатов

server < listen 80; listen 443 ssl; ssl on; ssl_certificate /path/to/certs/example.com+4.pem; ssl_certificate_key /path/to/certs/private/example.com+4-key.pem; server_name example.com; location / < root /var/www/html/example; index index.html; >>
systemctl restart nginx

Браузер

Перезагружаем браузер и теперь можно видеть https на ваших локальных доменных именах.

Примечание

Опасность использования заключается в том, чтобы ваш корневой сертификат не утек в сеть. Это опасно тем, что при умелом использовании злоумышленником вашим корневым сертификатом, вредоносные или недоверенные сайты могут оказаться доверенными

Источники

  • FiloSottile/mkcert: A simple zero-config tool to make locally trusted development certificates with any names you’d like.
  • Создание локального самоподписного сертификата с доверием браузеров Ubuntu 18 / Debian 8/9

Leave a comment Cancel reply

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

Найдите нас

Адрес
123 Мейн стрит
Нью Йорк, NY 10001

Часы
Понедельник—пятница: 9:00–17:00
Суббота и воскресенье: 11:00–15:00

Поиск

О сайте

Здесь может быть отличное место для того, чтобы представить себя, свой сайт или выразить какие-то благодарности.

Рубрики

Метки

Рефералка. Буду благодарен) (Сам им пользуюсь)

Установка https на localhost

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

Сначала создаем файлы Certificate authority (CA). Вместо Example-Root-CA можно подставить свое название.

openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA" openssl x509 -outform pem -in RootCA.pem -out RootCA.crt

Допустим мы хотим использовать домен project.local , для этого создаем файл domains.ext со следующим содержимым:

authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = project.local

Затем генерируем файлы для домена. US , YourState , YourCity , Example-Certificates можно заменить на свои данные.

openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local" openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt

Затем добавляем сертификат в настройки веб-сервера. В nginx это будет выглядеть примерно так:

listen 443 ssl; server_name project.local; ssl_certificate /path/to/localhost.crt; ssl_certificate_key /path/to/localhost.key;

Теперь необходимо добавить наш CA в список доверенных. - В Windows 10 для Chrome, IE11 и Edge это можно сделать, нажав правой клавишей на файл RootCA.crt и выбрав "Установить". Сертификат необходимо добавить в "Trusted Root Certification Authorities". - В Firefox это можно сделать, включив на странице about:config опцию security.enterprise_roots.enabled . Либо перейдя на about:preferences#privacy импортировать RootCA.pem .

Нерешенные проблемы: нет возможности обращаться к произвольному локальному IP (например, 127.0.0.9 ) по https - необходимо обязательно использовать домен.

  • How to create an HTTPS certificate for localhost domains
  • Сертификаты для localhost

Добавить комментарий

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