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

Я пытаюсь сгенерировать сертификат со следующим subjectAltName:

hostname
*.hostname
hostname.mydomain.local
*.hostname.mydomain.local

Я генерирую CSR через OpenSSL и затем получаю сертификат от Служб сертификации Microsoft Active Directory. Сертификат работает нормально для следующих альтернативных имен:

hostname
hostname.mydomain.local
*.hostname.mydomain.local

Но, *.hostname просто не работает. Тестируя с помощью Curl, я получаю следующий вывод:

% curl https://m.example/
curl: (51) SSL: certificate subject name '*.example' does not match target host name 'm.example'

Если, с другой стороны, я добавляю m.example в качестве subjectAltName, то это работает. Итак, шаблон с сокращенным именем хоста просто отказывается работать.

2 ответа

Решение

Личный опыт

Некоторое время назад у меня была похожая проблема.

Я настроил локальный DNS для серверов Windows и Linux с.staging в качестве TLD. Чтобы сэкономить на создании и подписании сертификатов для каждого виртуального хоста и избежать необходимости настраивать новые IP-адреса (веб-серверы без SNI), я создал ключ и сертификат для *.staging но все клиенты, которые я пробовал (включая curl), сообщали только, что имя субъекта сертификата *.staging не соответствует имени целевого хоста, когда я пытался загрузить виртуальные хосты на наш промежуточный сервер с использованием TLS.

Соответствующие RFC

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

Ответы по стеку безопасности

В конце концов я был просвещен после прочтения этого превосходного ответа по обмену стека безопасности.

Важно то, что клиенты SSL будут принимать в качестве "действительного сертификата", то есть сертификата, включающего имя, которое "соответствует" предполагаемому имени сервера (которое включено в URL). Это номинально указано в RFC 2818, раздел 3.1, и позволяет использовать много подстановочных имен, включая такие, как "www.*.*c*"сопоставить (теоретически) любое имя сервера, содержащее три компонента, первый из которых"www"а третий содержит хотя бы один"c".

...

Поэтому производители браузеров сделали свои собственные схемы и ограничения. Намного позже был опубликован новый RFC (6125, от марта 2011 г.) с разделом 6.4.3, посвященным обработке подстановочных имен в сертификатах. То, что описывает RFC 6125, больше соответствует действительности и является "предлагаемым стандартом", поэтому на каком-то уровне, по крайней мере, есть желание сделать это. Однако ничто в RFC 6125 не требует отклонения *.com; все же браузеры отклоняют это.

Принятый ответ на вопрос Можно ли выдать сертификат SSL с подстановочным знаком для домена второго уровня? также заслуживает голосования.

редактировать

Я полагал, что, кроме рассказа о личном разочаровании, мой ответ на самом деле не добавляет ничего, кроме ссылок на RFC и соответствующие ответы на Security Stack Exchange; Я думал, что приложу больше усилий и поищу текущий актуальный исходный код, используемый Chromium и Firefox.

Обратите внимание, что в комментариях в исходном коде Chromium явно упоминаются неизвестные домены верхнего уровня (такие как *.intranet) не разрешены.

Кроме того: нет ссылки на настраиваемый пользователем параметр, который может переопределить это поведение.

Исходный код Mozilla

Из Mozilla-центрального ртутного хранилища

Подобно NSS, требуется как минимум две метки, чтобы следовать метке подстановки.

if (isWildcard) {
  // If the DNS ID ends with a dot, the last dot signifies an absolute ID.
  size_t labelCount = (labelLength == 0) ? dotCount : (dotCount + 1);

  // Like NSS, require at least two labels to follow the wildcard label.
  //
  // TODO(bug XXXXXXX): Allow the TrustDomain to control this on a
  // per-eTLD+1 basis, similar to Chromium. Even then, it might be better to
  // still enforce that there are at least two labels after the wildcard.
  if (labelCount < 3) {
    return false;
  }
  // XXX: RFC6125 says that we shouldn't accept wildcards within an IDN
  // A-Label. The consequence of this is that we effectively discriminate
  // against users of languages that cannot be encoded with ASCII.
  if (StartsWithIDNALabel(hostname)) {
    return false;
  }

  // TODO(bug XXXXXXX): Wildcards are not allowed for EV certificates.
  // Provide an option to indicate whether wildcards should be matched, for
  // the purpose of helping the application enforce this.
}

