查看原文
其他

云为什么留不住客户 — 以腾讯云 CAM 为例

马工在瑞典 瑞典马工 2023-11-29


长话短说

本土云厂商虽然仿造了AWS的大多数服务,但是由于没有云上企业级开发生产的经验,云服务的开发者们本身不知道怎么用云,进而无法向客户传播最佳实践。在产品功能裁剪的时候,也完全没有头绪,胡乱拼凑一番,使得用户很难感受到云计算的先进性。打个比方,他们模仿福特汽车造出了一辆特福车,但是因为自己没开过车,于是想当然的给用户示范怎么用马鞭赶机动车。用户看着浑身别扭,试用了一下,回头还是赶自己的马车去了。所以特福车只能打极深的折扣,通过和马车比拼价格来获得市场份额。

云厂商不是租车服务

早期云厂商有一个很著名的比喻:“IDC是买车,云计算是租车”。他们意在说服客户“不用再去买服务器,直接使用云服务厂商提供的服务即可”。


这个比喻早期确实帮助云厂商做了科普,但是十多年发展之后的今天,这个过时的比喻已经成了一个坑。现在不少主张下云的客户在说:”即使有了租车,用车多的家庭还是会买车, 同样的,对于稳定业务,我们也应该自建机房节省成本。” 云厂商当年的飞镖,被客户扔回来刺伤厂商了。


这个比喻的问题在于,它暗示云计算厂商不过是一个更精细化出租的 IDC 2.0,提供和 IDC 同质的服务。在这种框架下,客户评估云计算厂商的标准会简化为一个指标:价格。客户相信,只有云计算价格低于 IDC 的时候,上云才有意义,否则应该选择 IDC。


云计算是智能手机

一个更好的比喻是,把云计算 vs IDC 的关系视作智能机 vs 功能机的关系。乔布斯在2007年推出iPhone的时候,根本没在意通话质量,续航时间或者防水性,也无意和诺基亚比拼价格。他强调的是智能机的全新特性:人人都爱的触摸屏,支持多任务的OS X和无限可能的App。是这些全新的功能,让iPhone迅速流行起来。


云平台也有很多 IDC 无法交付的功能:人人可用的高阶软件,开箱即有的安全底座,DevOps的低廉实施成本。如果客户深深体会到云平台的先进性,自然就不会谈论下云。


所以下一个问题很自然的是:


中国云厂商,相对传统 IDC 真的具备先进性吗?

答案是:不太乐观。

我们就以腾讯CAM为例,看下本来应该带着我们飞的云服务,落地究竟是个什么样子。


以腾讯云 CAM 为例

CAM的官方定义是

访问管理(Cloud Access Management,CAM)是腾讯云提供的一套 Web 服务,用于帮助客户安全地管理腾讯云账户的访问权限,资源管理和使用权限。通过 CAM,您可以创建、管理和销毁用户(组),并通过身份管理和策略管理控制哪些人可以使用哪些腾讯云资源

如果把云平台看作新时代的 Unix 操作系统,那么CAM就是腾讯云的 用户管理 + ACL,是最底层的基础服务,应该集中展示云平台的先进理念,集中输出云厂商的先进实践。


但是,不幸的是,我看看的恰恰相反。


落后十年的组织架构

按岗位职责管理员工访问权限最佳实践中,CAM 建议客户“不同运维岗位关注的功能不同”,分为运维负责人,云服务器运维组,网络运维组,数据库运维组,安全运维组和监控运维组。


这是一种非常陈旧的组织架构了。十年前的《凤凰项目》就已经指出这种Dev/Ops分离架构会导致团队效率低下,无法敏捷的应对需求和环境的变更。


尤为荒谬的是,CAM甚至建议客户建立一个单独的监控运维组,只授权监控运维组可以访问监控云服务。而这种授权机制,会使得监控系统价值大打折扣,毫无必要的提升了团队沟通成本。据我所知,任何一个可观测性厂家都强烈反对这种组织架构。


非常随意的授权原则

同样在按岗位职责管理员工访问权限一文中,CAM 建议客户给运维组几乎无限制的访问权限。

根据上面的授权策略,如果客户公司有处理个人信息,那么云服务器运维组的每一个成员可以不受限制的访问用户照片,简历,证书或者其他以对象形式存储的个人信息。显然这是没有必要并且不合规的。

