Я устраняю проблему с приложением на основе Java, которое извлекает полезную нагрузку JSON (список CVE из NIST) через HTTPS. Когда я подключаюсь напрямую к NIST, я успешно получаю данные. Когда я использую прокси-сервер HTTP, я получаю сообщение об ошибке TLS «неопознанное имя», указывающее на проблему с указанием имени сервера.
У меня нет доступа к коду приложения Java и минимальные возможности возиться с настройками JVM. Следовательно, я проводил отдельные тесты с использованием openssl напрямую, и я могу в некоторой степени воспроизвести проблему с этим.
Когда я выполняю tcpdump для следующего вызова, я вижу, что расширение server_name присутствует в пакете Client Hello:
openssl s_client -connect services.nvd.nist.gov:443
Однако, если я отправлю это через свой прокси-сервер Squid и создам дамп пакетов между прокси-сервером и целевым сервером со следующим, в пакете Client Hello не будет расширения server_name:
openssl s_client -connect services.nvd.nist.gov:443 -proxy myproxy:3128
Ответ от openssl:
140012895368512: ошибка: 14094458: подпрограммы SSL: ssl3_read_bytes: нераспознанное имя tlsv1:../ssl/record/rec_layer_s3.c:1543: номер предупреждения SSL 112
---
нет доступного однорангового сертификата
---
И мы видим, что в пакете нет записи server_name:
Я считаю, что это причина, по которой целевой сервер возвращает ошибку (хотя, насколько я понимаю, в этой ситуации он должен возвращать сертификат по умолчанию).
Теперь я могу сделать эту работу с помощью прокси, вручную указав имя сервера:
openssl s_client -connect services.nvd.nist.gov:443 -proxy myproxy:3128 -servername nvd.nist.gov
Насколько я понимаю, прокси-сервер просто туннелирует данные TLS и не должен их изменять, поэтому он предполагает, что openssl предпочитает не отправлять информацию о расширении имени сервера, когда используется прокси-сервер. С чего бы это?
(Очевидно, что в случае с openssl я могу просто указать параметр имени сервера, но с приложением Java у меня нет такой роскоши. Я надеюсь, что если я смогу понять, почему openssl предпочитает не отправлять данные SNI через прокси-сервер, это может пролить свет на то, почему Java делает то же самое.)