Исходный код хрома

Из репозитория Chromium Git

Не разрешать использование подстановочных знаков для открытых доменов / доменов, контролируемых реестром ICANN, то есть запрещать использование *.com или *.co.uk в качестве допустимых представленных имен.

Кроме того, неявным образом предотвращаются также неизвестные домены верхнего уровня (такие как домены интрасети или новые TLD /gTLD, еще не добавленные в набор данных домена, контролируемого реестром).

if (!reference_domain.empty()) {
  DCHECK(reference_domain.starts_with("."));

  // Do not allow wildcards for public/ICANN registry controlled domains -
  // that is, prevent *.com or *.co.uk as valid presented names, but do not
  // prevent *.appspot.com (a private registry controlled domain).
  // In addition, unknown top-level domains (such as 'intranet' domains or
  // new TLDs/gTLDs not yet added to the registry controlled domain dataset)
  // are also implicitly prevented.
  // Because |reference_domain| must contain at least one name component that
  // is not registry controlled, this ensures that all reference domains
  // contain at least three domain components when using wildcards.
  size_t registry_length =
      registry_controlled_domains::GetRegistryLength(
          reference_name,
          registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
          registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);

  // Because |reference_name| was already canonicalized, the following
  // should never happen.
  CHECK_NE(std::string::npos, registry_length);

  // Account for the leading dot in |reference_domain|.
  bool is_registry_controlled =
      registry_length != 0 &&
      registry_length == (reference_domain.size() - 1);

  // Additionally, do not attempt wildcard matching for purely numeric
  // hostnames.
  allow_wildcards =
      !is_registry_controlled &&
      reference_name.find_first_not_of("0123456789.") != std::string::npos;
}

Комментарии в registry_controlled_domain.h также актуальны:

RegistryControlledDomainService проверяет имя хоста переданного ему GURL и определяет самую длинную часть, контролируемую регистратором. Хотя технически домен верхнего уровня (TLD) для имени хоста является последней точечной частью имени (например,.com или.org), многие домены (например, co.uk) функционируют так, как если бы они были TLD, выделяя любые количество более конкретных, по сути, не связанных имен под ними. Например,.uk является TLD, но никому не разрешено регистрировать домен непосредственно под.uk; "эффективными" TLD являются ac.uk, co.uk и т. д. Мы бы не хотели, чтобы какой-либо сайт в *.co.uk устанавливал cookie для всего домена co.uk, поэтому важно иметь возможность определить, какие домены более высокого уровня функционируют как эффективные TLD, а какие можно зарегистрировать.

Оба проекта Chromium и Mozilla основывают свое определение эффективного ДВУ в Общедоступном списке суффиксов, опубликованном Mozilla.

Клиенты HTTPS должны отказаться от подстановочных знаков TLD, таких как *.com или же *.net (или даже *) по соображениям безопасности: ни один сертификат не должен требовать полномочий для всего TLD.

Теперь, как клиент должен узнать, является ли.example TLD (соответствует *.example запрещено) или краткая форма (соответствие разрешено)? Особенно с учетом того, что новые TLD появляются каждый день, и любой статический список TLD скоро устареет.

Таким образом, клиенты просто отказываются использовать любой шаблон *.XYZ и ожидайте увидеть как минимум две точки в шаблоне.

Обратите внимание, что они должны поддерживать черные списки *.co.uk *.co.jp и т.п.

Другие вопросы по тегам