讽刺的是,在《安全最佳实践》一文中,CAM 告知客户 “最小权限原则是一项标准的安全原则。即仅授予执行任务所需的最小权限,不要授予更多无关权限”。看得出来,这两篇文章的作者,尽管在同一个团队中,相互之间的沟通并不顺畅。


另外一方面,安全运维组被只赋予了有限几个安全产品的访问权限,而缺乏对广泛云服务的访问权限。在传统 IDC 里,这种思路问题不大,因为 IDC 安全特性确实主要集中几个有限的安全设备上。但是云平台上,安全特性嵌入几乎每个云服务,这种安排就会严重的约束安全团队的能力。


纯手工打造的用户管理

尽管 CAM 支持用户通过 SSO 和自己的 IdP 集成,这个对企业非常关键的特性。但是在 CAM 的最佳实践页面,没有看到一个 SSO 的案例。在 FAQ 页面《用户相关问题》,也只看到从控制台创建子账号的使用经验。这让我不得不怀疑:这个 SSO 功能,真的处于商业可用状态吗?


陌生的熟人

《CAM 之外的安全管理》一文中,CAM 团队指出在 CAM 之外,CVM和云数据库也有独立的访问控制机制,却漏掉了和 CAM 最密切的基于资源的策略。尽管作者宣称“本文仅提供部分示例供您参考”,鉴于基于身份的策略和基于资源的策略关系如此紧密和复杂,我认为这种忽略对用户是不负责任的。


让人忧虑的代码质量

像其他云服务一样,CAM 范例的 bug 密度很高,让读者有足够的理由怀疑:这些范例代码的作者,究竟有没有真的在生产系统用过自己的云服务?

错误的命名

《按标签鉴权时支持仅匹配标签键》一文中,下面的策略命名为“cvm-RebootInstances”,暗示这个策略只赋予主体重启CVM的权限。

{ "version": "2.0", "statement": [ { "effect": "allow", "action": "*", "resource": "*", "condition": { "null_equal": { "qcs:resource_tag/test1": "false", "qcs:resource_tag/test2": "false", "qcs:resource_tag/负责人": "false" } } } ]}

细心的读者可以看出,这个策略赋予的权限远远不止是重启虚拟机这么小,而是符合tag的所有资源的完全管理权限。名字和实际权限完全不相符,在后续的维护过程中,可能会严重的误导同事和作者自己。


我翻阅了全部文档,发现cvm-RebootInstances 这个名字应该是直接抄袭腾讯云另外一个案例《授予标签下部分操作权限》,在那个案例中,正确的权限是:

"action": [ "cvm:RebootInstances" ],

糟糕的变量命名

案例《授予标签下部分操作权限》虽然把策略名字写对了,但也有自己糟糕的地方,它的账号命名和标签命名都不可理解:

企业账号 CompanyExample 下有个子账号 DevA

企业账号 CompanyExample 下有个为 test1 的标签键。

企业账号 CompanyExample 希望给子账号 DevA 授予标签键 test1 下的所有资源。

显然,DevA和test1这样的名字是极为不规范的。老油条比如我看到这样的文档,会生成警惕心:“这腾讯云 CAM 团队不太专业啊,命名根本乱来。”但是小年轻就会想:“人家腾讯大师们都用test1这样的标签,我叫test肯定没错!”


如果我继续,这样的低级错误还可以列出十几个,但是让我们就此打住吧,回到重点问题:CAM 团队究竟会不会,以及有没有用过 CAM ?

答案几乎很明确了:CAM 团队推荐的 CAM 最佳实践,有大量的业界反面教材。而业界真正的创新优秀实践,CAM 团队几乎没有提及。

IAM主要用户不是人

CAM的官方定义,值得再引用一次:

访问管理(Cloud Access Management,CAM)是腾讯云提供的一套 Web 服务,用于帮助客户安全地管理腾讯云账户的访问权限,资源管理和使用权限。通过 CAM,您可以创建、管理和销毁用户(组),并通过身份管理和策略管理控制哪些人可以使用哪些腾讯云资源

哪些人三个字让人非常失望。IAM 固然可以管理人类用户的访问,但实际上 IAM 最大的调用者不是操作控制台或者命令行的人类用户,而是人类编写的工作负载。


所有的云服务,天生的就接入互联网。没有物理隔离的保护,云服务就必须在应用层来识别应用程序的访问,而 IAM 就是简化这个工作的一个基础设施。


