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