java运行时6与socks v5代理 – 可能吗?

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

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

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

在JRE6设置( 此处记录 )中没有相应的设置,因为远程DNS解析是SOCKS v5的一个function而不是v4,因为文档似乎意味着我担心它是不可能的。

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


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

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

    load:未找到类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 applet的页面,它已经失败了,我已经报告了堆栈跟踪消息。

但是,如果我编辑Windows \ System32 \ drivers \ etc \ hosts,为upload.facebook.com添加正确的IP我可以让applet加载并正常工作(有时需要重启FF)。

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

我的应用程序用于大规模部署,需要在其他站点(而不仅仅是facebook)上使用java applet。 我真的需要解决这个问题。


更新3由ZZ Coder请求的Stacktrace转储:

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. 

新的InetSocketAddress(hosta,port)通过默认解析IP,如果目标地址被解析,SocksSocketImpl首先使用IP。 如果你想要RemoteDNS,你可以新建Socket you An Proxy,然后连接到由InetSocketAddress.createUnresolved(主机,端口)构建的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); 

JRE肯定支持Socks V5。 自Java 1.4以来我一直在使用它。 如果您的SOCKS服务器是V4,则JRE仅使用V4。 服务器响应的第一个字节必须为5。

V4的支持是错误的。 它只适用于IP地址,而不是域名,因为它不知道如何解决域名。 因此,如果Socks工作,你必须使用V5。

我怀疑你的代理设置不正确所以袜子根本不起作用。 这应该很容易跟踪Wireshark。 只需检查applet使用的端口。

堆栈跟踪也非常有用。 如果使用袜子,它会告诉你。 例如,

 load: class test.MyApplet.class not found. java.lang.ClassNotFoundException: .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服务器,因此预计会出现此错误。