举例来说,我有两个微服务,一个 ImageReceiver 接受了客户上传照片,一个 ImageEnhancer 读取照片并且加以AI美容。两者都使用腾讯云对象存储 COS。那么我希望 ImageReceiver 只能写 /rawIamges 目录,而 ImageEnhancer 能读/rawIamges目录和写/enhancedImages。在这种授权原则下,即使我的代码被植入木马,暴露面也被极大的缩小了,同时软件bug能造成的爆炸半径也被限制了。


AWS的文档就比较清晰:

Require workloads to use temporary credentials with IAM roles to access AWS。

workload is a collection of resources and code, such as an application or backend process, that requires an identity to make requests to AWS services. IAM roles have specific permissions and provide a way for workloads to access AWS by relying on temporary security credentials through an IAM role. For more information, see IAM roles.


但是,很可惜的是,翻遍腾讯云 CAM 服务文档和控制台,也没看到我怎么能实现上述功能。


这个功能是如此的基础,AWS 还进一步推出了两个特性:

  1. 实例配置文件,进一步降低云虚拟机/容器上运行的应用程序实现上述访问控制机制的门槛。

  2. IAM Roles Anywhere,这个把 IAM Roles 推广到非 AWS 云服务。


替换数据库权限管理

这个功能,在传统的 IDC 是绝对找不到的。那些疑惑“ 我把价格打得这么低了,为什么还说不动那些企业用户”的朋友,我推荐你研究下这个场景。

思维严谨的读者会提出疑问:数据库也可以是一个云服务,那么 IAM 的鉴权是不是和数据库本身的账号体系重叠了?

答案是:Yes,两者就是重叠了。


如果您读一下AWS Dynamodb的文档,可以看出它没有自己的账号体系,其auths/authz完全委托给了 IAM 服务。假设你要限制 ImageReceiver/ImageEnhancer 两个应用对不同table的访问权限,你需要编写的是 IAM 策略和角色。应用层完全不需要关心数据库用户名或者密码,不仅减少了开发量,也提升了安全性。


至于RDS for MySQL/PostgreSQL这些云服务,由于兼容的原因,仍然使用传统的密码和安全组。很可惜的是,腾讯云的云原生数据库TDSQL-C,仍然使用传统的网络安全组和数据库用户名密码那一套,并不能直接使用 IAM 来鉴权。


IAM 降低开发者认知负荷

有较真的朋友会问我:“用户名密码+网络安全组又不是不能用,为什么你这么执着用 IAM 呢?”

答案很直白:因为 IAM 提供更高安全性的同时,能极大的降低我作为开发者的认知负载。我们可以对比一下TDSQL-C和Dynamodb的访问控制设置流程,看看这其间的差别。

没有 IAM 的数据库认证和授权流程

无尽的旅程:和密码复杂度做斗争

要在TDSQL-C实现合适的访问控制,首先你需要上一个页面去创建账号密码:

这个页面如此复杂,以至于你要认真的阅读一个说明书:

众所周知,密码泄漏是安全威胁的一大来源。密码管理是一个很繁琐的流程,从密码创建的强度检查,到密码的安全传递,到密码的更新,都很容易出错,是一个很大的认知负荷(cognitive load)。有不小的可能性,这里设置的密码,已经泄露到钉钉,微信甚至 GitHub 上了。

无尽的旅程:突然化身网络专家

但是给自己鼓个掌,下一步我们要在网络层配置安全组。


这个安全组的表格,甚至配备了两张填写说明书:

说明书写得很不严谨,只有提及端口号,却没有指明协议是TCP还是UDP,所以,很可能,我还要去问云厂商的客服才能准确的填写。

无尽的旅程:授权

上面我们还只是做了认证部分,授权部分要跳到另外一个完全不同的页面去。

说句实话,填表填到现在,我已经筋疲力尽了。我甚至不想去搞清楚 TDSQL-C 这个一会又叫“账号”一会又叫“账户”的东西究竟是个什么玩意。我只想尽快搞完。所以十有八九,大多数客户会给一个账户授予全读写的管理员权限,然后在所有应用程序中使用这个用户,尽管这意味着一个更大的安全暴露面。

无尽的旅程:西西弗斯的困境

如果您有几百个服务,想象一下,把上面的流程重复几百遍!


有IAM支撑的云服务访问控制设置流程

