vlambda博客
学习文章列表

民生银行基于c7n实现OpenStack私有云资源合规基线检查

1 背景介绍

OpenStack实现了基于多租户模型自服务云资源的快速供给交付,用户通过云管平台接口可以弹性按需构建各种虚拟云资源,比如虚拟交换机、虚拟防火墙、虚拟机、虚拟路由、虚拟负载均衡等,甚至可以在数分钟的时间编排构建一套完整的虚拟数据中心。

通过OpenStack云平台,资源的快速构建交付已不是什么难事,但是对用户自服务形式申请的云资源如何有效地、自动地进行安全合规等基线检测还没有很好的方案,例如安全组是否开放了高危端口、业务虚机是否考虑跨多AZ、是否存在闲置卷、资源标签是否完备并且符合规范、虚拟机是否使用了不满足要求的黄金镜像。

早期我们采用最朴素的方法是登录到用户账号进行手动巡检,这种方式效率显然非常低下。为了提高效率,我们通过编写大量的Shell及Python脚本以实现自动化检测,一个规则一个脚本,效率得到大幅度提高。但脚本的维护又是让人头疼的问题,可读性差、不易扩展,而且经常由于环境和参数的差异导致执行失败。

我们在公有云实践探索中发现在公有云同样需求场景中,有像AWS托管的Config服务以及支持多种公有云的开源Cloud Custodian(c7n)项目能够通过自定义的策略自动检查资源配置是否满足合规基线和最佳实践,这给了我们一种全新的思路,在私有OpenStack云平台环境中也可以采用可声明的抽象策略Policy进行基线检查而不是使用面向过程的脚本集的方式。

OpenStack曾经有一个安全合规检查项目Congress[1],经过前期调研,我们了解它的语法类似函数式写法,相对比较复杂,用户必须学习各种函数的用法,这种方式感觉与脚本方式差别不大。

比如检查port至多只有一个IP,对应的Congress策略为:

error(port_id, ip1, ip2) :-
  port(port_id, ip1),
  port(port_id, ip2),
  not equal(ip1, ip2);

这种方式更像是面向过程的编程方法,易用性不好,学习成本高,因此没有很好的推广,使用案例和场景不多,维护的人越来越少,因此社区在今年7月份对该项目进行了归档,意味着该项目最终退役(retire)不再维护,具体原因可以查看当时的描述:Retire the Congress project[2]

因此我们放弃了Congress方案,而Config服务又是AWS的托管服务,难以在私有云场景下落地,剩下的可选方案就是c7n项目了,因此我们开始对c7n项目进行进一步研究。

2. c7n项目简介

Cloud Custodian(简称c7n)在之前的一篇文章[3]中简单介绍过,是在公有云场景上非常流行的一款合规检查自动化工具,在Github上有3300多stars,它是美国第一资本投资国际集团CapitalOne银行开源的基于YAML简单DSL语言声明式云资源配置基线检查工具,能够通过大家熟悉的标准YAML语言定义规则来检索不符合基线配置的云资源并可以自动进行修正。

Cloud Custodian: Rules engine for cloud security, cost optimization, and governance, DSL in yaml for policies to query, filter, and take actions on resources

民生银行基于c7n实现OpenStack私有云资源合规基线检查

c7n_logo

通过c7n工具,运维人员不再需要编写和管理大量的shell脚本和策略参数就可以实现大规模云资源的实时合规性检查和成本管理,c7n还能与云上Serverless函数式编程FaaS服务集成,支持基于事件自动触发。感兴趣的可以观看Captial One总监Kapil Thangavelu的介绍:This Is My Architecture[4]

民生银行基于c7n实现OpenStack私有云资源合规基线检查

capital-one-archiecture

以之前文章里的一个AWS上常见的问题为例,我们知道AWS的EC2、EBS等资源是不记录创建者用户信息的,如果一个账户有多个用户,在EC2列表中查不到这个虚拟机到底是谁创建的,只能通过Cloudtrail在海量日志中低效率检索。

