Прокси-сервер socks для Java использует локальный DNS

Я пытаюсь подключиться к базе данных оракула через прокси-сервер SOCKS, потому что у меня нет прямого доступа к серверу оракула. Итак, я открываю свой прокси на порту 4000 и добавляю следующие параметры в свое приложение:

-DsocksProxyHost=localhost -DsocksProxyPort=4000

Теперь, если я запускаю свое приложение, используя имя хоста сервера оракула в строке подключения, я получаю «Указанный неизвестный хост». Если я использую IP-адрес вместо имени хоста, соединение будет успешным. Я предполагаю, что java пытается разрешить имя хоста, используя мой локальный DNS вместо удаленного. Как я могу использовать удаленный DNS?


person jaudo    schedule 05.06.2017    source источник
comment
какая версия SOCKS используется? SOCKS4 требовал, чтобы клиент разрешал имя хоста. SOCKS 4a предоставляет способ отправки имени на сервер для разрешения IP-адреса, а SOCKS5 также позволяет серверу разрешать имя (независимо от того, делает ли это это, определяется клиентом).   -  person Adrien    schedule 06.06.2017
comment
Я использую v5 (значение по умолчанию для socksProxyVersion). Вы говорите, что SOCKS5 позволяет серверу разрешать имя. Проблема в том, что в настоящее время мой клиент пытается разрешить имя, поэтому я получаю исключение.   -  person jaudo    schedule 06.06.2017
comment
Какой это клиент? Одна из структурных проблем с SOCKS (например, если он находится в библиотеке, подключенной к клиенту) заключается в том, что обычно клиенты разрешают DNS до установления соединения, тогда как в SOCKS разрешение и соединение выполняются вместе в одном запросе. Различные клиенты auto-SOCKS обходят это, перехватывая запросы DNS и возвращая поддельные адреса (которые они используют для идентификации исходного имени получателя, когда видят запрос на подключение в SOCKS).   -  person Adrien    schedule 07.06.2017
comment
Клиент представляет собой Java7 RE (соединение JDBC).   -  person jaudo    schedule 07.06.2017
comment
Что-то просит Java установить соединение.   -  person Adrien    schedule 08.06.2017


Ответы (2)


В текущей реализации OpenJDK для этого можно использовать неподдерживаемый обходной путь. Он может быть удален в будущих версиях. Реализация SOCKS поддерживает удаленный поиск DNS. Однако это работает только для неразрешенных объектов InetSocketAddress. К сожалению, класс NetworkClient, используемый URL.openConnection, всегда пытается разрешить InetSocketAddress, даже если используется SOCKS. Вы можете использовать трюк, чтобы предотвратить локальное разрешение имен.

Задайте для (внутреннего) системного свойства jdk.net.hosts.file имя файла с помощью параметра командной строки -Djdk.net.hosts.file=some_file или задав свойство из кода достаточно рано (первое действие в main) . Это необходимо сделать до выполнения внутреннего инициализатора класса NameService, иначе это не сработает:

System.setProperty(jdk.net.hosts.file, some_file);

В текущих средах выполнения Java на основе OpenJDK это изменит разрешение доменного имени на этот файл вместо обычного DNS. Отсутствие записи или несуществующий файл хоста приводит к неразрешенному InetSocketAddress. Это именно то, что нам здесь нужно, потому что реализация SOCKS теперь будет использовать удаленный DNS.

Однако учтите, что разрешение вашего прокси-сервера больше не будет работать, поэтому вместо этого вам придется указать IP-адрес прокси-сервера. Вы также можете добавить прокси-сервер в файл some_file. Другие разрешения DNS, которые могут вам понадобиться в вашем приложении, также не будут работать.

person josh    schedule 11.07.2020
comment
Я не думаю, что это работает (больше): Unable to resolve host <redacted> in hosts file foo вместо -Djdk.net.hosts.file=foo. - person Sander Verhagen; 04.04.2021

Это ошибка jvm, и кажется, что нет никакого немедленного плана починить это.

SOCKS действительно старый. Не получил широкого распространения в современной инфраструктуре. Понижение приоритета до P4.

person chao_chang    schedule 11.12.2017
comment
Вы имеете в виду, что нет плана исправить это - person jaudo; 11.12.2017
comment
@jaudo спасибо за напоминание, да, вы правы, нет пропустили, и я обновил свой ответ. - person chao_chang; 11.12.2017