rwi*_*red 8 java firefox proxy socks
我编写了一个应用程序(除其他外)在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代理?
更新:重现此问题的步骤:
它会因一系列类未找到的错误而失败,类似于:
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代理,来自我的本地客户端
两个主机都不可访问(因为防火墙)
如果我登录到远程服务器,我会得到:
几分钟后这两个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.
Run Code Online (Sandbox Code Playgroud)
小智 5
新的InetSocketAddress(主机,端口),默认情况下解析IP,如果解析了目标地址,则SocksSocketImpl首先使用IP。如果需要RemoteDNS,则可以为您的代理服务器新建一个Socket,然后连接到由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);
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
我将 SOCKS 代理指向我的 HTTP 服务器,因此出现此错误是预料之中的。