当配置审计发现资源配置有变更且不合规时,以事件通知的形式将告警推送到您指定的消息服务MNS主题。当您收到不合规告警时,通过函数计算实现不合规资源的自动修复。

前提条件

应用场景

您在配置审计控制台通过托管规则oss-bucket-public-read-prohibited新建一条资源类型为ACS::OSS::Bucket的规则,配置审计自动审计当前账号下所有资源类型为OSS Bucket的资源,其中一条资源的合规结果为不合规,如下图所示。Bucket不合规

数据规划

本文以修复对象存储OSS的存储桶的读写权限为例,为您介绍通过配置审计的MNS通知机制实现不合规资源自动修复的操作方法。相关数据规划如下表所示。
云服务 参数 示例
配置审计 托管规则 oss-bucket-public-read-prohibited
规则名称 test-oss-bucket-public-read-prohibited
消息服务 主题名称 MNSTestConfig
主题地域 华东2(上海)
对象存储OSS OSS Bucket config-snapshot
Bucket ACL 公共读
函数计算 服务 resource_repair
服务的系统模板权限 AliyunOSSFullAccess
函数 oss_repair_acl_trigger
触发器 ConfigRuleNonComplianceMNSTrigger
说明

由于配置审计部署在华东2(上海),为了减少网络损耗,建议消息服务MNS的主题地域选择华东2(上海)

操作流程

通过配置审计的MNS通知机制实现不合规资源自动修复的操作流程如下图所示。修复流程

操作步骤

  1. 接收资源事件。
    操作方法请参见接收资源事件
  2. 新建服务。
    1. 登录函数计算控制台
    2. 在顶部菜单栏,选择地域,例如:华东2(上海)
    3. 在左侧导航栏,单击服务/函数
    4. 从下拉列表中选择新建服务
    5. 新建服务页面,输入服务名称功能描述
      新建服务
    6. 单击创建
  3. 授权目标服务修改OSS Bucket的权限。
    1. 服务配置页签,单击修改
    2. 权限配置区域,系统模版授权选择AliyunOSSFullAccess
      权限配置
    3. 单击点击授权
    4. 角色快捷创建页面,输入策略名称
      角色快捷创建
    5. 单击同意授权
  4. 新建函数。
    1. 服务/函数页面,单击新建函数
    2. 创建函数页面,选择创建方式事件函数,单击下一步
    3. 配置函数页面,所在服务选择resource_repair运行环境选择python3,其他参数保持默认值。
      配置函数
    4. 单击完成
  5. 配置函数的环境变量。
    1. 在左侧导航栏,单击服务/函数
    2. 在目标服务的函数列表页签,单击目标函数名称对应的链接。
    3. 在目标函数概览页签的函数属性区域,单击配置
    4. 配置函数页面,配置该函数的环境变量。
      • prepareRuleName

        prepareRuleName与函数计算自动修复代码中参数ENV_RULE_NAME的取值保持一致。

      • test-oss-bucket-public-read-prohibited

        test-oss-bucket-public-read-prohibited为配置审计中的规则名称。

    5. 单击提交
  6. 新建触发器。
    1. 在目标服务的函数列表页签,单击目标函数名称对应的链接。
    2. 在目标函数的概览页签,单击触发器页签。
    3. 触发器页签,单击创建触发器
    4. 创建触发器页面,设置触发器相关参数。
      创建触发器
      参数设置如下:
      • 服务类型选择MNS主题触发器
      • 触发器名称输入ConfigRuleNonComplianceMNSTrigger
      • MNS Topic所在区域选择华东2(上海)
      • Topic选择MNSTestConfig
      • Event格式选择JSON
      说明 当您初次使用MNS主题触发器时,如果角色创建方式选择快捷授权,则在创建触发器页面,根据页面提示,为触发器快捷授权角色AliyunMNSNotificationRole后,需要关闭该页面,重新打开,即可看到已授权的服务角色,并根据所需创建触发器。
    5. 单击确定
      新建触发器完成后,当配置审计对目标资源进行评估时,您会接收到该资源的不合规事件通知。
  7. 配置自动修复代码。
    1. 在左侧导航栏,单击服务/函数
    2. 在目标服务的函数列表页签,单击目标函数名称对应的链接。
    3. 在目标函数的管理页面,单击代码执行页签。
    4. 代码执行页签,选择在线编辑,拷贝并粘贴如下代码。
      # -*- coding: utf-8 -*-
      import logging
      import json
      import os
      import base64
      import binascii
      from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
      
      IDENTIFIER = 'evaluationResultIdentifier'
      QUALIFIER = 'evaluationResultQualifier'
      RULE_NAME = 'configRuleName'
      ENV_RULE_NAME = 'prepareRuleName'
      RESOURCE_ID = 'resourceId'
      REGION_ID = 'regionId'
      FAIL = 'fail'
      SUCC = 'success'
      
      logger = logging.getLogger()
      
      
      def handler(event, context):
          logger.info("mns_topic trigger event = {}".format(event))
          decoded = None
          if event:
              try:
                  decoded = base64.b64decode(event)
              except binascii.Error as ex:
                  logger.exception('mns_topic trigger event malformed!')
                  return FAIL
          if not decoded:
              return FAIL
          notify_json = json.loads(decoded)
          if notify_json and IDENTIFIER in notify_json:
              evaluationResultIdentifier = notify_json.get(IDENTIFIER)
              if QUALIFIER in evaluationResultIdentifier and RULE_NAME in evaluationResultIdentifier.get(QUALIFIER):
                  evaluationResultQualifier = evaluationResultIdentifier.get(QUALIFIER)
                  configRuleName = evaluationResultQualifier.get(RULE_NAME)
                  # os.environ.get(ENV_RULE_NAME) 获取您设置的规则名称,例如:test-oss-bucket-public-read-prohibited。
                  if configRuleName == os.environ.get(ENV_RULE_NAME):
                      if RESOURCE_ID in evaluationResultQualifier and REGION_ID in evaluationResultQualifier:
                          bucket_name = evaluationResultQualifier.get(RESOURCE_ID)
                          region = evaluationResultQualifier.get(REGION_ID)
                          if region and bucket_name:
                              try:
                                  remedy_by_fc_assume(context, region, bucket_name)
                              except Exception as ex:
                                  logger.exception('remedy fail!')
          return FAIL
      
      
      def remedy_by_fc_assume(context, region, bucket_name):
          creds = context.credentials
          auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
          bucket = oss2.Bucket(auth, 'http://oss-' + region + '.aliyuncs.com', bucket_name)
          bucket.put_bucket_acl(oss2.BUCKET_ACL_PRIVATE)
          logger.info('bucket {bucket_name} in {region} acl remedy succ.'.format(bucket_name=bucket_name, region=region))
                                      
      说明 本段代码以规则名称prepareRuleName为例,为您介绍不合规资源的自动修复方法。如需通过其他参数修复,则请参见资源合规事件
    5. 单击保存
      说明 请勿单击保存并执行,即请勿手动执行代码。否则将导致操作失败。
  8. 十分钟后,查看修复结果。
    说明 当资源配置无变更,且审计结果为不合规时,您还需要手动执行审计,然后再执行此步骤。手动执行审计的操作方法,请参见手动执行审计
    • 通过配置审计控制台查看OSS Bucket合规
    • 通过OSS控制台查看OSS Bucket合规