Как настроить HTTPS для локального сервера на iOS: обход HSTS в Safari

Если вы разрабатываете iOS-приложение с встроенным веб-сервером (например, Mongoose), который работает временно в фоне, рано или поздно столкнётесь с проблемой Safari: при попытке открыть локальную страницу через HTTP браузер выдаст ошибку «Cannot open the page… HTTPS-only mode enabled».

Это связано с HSTS – механизмом принудительного использования HTTPS. Но как решить задачу, если сервер и клиент находятся внутри одного приложения и используют loopback-адрес (127.0.0.x), а публичный IP или DNS недоступны? Давайте разбираться, не переживайте – всё решаемо.

Почему Safari упорно требует HTTPS

Современные браузеры, включая Safari, активно борются с незашифрованным трафиком. HSTS (HTTP Strict Transport Security) – это политика, которая «запоминает» домены, обязанные использовать HTTPS. Если ваш локальный сервер отдаёт контент по HTTP, Safari просто заблокирует запрос после первого успешного подключения по HTTPS (даже если это было в другом контексте).

Кстати, ошибка «Cannot navigate to HTTP URL…» возникает именно из-за этой политики. Но выход есть: достаточно настроить сервер на работу с HTTPS, даже если он доступен только внутри приложения. И для этого не нужен публичный IP или DNS-запись – достаточно самоподписанного сертификата и пары трюков с локальным разрешением имён.

Пошаговая настройка HTTPS для Mongoose без публичных ресурсов

Основная идея: создать самоподписанный SSL-сертификат, привязать его к домену (например, local.dev), а затем «объяснить» устройству, что этот домен соответствует 127.0.0.1. Вот как это сделать:

1. Генерация сертификата

Используйте OpenSSL (установите через Homebrew, если нет):

openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj "/CN=local.dev"

Параметр – subj задаёт Common Name – имя домена. Можно выбрать любое, но позже оно должно совпадать с адресом в приложении.

2. Настройка Mongoose

Загрузите сертификат и приватный ключ в код. Пример для Mongoose:

struct mg_mgr mgr;  
mg_mgr_init(&mgr);  
struct mg_connection *c = mg_http_listen(&mgr, "https://0.0.0.0:8000", eh, NULL);  
mg_tls_opts opts = { .cert = "cert.pem", .certkey = "key.pem" };  
mg_tls_init(c, &opts);

Убедитесь, что файлы cert.pem и key.pem добавлены в проект и доступны в бандле.

3. Локальное разрешение домена

Добавьте в файл /etc/hosts на устройстве строку:

127.0.0.1 local.dev

Если редактирование hosts недоступно (например, на реальных iOS-устройствах), используйте кастомный URL-схему в приложении для перенаправления на https://local.dev:8000.

4. Доверие сертификату

Самоподписанные сертификаты по умолчанию не доверяются. Чтобы Safari не ругался:

  • Экспортируйте cert.pem в формате .der (например, через терминал: openssl x509 -in cert.pem -outform der -out cert.der).
  • Установите его на устройство через профиль конфигурации или програмно, используя SecTrustEvaluate.

Типичные ошибки и как их избежать

Даже после настройки HTTPS могут возникнуть проблемы:

  • «Invalid certificate» в Safari: Убедитесь, что Common Name в сертификате совпадает с доменом в URL (если вы используете local.dev, а в коде прописан localhost, ошибка неизбежна).
  • Сервер не запускается: Проверьте, что порт не занят (на iOS иногда требуются кастомные разрешения в Info.plist для фоновых сокетов).
  • HSTS всё равно блокирует запрос: Очистите кеш HSTS в Safari (Настройки → Safari → Очистить историю и данные).

Кстати, если вам не хочется возиться с hosts-файлами, можно использовать Bonjour для локального разрешения имён (mDNS). Например, зарегистрируйте службу с типом _https._tcp и доменом yourapp.local – тогда Safari автоматически обнаружит сервер.

И последнее: Mongoose поддерживает HTTP/2, что может ускорить загрузку файлов. Попробуйте включить его в настройках, добавив #define MG_ENABLE_HTTP2 1 перед компиляцией библиотеки.

Теперь ваш локальный сервер будет работать по HTTPS, обходя ограничения Safari. Да, придётся повозиться с сертификатами и доменами, зато пользователи не увидят раздражающих ошибок. А если что-то пойдёт не так – проверьте, нет ли опечаток в конфигах (вот где чаще всего кроются проблемы!).

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

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

Новое
Интересное