级别: 中级 Uche Ogbuji (uche.ogbuji@fourthought.com), 首席顾问, Fourthought, Inc.
2004 年 4 月 01 日 如果试图从防火墙后面访问 SOAP 服务,而您的 SOAP 库不支持代理网络连接,直接请求就不能通过防火墙。在这种情况下,可以使用套接字重定向程序使连接通过代理服务器。Uche Ogbuji 在本文中介绍了这种技巧。
安全性已成为企业无法回避的问题,多数计算机用户都采用了某种防火墙,尤其是在工作场所。这样做不会对普通的 Internet 访问造成很大障碍,比如
Web 浏览与电子邮件,因为多数相应的用户代理都支持一种特殊的服务器,这种服务器允许从一台计算机到另一台计算机的通信不必建立直接的连接。这种服务器被称为
代理服务器,
Internet 代理服务器最常用的协议称为
SOCKS。SOCKS
代理一般用于使防火墙后面的用户能够以有限的、受控的方式连接到 Internet 服务器。代理服务器通常强制实施安全策略,比如禁止访问某些 Web
站点,或者在连接之前要求用户验证。多数 SOCKS 实现都支持最新的 SOCKS 5 标准。
SOAP 和防火墙
如果试图穿过防火墙使用 SOAP,可能需要使用 SOCKS 代理。这意味着必须保证程序能够理解 SOCKS 协议。设置程序使其能够使用 SOCKS 协议的过程称为程序的
SOCKS 化。使 Web 服务设置 SOCKS 化有几种不同的方式:
- 使整个计算机的网络设施都通过 SOCKS 服务器。有一些程序(据我所知只有商业化的产品)能够使所有的网络通信都透明地通过 SOCKS 代理传输。
- 使用能够重定向所选网络通信使其通过 SOCKS 服务器的专门程序,后面我将举一个例子。
- 一些运行时环境支持重定向在其中运行的应用程序的网络连接,使其通过 SOCKS 代理。比如,最新版本的多数 Java 运行时都允许使用
socksProxyHost 和
socksProxyPort 这样的属性指定代理。这样可以对所有使用套接字的对象都使用代理。
- 使用支持 SOCKS 协议的 Web 服务工具包,比如 IBM Emerging Technologies Toolkit。
一个简单的例子
本例中将在防火墙后使用 SOAPpy Web 服务工具包 0.11.3 版。SOAPpy 是一个方便的 Python 工具包,过去我曾经在
developerWorks上介绍过(请参阅
参考资料),但是它没有内建的 SOCKS 支持,因此是稍微复杂一点的一个很好的例子。
我从防火墙背后尝试 SOAPpy 自带的
weatherTest.py 示例脚本。其中最重要的一行是:
SoapEndpointURL = 'http://services.xmethods.net:80/soap/servlet/rpcrouter'
|
这样就把客户设置成从服务器 services.xmethods.net 的端口 80 请求一个 SOAP 端点。第一次运行的结果得到下面的错误:
socket.gaierror: (-2, 'Name or service not known')
|
这种错误首先预示着此类防火墙问题。许多系统中,域名服务器只能在防火墙内解析地址,实际上必须使用代理服务器解析外部域名并建立后续连接。SOCKS
化客户的许多方法支持这种通过代理查询 DNS 的重定向,但是为了简化起见,我仅仅修改了 SOAP 端点请求,以便使用真正的 IP 地址而不是通常的
DNS 查找。修改后的一行如下:
SoapEndpointURL = 'http://66.28.98.121:80/soap/servlet/rpcrouter'
|
结果得到如下所示的错误:
socket.error: (111, 'Connection refused')
|
这就是对话错误。防火墙阻塞了直接连接到 66.28.98.121 服务器端口 80 的请求。我必须让请求通过 SOCKS 代理。为此,我下载了一个知名的套接字重定向工具 connect.c(请参阅
参考资料)。下载后构建了该程序(本例是在 Linux 上):
gcc connect.c -o proxyconnect
|
得到的
proxyconnect 命令可以重定向端口,监听本地端口并将其通过代理重定向到远程服务器。我希望它监听本地端口 8888,并重定向到 66.28.98.121 上的端口 80。在我的环境中 SOCKS 服务器的地址是 192.168.1.254,它从端口 8080 上接收 SOCKS 连接。这种情况下,正确的
proxyconnect 命令行设置如下:
proxyconnect -p 8888 -S 192.168.1.254:1080 66.28.98.121 80
|
如果在单独的会话中或者后台运行这个命令,那么就可以通过将其指向本地重定向的套接字来进一步使用 SOAP 端点。换句话说,代码中关键的一行就变为:
SoapEndpointURL = 'http://localhost:8888/soap/servlet/rpcrouter'
|
这一次,SOAP 请求运行得很好。
结束语
这个例子稍微有点笨拙,其中之一就是需要为希望使用的每个远程端点都设置重定向的套接字。我希望通过一个例子说明更糟的一些情况——通常选择的 Web 服务 SOCKS 化方法会更简单一些。如果 SOCKS 代理设置了拒绝 SOAP 的策略——最近的一些产品就是如此——这可能彻底击碎您对 SOAP 的雄心。如果这样,您就没有别的选择,只能与您的 IT 部门一道为许可 Web 服务访问设置专门的代理。和往常一样,很难在安全与方面之间求得平衡。
参考资料
关于作者
对本文的评价
|