IIS Web Service 也算是一个主流的HTTP服务软件,有不少MS系的应用在IIS上运行、也有用户使用IIS提供的平台运行他们.Net Framework开发的应用程序。当然,为了网站安全,不少用户选择在IIS server前放一层WAF避免攻击。而这次,我们的一个用户遇到了一个有意思的问题,
问题现象
IIS Web service,上面运行了许多网站应用程序,以SNI区分。在IIS服务器之前放置一层WAF回源。用户反馈,有个IIS Web site通过WAF回源不成功。
现象主要是 在访问网站的时候,浏览器一直在加载,返回502/504等错误码,同时伴有499错误。
排查过程
由于IIS Web service对于我们来说基本上是一个黑盒,且在问题发生的时候基本没有任何错误日志和访问日志,我们基本上采用大胆猜测小心求证的方案来一步步定位问题。作为一整套系统,问题无非出在这几个方面,
网络问题
所有涉及到的IP及其对应端口我们都测试了联通性,telnet/tcpping等都显示连接三次握手正常。
IIS服务器本身问题
通过对IIS 服务器直接访问,我们基本排除服务器处理问题。(以下是我们测试主机的访问记录)
curl -v https://hello.test.domain:8443/ -o /dev/null -s --trace-time --resolve hello.test.domain:8443:ip.add.rss.227
WAF网站配置问题
从其它相同配置的网站来看,WAF的配置并没有什么特别之处,即便跟其它正常网站的配置完全一致,问题依旧存在。排查WAF的日志,基本把问题又指回了IIS 服务器,因为日志明确的记录了120s超时的情况,
抓包分析
矛盾点出现在WAF和IIS 服务器之间,因此我们通过抓包来分析这两个服务之间的交互情况。可惜,我们第一次抓包的结果无法解密,也就无法完全获知WAF和IIS 服务器的交互内容。为此,我们做了几个尝试,
- Windows上导出Certificate和Private Key为PFX,并设置密码。配置在Wireshark的RSA Key中。
- Windows IIS 服务器上 禁用Diffie-Hellman加密算法,并重启。
- 客户端上配置SSLKEYLOGFILE="C:\temp\sslkey.log",并在客户端的Wireshark中指定。
具体方法网上都有,不一一列举。最终,我们抓到了正常和异常的HTTPS数据流,通过解密后的数据包如下,
正常:客户端直接连接IIS
异常:客户端通过WAF连接IIS
很容易看到问题在于服务器在一个SSL tunnel中给WAF 发送 HELLO REQUEST,但WAF没有任何回复导致IIS 一直等待在 RE-NEGOTIATE阶段。而正常的情况下,客户端能够正确的处理这个请求,发送CLIENT HELLO。
Review TLS的RFC规范后,我们发现RFC中并未对客户端接收到 HELLO REQUEST 的行为做明确的规定,
https://tools.ietf.org/html/rfc5246
在Windows Server 2008 R2的IIS实现中,IIS一直等待响应也未必是一个合适的行为。
解决方案
了解了问题发生的原因,HELLO REQUEST并不一定是必须的,具体我们通过IIS的帮助文档,定位相应的配置Ignore避免了IIS发送HELLO REQUEST,