Сам сертификат содержит сервер альтернативное имя субъекта, например, «server.xyz.abc.com». Из журналов Wireshark мы видим, что уровень TLS иногда отправляет SNI как «server.xyz.abc.com», а иногда как «SERVER.xyz.abc.com». Обратите внимание на то, что часть имени сервера написана заглавными буквами.
Запрос успешен, когда уровень TLS отправляет SNI как «server.xyz.abc.com», и кажется, что запрос не выполняется, когда SNI входит в «SERVER.xyz.abc.com».
Мы получаем сообщение «org.eclipse.jetty.http.BadMessageException: 400: Invalid SNI».Чтобы это исправить, мы попросили клиента исправить сертификат, добавив «SERVER.xyz.abc.com» в альтернативное имя субъекта, и развернули этот сертификат на сервере. Итак, сертификат теперь содержит:
server.xyz.abc.com
SERVER.xyz.abc.com
Однако это по-прежнему не устранило проблему, и сообщение о недопустимом SNI продолжает периодически приходить, хотя Wireshark показывает, что SNI Client Hello поступает точно так же, как в сертификате. Мы заметили одну вещь: сбой по-прежнему происходит, когда имя в верхнем регистре входит в качестве SNI в запросе Client Hello.
У меня есть следующие вопросы:
- Известна ли какая-либо проблема с Jetty, связанная с чувствительностью к регистру SNI, и правильно ли добавлять в сертификат имя сервера в верхнем регистре?
- Почему уровень TLS поочередно отправляет имя в верхнем и нижнем регистре, и есть ли где-нибудь какая-либо настройка, позволяющая заставить его отправлять его, скажем, в нижнем регистре?
- В худшем случае, чтобы это исправить, возможно, нам придется отключить проверку SNI. Это единственный способ сделать это, поскольку для отключения этой проверки нам потребуется внести изменения в код. Судя по другим сообщениям, я думаю, что нет настраиваемого параметра, позволяющего отключить эту проверку в Jetty.
[ОБНОВЛЕНИЕ]:
При дальнейшем копании, включив ведение журнала отладки Jetty, мы обнаружили, что хост SNI имеет значение null. . Таким образом, этот вызов внутри кода Jetty (SecureRequestCustomizer.java) для получения значения хоста SNI возвращает нулевое значение для «sniHost» и вызывает исключение. Есть идеи, почему это значение будет нулевым и что мы можем с этим поделать?
protected void checkSni(Request request, SSLSession session)
{
if (isSniRequired() || isSniHostCheck())
{
String sniHost = (String)session.getValue(SslContextFactory.Server.SNI_HOST);
X509 x509 = getX509(session);
if (x509 == null)
throw new BadMessageException(400, "Invalid SNI");
String serverName = Request.getServerName(request);
if (LOG.isDebugEnabled())
LOG.debug("Host={}, SNI={}, SNI Certificate={}", serverName, sniHost, x509);
if (isSniRequired() && (sniHost == null || !x509.matches(sniHost)))
throw new BadMessageException(400, "Invalid SNI");
if (isSniHostCheck() && !x509.matches(serverName))
throw new BadMessageException(400, "Invalid SNI");
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... is-correct
Мобильная версия