背景
最近公司有个论坛因为发展到一个阶段,且因为历史架构原因,应用和数据库没做分离,靠一台服务器硬撑,加上最近爬虫肆虐,影响到了正常服务,为应对这个问题,增加了多种优化和防御措施,其中就有采用cdn对静态资源进行加速,我们采用的是阿里云提供的Dcdn全站加速服务(讲到这,一个cdn阿里硬是拆成了好几条,为了赚钱搞的真是够精细)。
问题
刚部属服务时,运维发现论坛首页出现了原链接全部变为IP的情况,导致页面打不开,手动在地址栏中将IP替换为域名即可访问,缩小范围仅出现在首页,怀疑cdn生效下发时,应用相关配置导致了错误,遂向运维提出更新首页操作,这个时间段内应用自动生成了首页,问题解决。
随后,报后台无法访问,页面报预设的程序文件丢失,以下是检查步骤:
- 错误页面误导思路至该文件有误,检查和确认后,该文件最近并无更新操作;
- 检查服务器nginx配置中发现后台设置了IP访问限制,仅允许公司IP访问,其余deny all,deny all 操作应返回状态码 403,向下继续检查发现403页面返回 404.html,检查网站根目录下404页面与前台输出一致,基本确定是IP相关问题;
- 检查服务器响应日志,发现来源IP全部发生变化,为进一步确认该问题,检查了另一台服务器做cdn的全球站后台响应,本地环境发出两次请求后,服务器记录了两个不同来源IP,遂确认为IP问题;
- 向运维提出先去掉nginx IP限制配置,nginx -t 后无误 reload,再次访问,服务正常;
- 但相关方强烈要求后台IP限制不能取消,但nginx 还获取不到用户真实IP,遂寻找解决方案,方案中要求对nginx重编译、安装插件等经过评估后均存在风险,暂不考虑;
- 查询阿里帮助文档中发现WAF服务中阿里增加了用户真实IP这个header头,在cdn文档中未能体现,遂要求输出$_SERVER中内容,发现存在 HTTP_ALI_CDN_REAL_IP 和 HTTP_X_FORWARDED_FOR 指代用户真实IP,综合考虑采用了 HTTP_ALI_CDN_REAL_IP 用以获取IP进行相关权限限定。
- 进行隐藏问题分析时考虑到请求中表IP的头发生了变化,该服务器同时安装有云锁,有很多规则,如果获取不到的话,会导致爬虫没有限制,造成风险,遂让运维挂外网IP,同时将此IP加入黑名单中,访问网站,发现防御正常,推测云锁底层应该存在对主流cdn的支持。
- 至此,问题解决。
分析
在以往对于cdn的认知中,其主要分发缓存静态资源等,对于php等动态文件应该存在规则,同时分析网络请求中,静态资源文件均带有标识,而php文件不存在,按道理讲是没做cdn缓存,研究相关文档和cdn底层原理后
认为cdn实际上也承担了代理转发的作用,通过其内网渠道快速调用相关源站(应用在阿里云ECS上),这个过程中导致了请求IP实际为流程中最后一台代理服务器的IP,阿里为解决这个问题,增加 HTTP_X_ALICDN_DA_VIA 来标明实际请求转发节点,同时增加以上提到了表真实IP的请求头。
推测的大体流程:
总结
相关技术只会用而不了解其核心原理和实现方式,导致出现问题后不能快速定位问题,只能一点一点追踪和学习,我一直信奉着 “工程师的成长是由线上事故堆出来的” ,所以,出了问题不要慌,和团队一起探究和解决问题的过程也是一种享受。