0x01先查一个问题。测试环境微信支付通道提示网络环境未通过安全验证。请稍后再试。出现这种情况,首先想到的可能是双方网络交互中的微信端。我们在体验参与中遇到了不一致的情况,我们查看了手册确认是这类问题,并开始了调查过程。1、获取真实IP的方式可能有误。getenv('HTTP_CLIENT_IP')getenv('HTTP_X_FORWARDED_FOR')getenv('REMOTE_ADDR')filter_var($remote_ip,FILTER_VALIDATE_IP)依次获取和过滤。solid程序没有问题,发散2.是否反向代理通过反向代理后,由于在客户端和web服务器之间增加了一个中间层,web服务器无法直接获取客户端的ip,并且只能通过$remote_addr变量ip地址获取反向代理服务器的IP,检查没有这个问题,再往上走,网络工程好的同学绝对不认输3.可能NAT分配出口IP,或者负载均衡服务分配异常#localIPifconfig|grep-A1"en"|grepbroadcast|cut-d""-f2#InternetIPcurl--silenthttp://icanhazip.comnetstat-tn|grep80|akw'{print$5}'|awk-F'{print$1}'|grep[本地IP]有这里是个问题,没有我的IP,然后用nginx$remote_addr获取的IP作为参考,这个是nginx上次握手的IP,$remote_addr=10.168.0.0/16print$remote_addratnginx,并在server_name中添加当前机器ip,分别用负载均衡IP和本机IP进行测试。最终确定问题出在负载均衡服务器检查异常,与80端口建立连接时,谁先拿到我的本地内外网IP就方便了。故障排除0x02LNMP堆栈采用真正的IPLNMP堆栈。PHP获取到的所有TCP操作信息都是由前端Nginx通过fastcgi传递给它的,比如$_SERVER['REMOTE_ADDR']是通过includefastcgi.conf;引入的,相当于nginx$remote_addrNginx中的几个变量:$remote_addr代表客户端的IP,但它的值不是客户端提供的,而是服务端根据客户端的ip指定的。icanhazip的原理也是一样的。当你的浏览器访问某个网站时,假设中间没有代理,那么然后网站的web服务器会将remote_addr设置为你暴露在公网的IP。如果你使用了某个代理,你的浏览器会先访问这个代理,然后由代理转发给网站,这样web服务器就会把remote_addr设置为代理机器的IP,除非代理把你的IP附加到$proxy_add_x_forwarded_for$proxy_add_x_forwarded_for变量包含客户端请求头中的“X-Forwarded-For”,和$remote_addr两部分,用逗号分隔。X-Forwarded-For(简称XFF),X-Forwarded-For是一个HTTP扩展头。RFC2616协议没有定义它。最早由缓存代理软件Squid引入,代表HTTP请求端的真实IP。现在已经成为事实上的标准,被各大HTTP代理、负载均衡等转发服务广泛使用,并写入RFC7239(ForwardedHTTPExtension`标准。$proxy_set_header在排错问题中已经说明,代理可以设置header后proxy_set_headerHost$http_host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto$scheme;X-Real-IP一般是X-Real-IP等自定义头域,通常它被HTTP代理用来表示与其产生TCP连接的设备IP,这个设备可能是另一个代理,也可能是真正的请求者,这取决于通过代理的层数或真实IP是否一直向下传递。(切记:客户端上传的任何东西都是不可信任的)当使用多层代理或CDN时,如果代理服务器不传递用户的真实IP,那么服务器无线永远无法获得用户的真实IP。0x03用户的真实IP从哪里来?1、宽带商提供独立IP。比如家里电信宽带上网,电信给它分配了一个公网IP,那么一个请求经过的IP路径是:192.168.0.1(用户)-->192.168。0.1/116.1.2.3(路由器的局域网ip和路由器的电信公网ip)-->119.110.0.0/16(负载均衡服务器)-->10.168.0.0/32(业务处理服务器)本例为119.147。19.234会将获取到的116.1.2.3附加到头信息中,发送到10.168.0.0/32,所以本例中我们获取到的用户ip为:116.1.2.3。如果119.110.0.0/16不在header信息中加上116.1.2.3发送给业务服务器,业务服务器只能拿到上级IP地址2,宽带商无法提供独立IP。宽带提供商没有足够的公网IP。分配的是内网ip,比如长宽都比较小的isp。请求路径可能如下:192.168.0.1(用户)-->192.168.0.1/10.0.1.2(路由器获取的路由器局域网ip和运营商内网ip)-->211.162.78.1(网络公网)运营商长城宽带ip)119.110.0.0/16(负载均衡服务器)->10.168.0.0/32(业务处理服务器)本例中获取到的用户ip为211.162.78.1。这样的话,一个ip对应的用户可能有几十个,上百个。3、手机2G上网网络提供商不能直接给单个用户终端提供ip。以中国移动cmwap上网为例,那么请求路径可能是:手机(手机看不到ip)->10.0.0.172(cmwap代理服务器ip)->10.0.1.2(移动运营商)内网ip)-->202.96.75.1(移动运营商的公网ip)-->119.110.0.0/16(负载均衡服务器)-->10.168.0.0/32(业务处理服务器)本例中获取的用户ip为202.96。75.1。2008年,整个广东联通只有三个手机上网的公网ip,所以在这种情况下,同一个ip出现几十万用户是很正常的。对于几万、几十万员工的企业,同样会有大量的用户来自同一个IP,可能达到数万,但出口IP可能就那么几个。0x04NAT[NetworkAddressTranslation]中文意思是网络地址转换,它允许整个组织以公共IP地址出现在Internet上。顾名思义,它是一种将内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。NAT允许使用私有地址的内部网络连接到Internet或其他IP网络。NAT路由器在将内网的数据包发送到公网时,会在IP包的包头中将私有地址转换为合法的IP地址。RFC1918规定了三个专用地址,作为私有内部网络A类:10.0.0.0—10.255.255.25510.0.0.0/8B类:172.16.0.0—172.31.255.255172.16.0.0/12C类:192.168.0.0—192.168.255.255192.168.0.0/160x05IPV6要来了?写这篇文章的时候看到一个推送说阿里全面应用IPV6。IP地址由4X8=32位二进制数组成,理论上有2^32个IP地址。等于4,294,967,296,超过42亿个IPv4地址。参考《世界互联网用户统计报告》,目前全球约有4,208,571,287人在上网,也就是说几乎是ipv4地址设计的最大IP数。不过不用担心,上面提到的NAT地址交换技术,让IPv4就算用完了,也能凑合。
