阿里云监控插件安装蹲坑记 -- 安全策略导致的失败推论
最近用阿里云新搞了个项目,上线了,一切看起来都很美好,很安全。
由于其中一台机器作用特殊,于是禁止了该机器所有出外网的权限,毕竟为了安全嘛,而且经过考量确实是不需要出外网的。
直到后来从阿里云监控上看时,才发现了异常。阿里云最近提示有了新的监控升级,功能更强大,我果断选择了升级,升级后发现果然比之前的监控更美了。(缺失了系统监控的阿里云服务器犹如折翼的天使,可惜了)
然而问题就在这时候来了,该台机器显示监控插件安装失败。然后上面还有温馨提示:“插件自动安装失败,将在10分钟后重新再次安装!”。于是我苦等了几个小时,最后还是看到安装失败:“我信你个鬼,你个糟老头子坏得很。”
没办法,看来它肯定是指望不上了,只能看手动安装了呗。其实一眼就能看到上面有手动安装的功能,体验还是很棒的!点进去就能找到指引,大概步骤就是先选择机型,选择机器所属区域,然后给你一个解决方案,我的是阿里云主机,linux系统,所以得到的解决方案是一串shell命令,去机器上执行就好了。
1. 我们先简单看一下这个shell脚本是干啥的?
REGION_ID=cn-shanghai VERSION=1.3.7 bash -c "$(curl https://cms-agent-cn-shanghai.oss-cn-shanghai-internal.aliyuncs.com/release/cms_install_for_linux.sh)"
1. 指定版本号;
2. 从某资源服务器上下载一个shell文件;
3. 执行下载来的shell脚本;
所以,安装插件的工作是委托给了一个别人写好的安装脚本,这也是为啥前面要让你选择机型和所属区域的原因。因为该脚本只适合于特定case嘛。
2. 接下来是手动监控插件时间!
拿到安装脚本后,出于对阿里同学的信任,我果断去机器上执行了。然而,结果并没有想像中美好!想像中的样子是:几个进度条一刷,安装包下载,自动依赖解决,安装成功,启动服务!然而我执行脚本的结果却是一直等待。最后,结果出来了,域名无法解析,好嘛,那就是外网出不去呗。
很自然地,我想起了后台设置了禁止出外网的限制,为了验证该想法,我果断打开了限制。果然,安装脚本成功,稍等片刻,云监控上已经显示正在运行中,且已经出现了监控数据。看起来皆大欢喜了,但是等等,为了安全,我还是得禁用外网。我刚刚打开外网的目的,只有一个,那就是安装监控插件,现在插件已安装成功,自然不再需要外网了。
于是,机智的我关掉出外网的权限,我自然也考虑到会不会监控失效的问题。所以,关掉外网后,我观察了下监控数据,一切都很美好,监控正在运行中。于是,我继续去“疯狂打码中”了。后来很长一段时间,我也没有再去查看监控。直到后来闲下来,再去查看时,发现在监控状态变成了“已停止”!为啥?
两个猜想:1. 进程挂了,真正的停止; 2. 监控平台无法发现该机器,即所谓的心跳检测失败。
要验证猜想很简单,去该机器上查下就知道了。不过,这里有个小问题?我又不知道监控进程是啥嘛,我怎么去找?那就只能猜了呗,既然叫云监控,想来 cloud, monitor 之类的关键词应该会有,所以用grep过滤一下就可以了嘛,关键词太长,那就减少了来过滤嘛,最后验证了,监控进程还在的!所以只能是第二个猜想了:监控平台与机器间的心跳没了!稍微想一下就知道了,是网络通信出了问题,然后再想想自己设置的禁用外网自然就明白了。
知道是禁用外网导致的,怎么办?难道我要因为这监控把外网打开?根据业务场景嘛,反正我是不敢这么干的。不过再开一会还是可以接受的,一切为了验证猜想,外网再次打开后,监控数据又恢复了它跌宕起伏的姿态。好了,在没有想好怎么做之前,我宁可不要这监控了。于是断掉外网。
继续思考上面的问题,很明显是两个需求:不准出外网,希望有监控!那怎样既可以让监控运行,又可以禁止出外网呢?
linux上有经典的黑白名单控制机制,而阿里云上的安全策略则更加完善。其中我们也可以只看其黑白名单功能,要么禁止访问,要么允许访问,两个有冲突时,linux上是以允许为准,但好像阿里云不是,它是以优先级来判断的,你可以设置允许优先级高于禁止优先级就可以了。
所以,按照这个思路,我们要做也简单,保持现有黑名单的同时,增加云监控的白名单就可以了!嗯,没错就是这样!
3. 我怎么知道云监控使用的IP呢?
那我怎么知道监控的上报ip是多少呢?或者域名是多少呢?能通过域名添加允许吗?shit,好像都不知道呢!
对监控系统毫无所知的情况下怎么去设置?要了解监控系统的信息,至少有三种方式:
1. 查阅官方文档,看里面是否有说明;
2. 问百度或朋友,你知道吗?运气好的话,很快就有完整答案了;
3. 抓包分析数据,自己得出结论;
上面三种方案,我是按顺序来的,一是官方文档都是讲产品使用的,压根没想过你给他整个黑名单;二是网上江湖太混乱,简直是大海捞针,朋友留到最后;最后,只能寄希望于抓包了。
4. 抓包查看数据流向:(如下示例)
怎么抓呢?先全抓吧,那数据流看花了眼。(其实是可以看出来的)!但是换个角度想,既然监控平台要求出外网,那么,按照当下的行情,基本都是基于https通信的,所以,我们可以直接抓包443端口试试。等了好久发现没有,于是试着自己制造些443端口的访问,结果失败了才想起,要抓包还得先把禁止规则关了。很顺利,抓到了443的包,查了下ip,是上海阿里云!看起来应该ok了,但是,稍微多抓几个包后发现,ip居然是n个?那咋整?如果把自己找到的ip都加上白名单,那么可能会不全从而会有监控丢失(这是一定的)! 所以,只能换一种方式了。来分析下自己列举的ip,很快就发现其中规律,那就是前面几位都一样的。
tcpdump -iany port 443
得到的结果IP样例如下:
140.205.172.22 140.205.32.10 140.205.172.20 140.205.230.31 140.205.34.11
看着这么多个IP,可以有两个解决方案: 一是将以上ip加入白名单,但是可能不完全准确;另一个就是使用网段的表示方式,但是可能不安全,如上ip系列可以扩大为:140.205.0.0/16 。
怎么做都行,各自权衡!
5. 加上以上白名单就行了吗?
当我把白名单加上之后,我把原来的禁止规则打开!然后在该机器上 ping 这些ip时,准确无误的出去了,而对其他的ip则是拒绝的。所以,验证正确!
看了下后台监控,一切都很美好! 于是,我又吭哧吭哧写代码去了。
过了好长时间,我又回来溜达了,猛然发现,监控服务又停止了! 为啥??? 我不是加了白名单了吗?还出不去?继续ping那些ip,是没有问题的。
那还有什么问题呢?
6. DNS 出去了吗?
我们使用的外网服务一般都是以dns进行提供的,那么,dns 能出去吗? oh, no !
于是去检查 dns 地址:
cat /etc/resolv.conf # 查看配置的 dns
果然发现其中的ip,是被拒绝的。果断把该dns 的 ip 加入白名单后,终于OK了!
7. 最后的优化?
既然已经发现了dns解析问题,为什么不直接抓包 dns 呢?
tcpdump -iany host 100.100.1.1 or 100.100.2.2 -XX -vv
然后发现了实际的监控地址为: metrichub-cn-shanghai.aliyun.com 。 (其实在官方文档上面已经标明了,尴尬!)
cms-cloudmonitor.aliyun.com # 这个在文档里没说
一个小问题而已,有什么所谓!
万一你也遇到同样的问题呢?