我编写了一个应用程序(除其他外)在Windows中运行本地服务,充当Firefox的SOCKS v5代理。
我现在正处于调试阶段,发现某些网站无法正常运行。例如,Facebook.com上的图片上传Java Applet失败,因为无法查找域。
我的应用会覆盖隐藏的FF配置设置 network.proxy.socks__remote__dns 将其设置为 true 。该应用程序的整个目的是允许在防火墙后面访问网站(例如,如果用户在中国),因此此设置对于确保远程解析域(而不仅仅是HTTP请求)至关重要。
在JRE6设置中(记录here)没有相应的设置,因为远程DNS解析是SOCKS v5的一个功能而不是v4,因为文档似乎意味着我担心它只是不可能。
如何以编程方式确保JRE对所有请求(包括DNS)使用SOCKS v5代理?
更新: 重现此问题的步骤:
它将失败,发现一系列未找到类错误,类似于:
load:class 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代理,来自我的本地客户端
两个主机都不可访问(因为防火墙)
如果我登录远程服务器,我会:
这些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 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.
答案 0 :(得分:4)
新的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);
答案 1 :(得分:1)
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: <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服务器,因此预计会出现此错误。