带socks v5代理的java运行时6 - 可能吗?

发布于 2024-08-04 10:54:41 字数 4466 浏览 5 评论 0原文

我编写了一个应用程序(除其他外)在 Windows 中运行本地服务,充当 Firefox 的 SOCKS v5 代理。

我现在正处于调试阶段,发现某些网站无法正常工作。例如,用于 Facebook.com 上图片上传的 Java Applet 失败,因为它无法查找域。

我的应用程序覆盖隐藏的 FF 配置设置 network.proxy.socks__remote__dns 将其设置为 true。该应用程序的全部目的是允许在防火墙后面访问网站(例如,如果用户位于中国),因此此设置对于确保远程解析域(而不仅仅是 HTTP 请求)至关重要。

在 JRE6 设置中(记录在此处)没有等效的设置,并且由于远程 DNS 解析是 SOCKS v5 而不是 v4 的一项功能,因为文档似乎暗示我担心这是不可能的。

如何以编程方式确保 JRE 对所有请求(包括 DNS)使用 SOCKS v5 代理?


更新: 重现此问题的步骤:

  1. 确保您位于阻止(或重定向)互联网访问包括 DNS 的防火墙后面。
  2. 安装 PuTTY 并在您选择的某个端口号(例如 9870)上添加动态 SSH 隧道。然后登录到具有完全访问互联网权限的远程服务器
  3. 启动 Firefox,您将无法浏览网页
  4. 在 FF 网络设置中将 SOCKS v5 代理设置为 localhost:9870
  5. 在 FF 中转到 about :config,将 network.proxy.socks__remote__dns 更改为 true
  6. 您现在就可以浏览网页了。
  7. 转到 facebook.com,登录,转到您的个人资料并尝试使用图片上传器 Java 小程序添加一些图片
  8. 它将失败,并出现一系列类似于以下内容的类未找到错误:

    加载:找不到类 com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class

