
Иногда в процессе веб-разработки требуется безопасное окружение в браузере, то есть 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-окружении.
