Включить наблюдаемость (ведение журнала / метрики) рукопожатий TLS на встроенном Tomcat 8.5 с Java 8

Мы запускаем Spring Boot API, где мы завершаем TLS в самом API. Несколько раз мы наблюдали чрезмерную загрузку ЦП после того, как обширные поиски были вызваны тем, что кто-то создал много подключений (законно или ошибочно из-за отклоненных клиентских сертификатов) или не использовал возобновление TLS.

Чтобы предотвратить эти долгие и дорогостоящие поиски в будущем, мы хотели бы регистрировать, когда рукопожатие не удается или успешно, а также почему и используется ли возобновление сеанса.

Мы не привязаны конкретно к нашему текущему стеку, и обновление до другого сервера, такого как Undertow или WebFlux, и / или новой версии Java также подойдет. Точно так же мы можем использовать APR, NIO или собственные привязки для достижения этих целей.

Следующие другие вопросы предполагают, что в настоящее время нет готового решения. Они предлагают расширить Реализация JSSE или создать настраиваемую фабрику сокетов SSL или переключить уровень адаптера NIO на Debug. Эти решения кажутся хрупкими, и мне интересно, есть ли более расширяемый механизм, основанный на событиях или обратных вызовах. В качестве альтернативы мы могли бы включить журналы рукопожатий из Java, но они являются подробными, и при этом мы можем значительно снизить производительность.

Обновление1: Я попытался пойти по пути использования настроенной SSLServerSocketFactory. sun.security.ssl.SSLServerSocketFactoryImpl возвращает sun.security.ssl.SSLServerSocketImpl при связывании, который возвращает хороший SSLSocket при приеме. Я мог бы всегда обернуть этот метод accept, чтобы добавить обработчик завершения. Единственный недостаток: SSLServerSocketFactoryImpl финальный, поэтому просто завернуть не могу. Это означает, что мне нужно скопировать много кода, и он все равно будет давать мне показатели только при успешных рукопожатиях. Копирование кода было бы бременем обслуживания, потому что это специфический код JRE.

например событие или обратные вызовы: Об этом уже спрашивали на SO без какого-либо хорошего ответа из того, что я помню. Вы также даете упомянутые решения (расширение JSSE, реализация Factory)
Eugène Adell 12.09.2018 10:29

@ EugèneAdell, действительно, об этом уже спрашивали. Но один вопрос был задан год назад, а другой возник в 2008 году. За это время может произойти многое.

Alessandro Vermeulen 12.09.2018 11:42

Дело в том, что JSSE был разработан для изоляции приложения от базовой обработки SSL / TLS. Это хорошая идея, поскольку она позволяет подключать все это к различным поставщикам, но этот побочный эффект отсутствия легкого доступа к обратным вызовам приводит к штрафу за сбор статистики (протоколы, наборы шифров, используемые клиентами, причины ошибок). Дизайнеры не хотели знать, почему клиенты не могут вести переговоры с сервером, они считают, что эти клиенты старые / сломанные и неинтересные. Я проверил, что умеет OpenSSL, но не лучше.

Eugène Adell 12.09.2018 13:16

Интересно, что HandshakeCompletedEvent.html действительно существует. Если я сам смогу подключиться к этому, я, по крайней мере, смогу увидеть успешные подключения и, отслеживая идентификаторы сеанса, я могу отслеживать возобновления.

Alessandro Vermeulen 12.09.2018 14:07

Да, это событие вызовет успешный рукопожатия Только. Я использовал это на стороне клиента для моего клиент. На стороне сервера, на мой взгляд, гораздо интереснее выяснять причины сбоев.

Eugène Adell 12.09.2018 14:24
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
5
553
2

Ответы 2

Мой ответ может быть не таким, как вы ожидаете, но это то, что я сделал бы сам.

Во-первых, я никогда не включаю SSL в пользовательском ПО. Ни Java, ни C#, ни Python, ни Javascript. Во всех моих решениях они работают через простой HTTP.

Все материалы TLS я делегирую NGINX. Это надежно. Это быстро. У него множество вариантов. Имеет разносторонний и подробный журнал. Он имеет базовый контроль доступа и защиту от DDoS-атак. Он инкапсулирует детали развертывания и обеспечивает единый фасад для множества предоставляемых услуг.

Накладные расходы небольшие, и он хорошо работает даже на скромном оборудовании.

Вам понадобятся две функции: обратный прокси и подробное ведение журнала.

Самые простые файлы конфигурации выглядят так:

server {
        listen 443 ssl;

        server_name example.com;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;

        location / {
                # Transfer all request to the actual server using HTTP
                proxy_pass http://<server-in-intranet>:12345;
                proxy_set_header Host $host;
        }
        # TLS handshake errors are reported at the info level
        error_log /var/log/nginx/example.com/error.log info;
        # Extra ideas about SSL logging: 
        #   https://docs.nginx.com/nginx/admin-guide/monitoring/logging/#tls_sample

        # The certificates from Let's Encrypt are installed by Certbot
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
}

С этой конфигурацией сервер https://example.com/ обслуживает содержимое вашего фактического сервера, который работает где-то внутри интрасети, через HTTPS, в то время как фактический сервер является простым HTTP.

Используя эту настройку, я запускаю серверы, написанные на Go, Javascript и Python, которые работают на разных машинах, но собраны под одной точкой доступа, например. https://global.name/service1/, https://global.name/service2/, https://global.name/service3/

Это усложняет настройку и добавляет еще один прыжок. Tomcat предоставляет поддержку OpenSSL "из коробки", которая покрывает> 80% всех вариантов использования.

Michael-O 23.10.2020 10:36

Это одинокий сервер или набор серверов, находящихся за балансировщиком нагрузки?

Вы можете подумать о «повторном развертывании» сервера, чтобы у вас был дубликат с той же конфигурацией, но с включенным JAVA OPT debug ssl: handshake.

Теперь в балансировщике нагрузки вы направляете часть трафика на сервер отладки, чтобы выбрать интересующую вас активность.

В качестве альтернативы вы развертываете другой экземпляр tomcat на том же сервере на другом порту, на котором включена отладка. (Это меньше, чем идея, потому что это увеличивает нагрузку на сервер, который, как вы упомянули, может иметь проблемы уже во времена увеличения количества запросов.)

Так что, возможно, у вас нет балансировщика нагрузки, но у вас, вероятно, есть брандмауэр, посмотрите, поддерживает ли ваш брандмауэр состояние и может ли он «разделять трафик» за вас.

Если текущий сервер является Linux-сервером, вы можете использовать iptables для этого в примере «двойной локальной установки», о котором я упоминал выше. примерно так: https://www.webair.com/community/simple-stateful-load-balancer-with-iptables-and-nat/

От комплексного решения не обойтись.

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

Удачи

Дэйвид

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