Dynamodb的访问控制设置非常直白。你只需要一个terraform文件(或者cloudformation文件,取决你团队的审美)

provider "aws" { region = "us-west-2"}
resource "aws_iam_role" "dynamodb_books_role" { name = "DynamoDBBooksRole"
assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Action = "sts:AssumeRole", Principal = { Service = "ec2.amazonaws.com" }, Effect = "Allow", Sid = "" } ] })}
resource "aws_iam_role_policy" "dynamodb_books_policy" { name = "DynamoDBBooksPolicy" role = aws_iam_role.dynamodb_books_role.id
policy = jsonencode({ Version = "2012-10-17", Statement = [ { Sid = "DescribeQueryScanBooksTable", Effect = "Allow", Action = [ "dynamodb:DescribeTable", "dynamodb:Query", "dynamodb:Scan" ], Resource = "arn:aws:dynamodb:us-west-2:231233387771:table/Books" } ] })}

如果你想为五百个应用设置500种不同的权限集,只需要把这个文件做成一个模版,传入合适的变量,就可以嵌入CICD流水线了。


这样做不仅减轻了工作量,而且由于code review的存在,配置会得到审视,并且有版本历史。尤其全程没有密码的生成/传递/保存/轮换,一个极大的安全威胁被消除了。


DevOps and Infra-as-Code

上述Dynamodb的配置流程,是一个典型的利用Infra-as-Code工具提升生产力的应用场景。让我们打开天窗说亮话,能支持我这样自动化的云,就是先进技术提供商。不支持自动化反而向我示范手工作业的云,就是个IDC 2.0.


先进技术提供商可以理直气壮的收取技术红利,而 IDC 2.0是没有议价能力的,要么走劳动密型路线提供廉价的驻场技术支持,要么走资本密集性路行提供极深的折扣价。这也是我看到的本土云厂家最大的缺陷。

AWS也是可以超越的

有敏感的朋友可能会骂我“你天天吹AWS这个好那个好,还要踩本土云一脚,你是不是亚马逊的打手?”

对这个问题,我只能说:亲,不是的,AWS没有给过我一分钱,但是不妨碍我称赞他们的产品做的漂亮。中国本土云厂商,如果要想有世界影响力,不能只无脑抄一个肤浅的界面,深入了解 AWS 产品的应用场景和优缺点是一个起码的要求。


实际上,我现在就可以指出一个 AWS IAM 的缺点供本土厂商参考:一个应用程序在不同的阶段可能需要不同的权限,但是 AWS IAM 不允许同时 assume 多个角色,使得应用程序要不停的显式的调用assume-role去切换角色,这是一个很繁琐的工作,也很容易出错。目前没看到 AWS 有能接受的答案。


造车的要开过车,造云的要用过云

你很难想象Michael Widenius没有写过SQL,乔布斯只用座机,福特上下班开马车,盖茨雇个秘书帮他打字,马斯克不用自媒体,马化腾不聊QQ,但是云厂商的开发者自己不用云几乎是普遍现象(有些甚至没有自己的云平台账号)。如果这种浮躁风气不改变,我看不出云厂商拿什么和 IDC 竞争市场。


不少云厂家养了一堆DevOps专家和持续交付大师,一年到头的跑会讲理念,讲哲学甚至讲中美文气候差异对软件开发流程的影响,就是不能把他们的理念落实到具体的云服务上。有时候,我看着这群人,只有一个感觉:草台班子居然可以搭这么大还不倒,真是令人佩服。


为下云的客户辩护一句

我在乡下,本来骑着我的小毛驴去种地。听了资深SA的建议,升级到了摩托车。资深SA教我“你两只脚这样踏在地上,左脚先划一下,然后重心移到右边,右脚再划一下,如此反复,摩托车就走起来了。” 我这样傻不拉几的划了几天,实在忍不了,把摩托车退回去,换回我的小毛驴了。然后我逢人就说“摩托车真的不行,还是小毛驴更符合中国国情。”

备注

  1. 我所有的引用在原文都有链接,但是很可惜,微信的张小龙裁定微信公众号不支持蒂姆·伯纳斯-李先生三十年前发明的 web 超链接,所以各位读者无法自由跳转过去。

  2. 我和腾讯云 CAM 团队没有利益关系。本文指出的现象,也广泛的存在于其他云服务产品团队。我只是提出议题,需要一个例子。


继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存