当然针对这个问题可以写一个几百行的Lambda函数来处理和分析创建资源的事件,并从事件中取出User字段,给资源添加上User标签。

但是如果有很多账户,每个账户都手动配置一遍显然非常繁琐且耗费时间。你可以把Lambda函数提前放到S3上,然后通过Terraform配置Lambda、Cloudwatch以及Cloudtrail,不过这种方式需要构建Lambda函数不说,光Terraform代码没有几百行肯定是搞不定的。

而使用c7n则只需要写一条Policy,不到20行代码:

policies:
- name: ec2-auto-tag-user
  resource: ec2
  mode:
    type: cloudtrail
    role: arn:aws-cn:iam::***:role/***
    events:
    - RunInstances
  filters:
  - tag:CreatorName: absent
  actions:
  - type: auto-tag-user
    tag: CreatorName
    principal_id_tag: CreatorId

再比如检查哪些安全组开放了22、3389等高危端口到互联网,只需要编写如下规则:

policies:
- name: ...
  resource: ec2
  filters:
  - type: ingress
    IpProtocol: tcp
    Ports: [22, 3389]
    Cidr:
      value:
      - "0.0.0.0/0"
      - "::/0"
      op: in
   actions: ...

通过如上两个例子,我们发现通过c7n进行合规基线检查只需要定义简单的规则就能替代大量的脚本工作,并且语法简单、易读性高。这得益于c7n把规则逻辑从代码中完全抽象出来,用户只需要声明或者定义规则,不需要为每个规则编写代码告诉平台怎么一步步处理,不需要学习函数语法,而只需要复用一套通用规则引擎即可实现对资源的检索和操作。

不过目前c7n仅支持AWS、Azure、GCP等公有云,Kubernetes也在开发中,但暂无计划支持OpenStack私有云。

3 c7n OpenStack provider设计与实现

前面提到c7n目前不支持OpenStack,但c7n具有非常良好的可扩展性,在c7n的源码基础上很容易增加新的Provider以支持OpenStack。

沿着这思路,我们开始着手开发基于c7n的框架实现OpenStack Provider。

早期我们使用了OpenStack shade库[5]连接OpenStack API,后续由于社区逐步推广使用openstacksdk[6]替代shade,因此我们也使用了新的openstacksdk库进行了重写,配置支持环境变量以及config文件两种方式,环境变量即我们常用的openrc文件,而config文件官方样例如下:

  test_cloud:
    region_name: RegionOne
    auth:
      auth_url: http://xxx.xxx.xxx.xxx:5000/v2.0/
      username: demo
      password: secrete
      project_name: demo
  rackspace:
    cloud: rackspace
    auth:
      username: joe
      password: joes-password
      project_name: 123123
    region_name: IAD
example:
  image_name: fedora-20.x86_64
  flavor_name: m1.small
  network_name: private

具体的配置方法可以参考OpenStack官方文档Connect From Config[7]

解决了OpenStack环境的连接问题,最后的问题就是resources的编写,c7n支持资源的动态注册,而resources主要包含filters和actions,filters决定如何检索过滤不符合安全合规基线的资源,比如虚拟机可以基于status、image、flavor等属性进行过滤,而actions决定过滤后的不合规资源执行什么操作,比如虚拟机关机、重启、删除、告警、标签标识等。

c7n已经实现了很多通用的filters,比如ValueFilterAgeFilter等,一些常见的属性值比较,比如gtlteqincontains、正则匹配等均已经实现,直接继承ValueFilter即可,而AgeFilter只需要重写启动时间参数即可,这些通用的filters大大减少了resources开发量。

而针对OpenStack特定的filters也只需要继承QueryResourceManager类并实现process方法,然后调用filter_registry.register注册即可。actions实现与filters类似,这里不再赘述。

我们经过日常运维和安全合规管理的大量实践和总结,已经编写了许多针对OpenStack资源(如Server、Flavor、Project等)的filters和actions并应用在日常运维和管理中,使用c7n替换了大量的shell脚本对OpenStack上的云资源不符合安全基线的资源进行快速检索和操作,获得与AWS资源检索与合规检查一致的体验。

比如检索哪些安全组开放了192.168.0.0/16的高危22端口访问,只需要编写如下规则:

- name: test-security-groups
  resource: openstack.security_group
  filters:
  - type: ingress
    cidr: 192.168.0.0/16
    port: "22"
    protocol: tcp

查看存在哪些全局高权限admin管理员角色用户:

policies:
- name: find-admin-users
  resource: openstack.user
  filters:
  - type: role
    role_name: admin
    system_scope: true

查看demo租户有哪些_member_角色用户(全局admin除外):

- name: test-user
  resource: openstack.user
  filters:
  - type: role
    role_name: _member_
    system_scope: false

删除镜像已经被移除的废弃虚拟机:

- name: delete-old-servers
  resource: openstack.server
  filters:
  - type: image
    status: absent
  actions:
  - delete

运行方式和AWS资源完全一样,只需要执行run子命令即可,通过report子命令可以查看匹配的资源列表。

custodian run /root/demo.yaml -s /root/output
custodian report /root/demo.yaml -s /root/output --format grid

tags-with-app-equal-web

4 总结

我们源于开源社区同时积极贡献社区,目前已经把c7n OpenStack Provider提交PR到上游中#6317[8],获得了Core Reviewer的积极反馈[9],相信后续等待测试完毕后将很快合并到Main分支中,我们也期待更多的OpenStack开发者加入到c7n OpenStack Provider子项目开发,贡献更多好用的OpenStack filters以及actions,完善c7n OpenStack Provider的功能。

不过由于OpenStack目前缺乏像AWS那样成熟的函数计算FaaS集成方案,当前c7n OpenStack只能运行在local模式,暂不支持类似cloudtrail、periodic等模式,后续将调研如何与OpenStack Qinling、Ceilometer等服务的集成,使c7n OpenStack能够像AWS一样基于event事件驱动触发。

参考资料

[1]

Congress: https://docs.openstack.org/congress/train/user/readme.html

[2]

Retire the Congress project: https://opendev.org/openstack/congress/commit/bba805af02f516b95650531afc02d1c60b1cd010

[3]

云资源安全合规基线自动化检查与配置: https://int32bit.sh/2020/01/14/%E4%BA%91%E8%B5%84%E6%BA%90%E5%AE%89%E5%85%A8%E5%90%88%E8%A7%84%E5%9F%BA%E7%BA%BF%E8%87%AA%E5%8A%A8%E5%8C%96%E6%A3%80%E6%9F%A5%E4%B8%8E%E9%85%8D%E7%BD%AE/

[4]

This Is My Architecture: https://www.youtube.com/watch?v=7psvM3r_wCg&list=PLhr1KZpdzukdeX8mQ2qO73bg6UKQHYsHb&index=1

[5]

OpenStack shade库: https://docs.openstack.org/shade/latest/

[6]

openstacksdk: https://docs.openstack.org/openstacksdk/latest/user/

[7]

Connect From Config: https://docs.openstack.org/openstacksdk/latest/user/guides/connect_from_config.html

[8]

#6317: https://github.com/cloud-custodian/cloud-custodian/pull/6317

[9]

积极反馈: https://github.com/cloud-custodian/cloud-custodian/pull/6317#issuecomment-735792625


作者简介:

高岩:任职民生科技智能云技术部,目前致力于云平台工作,熟悉Python、Shell、操作系统、虚拟化等相关技术。

刘婉辉:任职民生银行云技术管理中心,目前致力于云平台落地、推广、云平台运维管理等工作。

蔡泽宇:任职民生银行云技术管理中心,毕业于北京邮电大学,目前致力于民生银行运维相关工作,熟悉Python、Shell等编程语言。

崔增顺:任职民生银行云技术管理中心,目前致力于云平台工作,熟悉私有云、公有云架构以及解决方案。



↓↓ 点击"阅读原文" 【加入云技术社区】

相关阅读:





更多文章请关注


文章好看点这里[在看]👇