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

Posted

技术标签:

【中文标题】带有 socks v5 代理的 java 运行时 6 - 可能吗?【英文标题】:java runtime 6 with socks v5 proxy - Possible? 【发布时间】:2009-09-16 09:49:45 【问题描述】:

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

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

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

在 JRE6 设置(记录在 here)中没有等效设置,并且由于远程 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

我认为这是失败的,因为 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.

【问题讨论】:

我也遇到过这个问题,Java不能远程解析DNS。你有没有得到这个工作? 不,一直不知道如何解决。放弃了那个项目。 很抱歉您没有找到解决方案,但您帮了我很大的忙!这整个“java 无法远程解析 DNS”是一个狡猾的霍比特人。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

V4 支持有问题。它仅适用于 IP 地址,不适用于域名,因为它事先不知道如何解析域名。因此,如果 Socks 可以正常工作,您必须使用 V5。

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

stacktrace 也会很有帮助。它会告诉你是否使用了袜子。例如,

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 服务器,所以这个错误是意料之中的。

【讨论】:

我根据您的建议进行了检查。从代理获取 5 作为第一个字节。它肯定是通过代理。我的堆栈跟踪仍然显示 ClassNotFoundException。 如果你发布你的整个堆栈跟踪有原因,我可能会得到一个线索 这是我导航到 www.facebook.com 后的堆栈跟踪,选择 profile-photos-album-add more-photos,在小程序失败并显示“错误:单击以获取详细信息”后底部我也转储了类加载器列表。 在主要帖子中(超过 600 chrs) 看起来您的 SOCKS 服务器有问题,它断开了连接。我不知道为什么。根据跟踪,您在加载过程中走了很长一段路,通过了 DNS、TCP 连接。尝试解析 HTTP 标头时发生异常。

以上是关于带有 socks v5 代理的 java 运行时 6 - 可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

带有 Socks4 代理的 Java Socket 更改为 Socks5

带有 Python 的 SOCKS 代理

带有 Socks 代理的 JMeter?

使用带有 git 的 socks 代理进行 http 传输

java.net.UnknownHostException:主机是未解析的 SOCKS 代理

带有 socks 代理的 SSH