网络安全检测|网络安全服务|网络安全扫描-香港墨客投资移动版

主页 > 业界资讯 > 网络安全预防措施

因微信支付API对IPv6支持不完整引起的一次故障(3)

我们会注意到api.mch.weixin.qq.com status的值 NOERROR ,如果一个返回为 NOERROR 且 没有 ANSWER SECTION,按照(https://tools.ietf.org/html/rfc2308#section-2.2)这是一个 NO DATA 返回,表明这是一个指示返回(例如根权威返回顶级权威的 NS)或者是域名记录不存在(例如查询 163.com AAAA)。

从上文可以看到 forward.qq.com. 实际上是做了一层 NS,虽然没有真正的授权出去(ns-os1.qq.com. 上没有 forward.qq.com SOA 记录),但缓存看来,它已经授权了一层,而返回的 SOA 有误,因此缓存服务器无法判定该 NODATA 返回的类型,所以认为该返回不合法,最终导致了api.mch.weixin.qq.com和forward.qq.com 的AAAA记录一直返回 SERVFAIL,所以缓存服务器会尝试继续解析,从而导致首次解析时间过长。等到之后解析成功后,就使用的本地缓存,所以解析很快,等到缓存失效后,问题就会重现。

2、关于curl的DNS解析顺序

一般来说,如果服务器开启了IPv6,curl默认会优先解析 IPv6,在对应域名没有 IPv6 的情况下,会等待 IPv6 DNS解析失败 timeout 之后才按以前的正常流程去找 IPv4。DNS服务都是支持解析IPv6的,如果没有设置IPv6解析,查询结果就是空,不会是serverfail。

3、关于nslookup和dig的工作原理

不同操作系统nslookup和dig的原理并不同,比如Win7的nslookup每发一次IPv4请求就会产生2个A记录请求,换到Win XP下nslookup没发一次IPv4请求则只会产生一个A记录请求,所以在抓包分析时需要根据不同操作系统的应用特性进行区分。

微信原来已有解决方案

针对这个问题,其实微信官方文档

已经给出了答案。

商户访问微信支付

商户侧使用api.mch.weixin.qq.com(主)和api2.mch.weixin.qq.com(备)这两个支付api域名访问微信支付,这两个域名功能完全一样。

这两个域名分别配hosts绑定专线访问微信的两个131开头的策略IP,具体电信IP和联通IP那个绑定到api和api2, 商户侧可以测速后自己决定。

商户侧的访问支付接口的代码逻辑需具备失败换域名重试的机制,即访问api.mch.weixin.qq.com不通的话,就换成api2.mch.weixin.qq.com重试。

商户侧访问微信支付时,若两条专线都不通,要有能切回走公网访问的能力。若无法走公网,则商户侧需要知晓这里的风险。

可行的解决办法

关闭服务器IPv6功能

1、使用ifconfig验证是否开启IPv6:

eth0 Link encap:Ethernet HWaddr 00:13:D4:05:B2:ED

inet addr:119.119.xxx.xx Bcast:119.119.115.255 Mask:255.255.255.0 #ipv4

inet6 addr: fe80::213:d4ff:fe05:b2ed/64 Scope:Link #IPv6

 

2、查看服务监听的IP验证是否开启IPv6:

netstat -nulp

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN #ipv4

tcp 0 0 :::8080 :::* LISTEN #IPv6

 

3、使用lsmod验证是否开启IPv6:

[root@linux ~]# lsmod |grep ip

ip6t_REJECT 9409 1

ip6table_filter 6849 1

ip6_tables 18053 1 ip6table_filter

 

关闭IPv6:修改/etc/modprobe.conf加入如下的两条,重启系统即可。

alias net-pf-10 off

alias IPv6 off

开启IPv6:IPv6是默认支持的,所以只需将/etc/modprobe.conf中的上面两条指令注释掉即可。

在/etc/hosts文件中指定域名ip解析记录

按照下面格式配置,但是如果指定的服务器故障了,业务也会受牵连,这不是很稳妥的方法。

api.mch.weixin.qq.com 183.3.235.18

在代码中指定域名解析使用ipv4结果

比如PHP:

if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4'))

{

curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

}

 

使用微信官方方案,设置主备域名进行冗余,支持域名解析失败切换。

经验教训

熟读用户文档

(责任编辑:admin)