我编写了一个应用程序,它(除其他外)在 Windows 中运行本地服务,充当 Firefox 的 SOCKS v5 代理。
我现在处于调试阶段,发现某些网站无法正常工作。例如,Facebook.com 上用于图片上传的 Java 小程序失败,因为无法查找域。
我的应用程序覆盖了隐藏的 FF 配置设置network.proxy.socks__remote__dns将其设置为true。该应用程序的全部目的是允许在防火墙后访问网站(例如,如果用户在中国),因此此设置对于确保域也被远程解析(而不仅仅是 HTTP 请求)至关重要。
在 JRE6 设置(在此处记录)中没有等效设置,并且由于远程 DNS 解析是 SOCKS v5 而不是 v4 的功能,因为文档似乎暗示我担心这是不可能的。
如何以编程方式确保 JRE 对所有请求(包括 DNS)使用 SOCKS v5 代理?
更新:重现此问题的步骤:
- 确保您位于阻止(或重定向)互联网访问(包括 DNS )的防火墙后面
- 安装 PuTTY 并在您选择的某个端口号(例如 9870)上添加动态 SSH 隧道。然后登录到可以完全访问互联网的远程服务器
- 启动 Firefox,您将无法浏览网页
- 在 FF 网络设置中,将 SOCKS v5 代理设置为 localhost:9870
- 在 FF 中转到 about:config,将network.proxy.socks__remote__dns更改为 true
- 您现在可以浏览网页了。
- 转到 facebook.com,登录,转到您的个人资料并尝试使用图片上传器 java 小程序添加一些图片
它将失败,并出现一系列类似于以下的类未找到错误:
加载:类 com.facebook.facebookphotouploader5.FacebookPhotoUploader5.class not found。
我相信这是失败的,因为 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
- 上传.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 Stacktrace 转储 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.