欢迎您光临本站,如有问题请及时联系我们。

微软资深工程师:聊聊合规要求对系统设计的影响

  Compliance,中文通常翻译为合规性,是软件和云计算领域频繁提到的一个概念。在很多国家和地区,一些特定行业和政府部门,对使用的 IT 设施,软件和服务都制定了各种基于数据安全考虑的规范。我们有时候听到一些术语,比如信息安全等级,可信云认证、FISMA、HIPAA、DPD 和最新的 GDPR 等都是与合规性相关的。

  作为云计算平台或者通用软件服务的提供商,在开发和运维过程中不同的应用场景都不可避免的涉及到合规的问题。国内云计算的主要玩家,阿里巴巴、腾讯和华为,近年来开始向国际市场进军,随之遇到的合规问题会显得更加复杂。而国内市场本身,随着 IT 和互联网环境的日趋成熟,外加政府云项目的推广,合规性的相关问题也会更加突出。

  部分工程师可能觉得这个话题和技术设计没有最直接的关系,不会对系统架构产生特别大的影响,而更多的是公司市场或者法律团队要操心的问题。但事实上因为合规要求所带来的需求会在很多方面影响到系统设计。

  举个例子,一些系统中直接使用用户名来作为用户的唯一标识,在内部逻辑中也没有将用户名映射到其他的 ID 或者 hash。在生成一个和某用户关联的 URL 给第三方使用的时候,由于应用场景对 PII 的规定用户名不能被泄露,所以就必须采取额外措施对用户名进行加密等处理。而加密常常涉及到密钥的管理、部署和更迭,无形当中就增加了开发和运维的工作量,同时还影响了运行效率。

  尽管不同国家和地区,不同行业,有不同的规范,但就一般商业软件和云计算平台而言,仍然有一些方法和实践是可以通用的。在适当的情况下借鉴这些经验可以很大程度上规避由于合规性带来的风险和额外工作量。在大型系统设计的初期,尤其企业级应用,应尽早把合规纳入设计的考虑问题之列。一些针对个人用户的网站,因为涉及到金融和支付的功能,也可以考虑参考一些类似的设计理念和注意事项,同样做到对个人客户负责。在这里我根据自己多年的行业经验,和各位简单聊一聊这个不是那么有趣,可能稍稍有点严肃的技术话题。

  用户身份认证

  谈合规性首先要谈到安全和身份认证。对于现代互联网和软件应用来说,基于 web 的用户认证方式是每个系统设计要解决的首要问题。云计算平台的提供商,尤其是 PaaS 层,往往是认证方式的实现者,需要提供完善和健壮的用户认证解决方案。

  明文密码和 token基于 web services 的 API 可以很简单地实现 Basic Authentication,即客户端用 HTTP 协议的 Authorization 头(header)来发送 base64 编码过的用户名和密码。因为 web services 大多数是无状态的,所以基本上要求每个请求都包含用户名和密码。这样的认证方式最简单,但要求服务器端全程 SSL 加密。而且因为整个过程的所有请求都带有密码,所以密码被泄露风险较高。举个例子,如果负责运维的工程师用诊断工具看到了 Authorization 头的内容,那么他就获取了用户的原始密码。

  很多应用场景禁止使用 Basic Auth,例如 PCI DSS 规范就要求使用基于 token 的用户验证方式。在 Authorization Server 和 Resource Server 分离的情况下,应尽量使用基于 OAuth 2.0 的模式来完成用户认证,这样避免用户密码在没有必要的情况下被传递到 Resource Server 上去。

  Multi-Factor Authentication一些公司和组织由于业务数据的敏感性,规定终端用户至少需要两种以上的认证方式进行登陆。经常听到的 FISMA 规范就有相关条款,要求组织职员和云服务提供商的运维人员都要遵守。除传统密码以外,电话,短信,USB 密钥等都可以作为其他的认证方式。

  对于认证方式的提供者来说,在系统设计时候将各种物理认证方式的抽象化就显得比较关键,易于从基本的用户名密码扩展到其他认证方式。

  URL 中的信息URL 很容易被客户端和服务器端的各个部件记录下来,尤其各种 web server 和 proxy 的 log 基本都在记录 URL,包括浏览器的历史记录。因此诸如用户 access token 等敏感信息不建议使用 URL 来传递。即便 access token 会过期,在 TTL 内被泄露仍可能造成重大损失,例如被用来执行删除操作。 对于 web services 和一些认证协议, Authorization 头是比较推荐的 token 载体。

  同样的道理,在进行 web 界面认证流程的时候,应该尽量使用 POST 而不是 GET 来传递原始 access token。一些认证系统为此专门使用相对复杂的浏览器端 JavaScript POST 来代替简单的 302 重定向,就是为了避免将 token 放在 URL 里。

  个人可识别信息

  前面的例子提到行业里经常使用的一个术语 Personally Identifiable Information,即个人可识别信息,简称 PII,相关术语还有 Linked PII、OII 等。很多条文规范,例如 HIPAA,对用户的隐私和 PII 信息的保密做了相关规定。这类信息包括用户名、姓名、电子邮件、电话等,从在大多数系统中虽然不是用户核心数据,但仍然可以被挖掘和恶意使用,造成个人和企业的损失。

  ID 影射前面的例子提到,使用用户自己创建的用户名,或者填写的电子邮件,手机号等来作为系统内部使用的唯一标识在很多情况下并不是理想的选择。一方面这类型的 ID 是可更改的,甚至是可以重复的,另一方面这些 ID 本身就很容易关联到用户的真实身份,无法满足合规性的需求。

  大型分布式系统大多都有 shard 的概念,如果基于 web 的应用协议在一个相对扁平 URL 的反向代理之内,那么在进行多方 web 跳转时候,有的系统设计可能需要借助用户的 ID 来重新定位原先的 shard 和节点。这种情况下就需要保证所生成的回调 URL 中不能有可识别的用户 PII 信息。

  新用户创建以后,系统应该分配不可人为识别的用户标识,比如 UUID 或者 sequence number 等,然后系统内部逻辑应该围绕其进行设计。这样的标识因为不能直接关联用户,需要通过某种可控的查找过程才能映射到可以识别用户身份的信息,所以不属于 PII 的类型。开发人员在使用此类型标识时候就有更灵活的空间。

  诊断工具和系统日志在如今的云计算时代,运维和诊断的工作基本上是由开发人员负责的。这些工程师可能属于 IaaS 和 PaaS 的云服务提供商,也可能属于 SaaS 的提供商。对于开发和运维人员来说,获取尽量多的用户信息,会让工作变得更加容易,但这其实与合规的要求是矛盾的。很多规范都不允许云服务提供商的工程师在默认情况下能直接接触到客户的 PII 信息。

  如前面提到,如果系统使用不可识别的内部用户 ID,那么工程师需要检查用户信息时候所依赖的工具也应使用该类型。根据一些条款,诊断工具在默认情况下应该将包含 PII 的返回字段进行清洗(scrub),例如加密或者乱序(scramble)到不可识别。当然,在需要的情况下,工程师还是可以通过申请临时权限提升来关闭 PII 清洗功能,从而看到用户的完整信息来帮助完成工作。另外在用户身份已知的情况下,比如用户提供了用户名,一般情况下用工具作反向查找获得用户的内部系统 ID 是被允许的。

  通常情况下系统日志(log)里面很容易包含 PII 信息,因为开发人员希望能够尽可能详细记录用户请求的细节,让诊断工作和基于日志的数据分析变得容易。但大多数情况下一个系统的日志来自很多不同组件,而大多数日志在生成和转移过程中都是可以被负责运维的工程师直接获得的,这样就需要进行 PII 清洗。最严格的规定要求在日志生成的时候就进行 PII 清洗。可以想象,在设计日志子系统时,如果用的是有 schema 的 log 格式,就有可能需要 metadata 来标记一个字断是否属于 PII。

  部署和运维

  经常可以听到项目组在讨论一个新的微服务应该在哪里运行,或者一些相对较小的数据可以存放在哪里,能不能使用 Azure 和 AWS 上的那些大家熟知的 PaaS 服务,如果可以用的话怎样用。比较有经验的工程师应该能马上根据服务和数据的类型来作出判断。元数据、配置数据、用户画像数据、用户核心数据等都是不同的数据类型,按照商业价值级别还可分为 LBI、MBI 和 HBI。

  代码安全这里指的代码安全是指产品代码在从源代码控制工具(如 GitHub)到部署,再到运行的过程中,不会被个人更改和替换。一些产品的核心部分代码要求使用带有数字签名的编译文件来实现,防止被有 bin 目录访问权限的个人更改。值得一提的是,这种严格的要求甚至可能会对编程语言的选择带来影响。

  一些初创型的互联网公司,代码交付和部署就是一个人手动搞定的事,轮到谁值班就谁来,被戏称为牛仔式部署(cowboy deployment)方式。尤其在使用诸如 AWS Lambda 和 Azure Functions 等 serverless computing 方案的时候,甚至可以在控制台里直接粘贴代码上去。可以想象这种部署方式是不满足合规要求的。

  团队应该对最终交付代码的权限有清晰的管理制度,避免单个工程师可以对系统作较大的改动,并且尽量使用自动化工具来进行管控。需要指出的是,这样做的目的并非不信任团队成员,而是为了达到合规要求,获得相关认证所需要实施的举措。

  权限提升运维过程中不可避免地要更改配置,查看原始日志,连接到服务器终端,甚至有的时候需要更改用户数据。这些对数据安全有影响,甚至危险的操作(例如前段时间的某网站误删数据库),都应该按照一定的流程来管控。在运维人员申请权限提升时候,应该有相应的流程来审批和授权,工程师的操作也应该被记录和 audit,临时权限提升不应该超过四小时。

  数据备份和保留

  备份和容灾对于云服务的提供商来说,用户数据的冗余存储和跨地域备份是基本要求。不同的云服务客户可能会根据自身需求和预算来选择高可用性和数据备份的方案,但一些规范则对跨地域存储和容灾备份有明确规定,不符合规定的提供商无法参与竞标。 另外需要注意的是,如果数据中心的地理位置跨国家和地区的话,在做跨地域设计时候,某些有合规要求的用户数据不能随便跨国家备份和 failover。

  Document Retention根据美国证监会(SEC)的 SOX 法案,上市公司的一些电子文档需要保存三年,并且要在会计和审计的时候要能够进行查询和导出操作。事实上市场上很多企业电子邮件备份解决方案就是根据这个法案的要求诞生的。这也意味着一些公司员工在删除电子邮件的时候其实并不能彻底删除数据。除第三方开发的邮件和数据备份软件外,像 Office 365 这样的企业应用产品也自身集成了这些功能。另外法案中对各种类型的用户文档的保留时长做了比较详细的规定,相应产品的功能设计也应该围绕具体条款进行。

  在以个人用户数据为中心的系统中,关于备份的要求可能会影响基本存储模型的选择和设计。产生数据的企业应用,作为第一方,可以选择将备份和保留的数据存在用户的基本存储单元和 shard 里,但必须有相对应的访问控制模型来区分用户可写数据和系统数据,对用户操作进行隔离,这样保证用户无法真正改写和删除数据。而第三方的备份产品,则可能需要复制相似的用户目录结构来存储备份的数据,还要应对用户变更和重命名的情况。

  除了以上讨论的几点以外,合规性要求也会对云服务的基础设施产生影响。微软数据中心对坏硬盘的销毁方式也根据数据价值级别有所区别,有的只要打孔,有的则需要把整个硬盘绞碎。除了上面讨论的内容外,还有一些非技术的相关流程,比如 FISMA 中规定了手提电脑丢失的上报时间期限等。

  本文只讨论了合规性的一小部分内容,而且只涵盖了那些基本适用大多数行业的方法和实践。特定的行业还有大量特定的需求,会对系统的方方面面造成影响。总而言之,负责总体设计的工程师,应当和产品经理紧密沟通,严肃对待合规性的问题,从第一天就带入设计的考量中,避免将来产生安全问题或者法律上的纠纷。


来源:本文由E8运维原创撰写,欢迎分享本文,转载请保留出处和链接!