Иногда в процессе веб-разработки требуется безопасное окружение в браузере, то есть HTTPS. Удобный способ сделать это — установить локальный УЦ и автоматизировать выдачу сертификатов на любые поддомены lcl.host и localhost. Это более функциональная и удобная альтернатива самоподписанным сертификатам.

Для установки локального УЦ есть инструменты lcl.host и mkcert, которые помогают быстро настроить и использовать HTTPS в dev-окружении.

Если mkcert относительно хорошо известен, то lcl.host появился только в марте 2024 года. В некотором отношении это более удобный инструмент — он настраивает HTTPS в интерактивном режиме консоли в несколько нажатий кнопки (об этом ниже).

HTTPS в dev-окружении


В документации lcl.host поясняется, что локальный HTTPS может пригодиться при разработке следующих сервисов:

  • Публичные веб-сайты и приложения. В этом случае в продакшне есть публичный сертификат, а мы хотим имитировать эту среду локально.
  • SaaS. Сервисы в интернете, например, SaaS-проект на Ruby on Rails.
  • Микросервисы. Например, приложение на React обращается к отдельному API бэкенда, устанавливая cookies и делая API-запросы.

Локальный HTTPS решает ряд проблем в реальной веб-разработке:

  • Смешанный контент. В идеальном мире всё содержимое передаётся по HTTPS. К сожалению, в реальном мире защищённая веб-страница может запрашивать незащищённое содержимое по HTTP. Поэтому нужно добавить HTTPS в локальную среду, чтобы имитировать смешанный контент в продакшне.
  • Ошибки CORS. Когда веб-страница загружает содержимое из нескольких источников, контекст безопасности браузера может измениться, что приведёт к ошибке CORS. Сохраняя в браузере тот же контекст безопасности, что и в продакшне, можно локально воспроизвести и отладить проблемы CORS.
  • HTTP/2. HTTP/2 и HTTP/3 требуют (или не позволяют избежать) использования TLS.
  • Безопасные куки. Как правило, браузеры работают с куками на localhost так же, как и в продакшне, за исключением безопасных куков (с атрибутом Secure, который ограничивает область применения куки). Чтобы поведение браузеров было одинаковым, нужно использовать HTTPS в локальной среде аналогично продакшну.
  • OAuth и безопасные сторонние эндпоинты. Многие внешние организации требуют HTTPS для эндпоинтов даже в локальной разработке.
  • Приложения и маркетплейсы на локальном хосте. Некоторые инструменты, которые запускают веб-сервер на локальном порту и открываются в браузере через http://localhost:[PORT], иногда требуют HTTPS, также как маркетплейсы вроде Heroku, Slack и AWS (при разработке приложений для маркетплейса).
  • Требования к инструментам. Некоторые dev-инструменты для корректной работы требуют HTTPS.

Сравнение с самоподписанными сертификатами


Обычно в dev-окружении используются самоподписанные сертификаты, но им присущи некоторые недостатки:

  • Все члены команды должны вручную создавать (и пересоздавать) свои собственные самоподписанные сертификаты.
  • Самоподписанные сертификаты нужно вручную добавлять в каждое хранилище доверия в системе.
  • Домены app.localhost работают не везде, поэтому для небраузерных клиентов (например, curl) требуются записи в /etc/hosts или DNS-сервер разработки.
  • Запуск приложений в локальных контейнерах требует постоянного обновления сертификатов и хранилища доверия.

Система lcl.host с приватным УЦ решает эти проблемы, потому что устанавливается в системные каталоги доверенных сертификатов, обеспечивая универсальность работы в разных средах и внутри, вне и даже между контейнерами, а поддержка ACME позволяет настраивать автоматическую выдачу и продление сертификатов. Имена хостов работают повсюду, без какой-либо настройки. Здесь тот же безопасный контекст браузера, что и в продакшне, без причуд браузера в контексте localhost.

Настройка программы не требует знания формата сертификатов и принципов их работы.

Чтобы настроить HTTPS в разработке, нужно установить инструментарий Anchor CLI, запустить anchor lcl и просто следовать инструкциям.

$ brew install anchordotdev/tap/anchor
$ anchor lcl

Под Windows нужно установить пакетный менеджер Chocolatey, а уже из него — Anchor и lcl:

> choco install anchor --version=0.0.22
> anchor lcl



После запуска программы большинство инструкций для настройки HTTPS-окружения — это нажимать Enter, вводить имена доменов, скопировать код в окно браузера и т. д., как в базовом примере:

