Java Runtime 6 с Socks v5 прокси - Возможно?

Я написал приложение, которое (помимо прочего) запускает локальную службу в Windows, которая действует как прокси SOCKS v5 для Firefox.

Сейчас я нахожусь в фазе отладки и нашел некоторые сайты, которые работают неправильно. Например, Java-апплет для загрузки изображений на Facebook.com не работает, потому что не может искать домены.

Мое приложение переопределяет скрытую конфигурацию FF, в которой для параметра network.proxy.socks__remote__dns задано значение true. Цель приложения - разрешить доступ к веб-сайтам за брандмауэром (например, если пользователь находится в Китае), поэтому этот параметр необходим для обеспечения удаленного разрешения доменов (а не только запросов HTTP).

В настройках JRE6 (задокументированных здесь) нет эквивалентной настройки, и, поскольку удаленное разрешение DNS является функцией SOCKS v5, а не v4, поскольку документация подразумевает, что я обеспокоен тем, что это просто невозможно.

Как программно убедиться, что JRE использует прокси-сервер SOCKS v5 для всех запросов (включая DNS)?


ОБНОВЛЕНИЕ: шаги, чтобы воспроизвести эту проблему:

  1. Убедитесь, что вы находитесь за брандмауэром, который блокирует (или перенаправляет) доступ в Интернет, включая DNS
  2. Установите PuTTY и добавьте динамический туннель SSH на некоторый номер порта по вашему выбору (например, 9870). Затем войдите на удаленный сервер, который имеет полный доступ к Интернету
  3. Запустите Firefox, и вы не сможете просматривать веб-страницы.
  4. В настройках сети FF установите прокси SOCKS v5 на localhost:9870
  5. В FF перейдите к:config, измените network.proxy.socks__remote__dns на true
  6. Теперь вы сможете просматривать веб-страницы.
  7. Зайдите на facebook.com, войдите, зайдите в свой профиль и попробуйте использовать Java-апплет загрузки изображений, чтобы добавить несколько картинок.
  8. Он потерпит неудачу с рядом ошибок класса not found, похожих на:

    загрузка: класс com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class не найден.

Я полагаю, что это не удается, поскольку JRE не может разрешить домен, в котором находится класс. Я основываю это убеждение на том факте, что документация ( http://java.sun.com/javase/6/docs/technotes/guides/deployment/deployment-guide/properties.html) говорит только о SOCKS v4 (который насколько я знаю не поддерживает удаленный DNS). Мой файл deploy.properties находится в%APPDATA%\Sun\Java\Deployment. Я могу подтвердить, что изменения, которые я делаю в Панели управления Java, записываются в этот файл. Если вместо "Использовать настройки браузера" настройки сети для Java я перезаписываю и пытаюсь использовать настройки прокси-сервера SOCKS вручную, у меня все еще остается проблема. Кажется, не существует простого способа заставить JRE выполнять DNS удаленно через Прокси.


ОБНОВЛЕНИЕ 2:

Без SOCKS прокси от моего локального клиента

  • www.facebook.com разрешает до 203.161.230.171
  • upload.facebook.com разрешает до 64.33.88.161

Ни один хост не доступен (из-за брандмауэра)

Если я войду на удаленный сервер, я получу:

  • www.facebook.com 69.63.187.17
  • upload.facebook.com 69.63.178.32

Оба этих IP-адреса меняются через несколько минут, так как кажется, что Facebook использует циклический DNS и другую балансировку нагрузки.

С настройками прокси-сервера, установленными в Firefox, я могу без проблем перейти на www.facebook.com (поскольку DNS разрешается удаленно на прокси-сервере). Когда я захожу на страницу с Java-апплетом, она выходит из строя с сообщениями о трассировке стека, о которых я уже сообщил.

Однако, если я отредактирую Windows\System32\drivers\etc\hosts, добавив правильный IP-адрес для upload.facebook.com, я смогу заставить апплет загружаться и работать правильно (иногда требуется перезапуск FF).

Это доказательство, кажется, подтверждает мою теорию, что Java Runtime не разрешает DNS на Прокси, а просто маршрутизирует трафик через него.

Мое приложение предназначено для массового развертывания и должно работать с Java-апплетами на других сайтах (не только на Facebook). Мне действительно нужно обойти эту проблему.


ОБНОВЛЕНИЕ 3 Stacktrace dump запрашивается ZZ Coder:

load: class com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class not found.
java.lang.ClassNotFoundException: com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
    at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.fill(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    ... 7 more
Exception: java.lang.ClassNotFoundException: com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class

Dumping class loader cache...
 Live entry: key=http://upload.facebook.com/controls/2008.10.10_v5.5.8/,FacebookPhotoUploader5.jar,FacebookPhotoUploader5.jar, refCount=1, threadGroup=sun.plugin2.applet.Applet2ThreadGroup[name=http://upload.facebook.com/controls/2008.10.10_v5.5.8/-threadGroup,maxpri=4]
Done.

2 ответа

Новый InetSocketAddress(хоста, порт), который разрешает IP по умолчанию, и SocksSocketImpl сначала используют IP, если целевой адрес разрешен. Если вы хотите RemoteDNS, вы можете создать Socket you An Proxy, а затем подключиться к InetSocketAddress, который создается InetSocketAddress.createUnresolved(host, port).

Ваш Socks Server должен быть SOCKS5, java SocksSocketImpl автоматически определяет версию.

Proxy p = new Proxy(Proxy.Type.SOCKS, paddr);
Socket s = new Socket(p);
InetSocketAddress addr = InetSocketAddress.createUnresolved("host.blocked.by.gfw", port);
s.connect(addr);

JRE наверняка поддерживает Socks V5. Я использую его с Java 1.4. JRE использует только V4, если ваш SOCKS сервер V4. Первый байт ответа вашего сервера должен быть 5.

Поддержка V4 была глючной. Он работает только с IP-адресом, а не с именем домена, потому что не знает, как разрешить имя домена заранее. Так что вы должны использовать V5, если Socks работает вообще.

Я подозреваю, что ваш прокси-сервер неверен, поэтому socks не работает вообще. Это должно быть легко проследить с помощью Wireshark. Просто проверьте, какой порт использует апплет.

Также трассировка стека будет очень полезна. Он покажет вам, если используются носки. Например,

load: class test.MyApplet.class not found.
java.lang.ClassNotFoundException: <name>.class
at sun.applet.AppletClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.applet.AppletClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.applet.AppletClassLoader.loadCode(Unknown Source)
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.plugin.AppletViewer.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Caused by: java.net.SocketException: Malformed reply from SOCKS server
at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)

Я указал SOCKS прокси на мой HTTP-сервер, поэтому ожидается эта ошибка.

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