我认为这是失败的,因为 JRE 无法解析该类所在的域。我的这种信念基于以下事实:文档 (http://java.sun.com/javase/6/docs/technotes/guides/deployment/deployment-guide/properties.html)仅讨论 SOCKS v4(据我所知不支持远程DNS)。我的deployment.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,为 upload.facebook.com 添加正确的 IP,我可以让小程序加载并正常工作(重新启动FF有时是必要的)。

这个证据似乎支持我的理论,即 Java 运行时解析代理上的 DNS,而只是通过它路由流量。

我的应用程序用于大规模部署,并且需要与其他站点(不仅仅是 facebook)上的 java 小程序一起使用。我确实需要解决这个问题。


更新3 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.

I have written an application that (amongst other things) runs a local service in windows that acts as a SOCKS v5 proxy for Firefox.

I'm in the debugging phase right now and have found certain websites that don't work correctly. For example the Java Applet for Picture Uploading on Facebook.com fails because is is unable to lookup domains.

My app overrides a hidden FF config setting network.proxy.socks__remote__dns setting it to true. The whole purpose of the app is to allow access to websites when behind a firewall (e.g. if the user is in China), so this setting is essential to ensure domains are resolved remotely also (and not just HTTP requests).

In the JRE6 settings (documented here) there isn't an equivalent setting, and since remote DNS resolution is a feature of SOCKS v5 and not v4 as the documentation seems to imply I'm worried that it's just not possible.

How can I programmatically make sure the JRE uses a SOCKS v5 proxy for all requests (including DNS)?


UPDATE:
Steps to reproduce this problem:

  1. Make sure you are behind a firewall that blocks (or redirects) internet access including DNS
  2. Install PuTTY and add a dynamic SSH tunnel on some port number of your choice (e.g. 9870). Then login to a remote server that has full access to the internet
  3. Launch Firefox and you will not be able to browse the web
  4. In FF network settings set the SOCKS v5 proxy to localhost:9870
  5. In FF go to about:config, change network.proxy.socks__remote__dns to true
  6. You will now be able to browse the web.
  7. Go to facebook.com, login, go to your profile and attempt to use the picture uploader java applet to add some pictures
  8. It will fail with a series of class not found errors looking similar to:

    load: class com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class not found.

I believe this is failing because the JRE is unable to resolve the domain that the class resides on. I'm basing this belief on the fact that the documentation (http://java.sun.com/javase/6/docs/technotes/guides/deployment/deployment-guide/properties.html) talks only about SOCKS v4 (which as far as I know does not support remote DNS). My deployment.properties file is located in %APPDATA%\Sun\Java\Deployment. I can confirm that modifications I make in the Java Control Panel get written into that file. If instead of "Use browser setting" the network settings for Java I override and attempt to use the SOCKS proxy settings manually, I still have the issue. There does not seem to be an easy way to force the JRE to do DNS remotely through the Proxy.


UPDATE 2:

Without the SOCKS proxy, from my local client

  • www.facebook.com resolves to 203.161.230.171
  • upload.facebook.com resolves to 64.33.88.161

Neither host is reachable (because of the firewall)

If I login to the remote server, I get:

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

Both these IPs change after a few minutes, as it seems Facebook uses round-robin DNS and other load-balancing.

With the Proxy settings set in Firefox, I can navigate to www.facebook.com without any difficulty (since DNS is being resolved remotely on the Proxy). Whey I go to the page with the Java applet it fails with the stacktrace messages I've already reported.

However if I edit Windows\System32\drivers\etc\hosts, adding the correct IP for upload.facebook.com I can get the applet to load and work correctly (restart of FF is sometimes necessary).

This evidence seems to support my theory that the Java Runtime is not resolving DNS on the Proxy, but instead just routing traffic though it.

My application is for mass-deployment, and needs to work with java applets on other sites (not just facebook). I really need a work-around for this problem.


UPDATE 3
Stacktrace dump a requested by 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗琴音 2024-08-11 10:54:41

new InetSocketAddress(hosta, port) 默认解析 IP,如果解析目标地址,SocksSocketImpl 首先使用 IP。
如果你想要RemoteDNS,你可以为你的代理新建一个Socket,然后连接到一个由InetSocketAddress.createUnresolved(host, port)构造的InetSocketAddress。

你的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);

new InetSocketAddress(hosta, port) which resolve IP by Default, and SocksSocketImpl use IP first if the target address is resolved.
If you want RemoteDNS, you can new Socket you An Proxy,then connnect to a InetSocketAddress which is constructed by InetSocketAddress.createUnresolved(host, port).

You Socks Server must be SOCKS5, java SocksSocketImpl auto detect is version.

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);
青瓷清茶倾城歌 2024-08-11 10:54:41

JRE 当然支持 Socks V5。我从 Java 1.4 就开始使用它了。如果您的 SOCKS 服务器是 V4,JRE 仅使用 V4。服务器响应的第一个字节必须是 5。V4

支持有问题。它仅适用于 IP 地址,不适用于域名,因为它事先不知道如何解析域名。所以如果 Socks 能工作的话你必须使用 V5。

我怀疑您的代理设置不正确,因此袜子根本不起作用。使用 Wireshark 应该很容易追踪这一点。只需检查小程序正在使用哪个端口即可。

堆栈跟踪也会非常有帮助。它会显示是否使用了 Socks。例如,

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 服务器,因此出现此错误是预料之中的。

JRE certainly supports Socks V5. I have been using it since Java 1.4. JRE only uses V4 if your SOCKS server is V4. The first byte from your server response must be 5.

The V4 support was buggy. It only works with IP address, not domain name because it doesn't know how to resolve the domain name before hand. So you must be use V5 if Socks works at all.

I suspect that your proxy setting is incorrect so socks doesn't work at all. This should be easy to trace with Wireshark. Just check which port the applet is using.

Also the stacktrace will be very helpful. It will show you if Socks is used. For example,

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)

I pointed SOCKS proxy to my HTTP server so this error is expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文