~/nextjs-app $ anchor lcl                                                                                                         
| Let's set up HTTPS in your local development environment!                                                                       
|                                                                                                                                 
| lcl.host (made by the team at Anchor) is a fast and completely free                                                             
| way to add HTTPS to local applications & services.                                                                              
|                                                                                                                                 
| Once setup is finished you'll have a secure context in your browsers                                                            
| and local system so you can run HTTPS locally.                                                                                  
# System Configuration `anchor lcl config`                                                                                        
    | Before issuing HTTPS certificates for your local applications, we need                                                      
    | to configure your browsers and OS to trust your personal certificates.                                                      
    |                                                                                                                             
    | We'll start a local diagnostic webserver to guide you through                                                               
    | the system configuration process.                                                                                           
    - Scanned local configuration and status.                                                                                     
    - Entered hi-ankydotdev.lcl.host domain for lcl.host diagnostic certificate.                                                  
    | Now it's time to create your application's resources in Anchor.dev and start                                                
    | provisioning HTTPS certificates for your development environment                                                            
    - Created hi-ankydotdev [hi-ankydotdev.lcl.host, hi-ankydotdev.localhost] diagnostic server resources on Anchor.dev.          
    - Great, http://hi-ankydotdev.lcl.host:4433 works as expected (without HTTPS)                                                 
    | Next, we'll add your personal CA certificates to your system's trust stores                                                 
    | This may require sudo privileges. Here's why:                                                                               
    | https://lcl.host/why-sudo                                                                                                   
    - Compared local stores to expected CA certificates: need to install 2 missing certificates.                                  
    - Updated System (MacOS Keychain): installed ankydotdev/localhost - AnchorCA [RSA, ECDSA]                                     
    - Updated Network Security Services (NSS): installed ankydotdev/localhost - AnchorCA [RSA, ECDSA]                             
    - Updated Homebrew OpenSSL (ca-certificates): installed ankydotdev/localhost - AnchorCA [RSA, ECDSA]                          
    | Before we move on, let's make sure your system is configured properly                                                       
    | by trying out HTTPS with our local diagnostic webserver.                                                                    
    - Success! https://hi-ankydotdev.lcl.host:4433 is encrypted and HTTPS is working as expected                                  
# Application Setup `anchor lcl setup`                                                                                            
    | Start by choosing the server type of your local application so we can generate                                              
    | setup instructions for your specific application type.                                                                      
    - Scanned current directory.                                                                                                  
    - Entered javascript application type                                                                                         
    - nextjs-app application name.                                                                                                
    - Entered nextjs-app domain for local application development                                                                 
    | Now it's time to create your application's resources in Anchor.dev and start                                                
    | provisioning HTTPS certificates for your development environment                                                            
    - Created nextjs-app [nextjs-app.lcl.host, nextjs-app.localhost] javascript server resources on Anchor.dev.                   
# Provision Certificate `anchor lcl mkcert`                                                                                       
    - Provisioned certificate for [nextjs-app.lcl.host, nextjs-app.localhost].                                                    
    - Wrote certificate to ./nextjs-app.lcl.host+1-cert.pem                                                                       
    - Wrote chain to ./nextjs-app.lcl.host+1-chain.pem                                                                            
    - Wrote key to ./nextjs-app.lcl.host+1-chain.pem                                                                              
    | You can use these certificate files to manually configure your application and start                                        
    | using HTTPS in your development environment.                                                                                
# Next Steps                                                                                                                      
    | Now that you have local HTTPS setup, let's automate the certificate provisioning process                                    
    | so you never have to manually provision future certificates.                                                                
    |                                                                                                                             
    | We've generated a setup guide for your application on Anchor.dev with instructions on                                       
    | how to automate certificate provisioning inside your application.                                                           
    - Opened https://anchor.dev/ankydotdev/services/nextjs-app/guide.


lcl.host можно сравнить с инструментом mkcert, который тоже предназначен для создания локально доверенных dev-сертификатов с произвольными именами. Он тоже создаёт локально приватный удостоверяющий центр уже в процессе установки:

$ 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"



Как написано в документации, lcl.host сочетает в себе управляемый приватный УЦ Anchor, DNS-зону для разрешения поддоменов в локальной системе и утилиту командной строки Anchor CLI для управления локальными хранилищами доверия. Нужно заметить, что управляемый УЦ Anchor — это уже платная услуга. Отличие lcl.host от инструмента mkcert том, что шаги по настройке в lcl.host максимально автоматизированы в интерактивном консольном UI (см. пример выше).

В любом случае, локальный УЦ — более функциональная альтернатива самоподписанным сертификатам в dev-окружении.

Комментарии (3)


  1. CarrolCox
    26.05.2024 22:45
    +16

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

    Так же как при использовании lcl.host и mkcert

    Самоподписанные сертификаты нужно вручную добавлять в каждое хранилище доверия в системе.

    Так же как при использовании lcl.host и mkcert

    Домены app.localhost работают не везде, поэтому для небраузерных клиентов (например, curl) требуются записи в /etc/hosts или DNS-сервер разработки.

    Какое-либо расширенное разрешение доменных имён не предо при использовании lcl.host и mkcert, и работает точно так же при использовании любого инструмента управления сертификатами.

    Запуск приложений в локальных контейнерах требует постоянного обновления сертификатов и хранилища доверия.

    Так же как при использовании lcl.host и mkcert

    Описанные инструменты lcl.host и mkcert всего лишь упрощают работу с *самоподписанными сертификатами* и имеют те же ограничения, а так же дополнительно ограничивают использование, за счёт чего они и снижают требования к разработчику.

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


  1. dinisoft
    26.05.2024 22:45

    Думаю во всей этой истории проще использовать https://get.localhost.direct/


    1. SabMakc
      26.05.2024 22:45

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

      P.S. при всей удобности подобного подхода - есть и риски. DNS-ответы могут подменить, после чего трафик пойдет неизвестно куда.
      P.P.S. знаю подобный проект, с прикрученным traefik для управления поддоменами: https://habr.com/ru/articles/714916/