亚马逊AWS官方博客

使用 Amazon Polly 针对 AWS 账户安全事件进行电话呼叫报警

AWS 账户的安全性是重中之重。随时了解您 AWS 账户中与安全相关的所有最新事件非常重要。您可以通过多种方式接收警报,例如通过电子邮件或短信,不过在本博客帖子中,我将向您演示如何使用 Amazon AI 服务 (例如 Amazon Polly) 以及任何基于云的通信平台 (例如 Twilio),在手机上接听语音警报。

Amazon Polly 是一项将文本转换为逼真语音的服务,让您可以构建支持聊天功能的应用程序,从而打造全新类别的具有语音功能的产品。它使用深度学习技术来合成类似于人声的语音。该服务提供了不同语言的各种语音。

对于外出的企业 IT 安全人员,有关 AWS 账户安全事件的电话呼叫警报可以带来极大的帮助。这些安全事件可以根据事件的严重性和优先级进行自定义。严重性和优先级较高的安全事件可以发送到通过电话呼叫报警的系统中。

对于电话呼叫报警,我会使用 Twilio,它提供了 API 功能,例如语音、视频和消息传送。当给定 AWS 账户中发生安全事件时,使用 Twilio 的平台能够以编程方式发布 API 调用,用于进行电话呼叫。Amazon Polly 将此文本警报转换为在电话呼叫上播放的语音消息。

解决方案概述

该解决方案包括两个系统,如以下架构图所示:

  • 事件检测和通知系统
  • 文本到语音转换系统

事件检测和通知系统与文本到语音转换系统彼此分离,这是因为后一个系统对用户定义的任何其他事件检测通用。在此博客帖子中,作为解决方案示例,我重点介绍文本到语音转换系统,并使用来自我之前博客帖子中介绍的事件检测和通知系统

如架构图中所示。步骤 3 的警报消息发布到 Amazon SNS 主题,该 SNS 触发我们文本到语音转换系统中的 Lambda 函数。

  1. 此 Lambda 函数解析 SNS 警报消息的主题,并使用 Amazon Polly 将文本转换为语音文件。
  2. 此语音文件存储在 Amazon S3 存储桶中。
  3. Twilio 使用语音文件的位置,对相关方进行出站呼叫并播放语音文件。请注意,您可以根据在使用语音文件进行出站呼叫之后的需求,为这些文件添加 Amazon S3 对象生命周期策略

演示

先决条件

  • 至少有一个事件检测和通知系统。例如,您可以设置对 AWS 账户根用户活动进行监视和通知
  • 您将需要 Twilio 账户身份验证令牌来进行 API 调用。您可在此处注册免费 (试用) Twilio 账户。
  • 会向您的 Twilio 账户分配一个电话号码。这是您接听电话呼叫报警时的主叫号码。
  • 如果您使用的是试用账户,则需要确保对“被叫”电话号码进行验证。

部署步骤

以下部署步骤将部署“文本到语音转换”系统,如下图中所示。

  1. 在 AWS CloudFormation 控制台中,选择 Create Stack。使用 CloudFormation JSON 模板 。选择 Next。(注意:中国和 AWS GovCloud (美国) 区域不支持 Amazon Polly。)
  2. 在要部署事件检测和通知系统的区域中创建堆栈。
  3. 输入以下参数详细信息,选择 Next,然后选择 Next
    1. ToPhoneNo:Twilio 将拨打的电话号码。在电话号码前面加上“+国家/地区代码”,例如 +14561237890。
    2. FromPhoneNo:Twilio 进行呼叫时所用的虚拟电话号码。在您的 Twilio 账户中可以找到此信息。请参阅“先决条件”部分。
    3. TwilioAccntSid:输入 Twilio 账户 SID。当您在 https://www.twilio.com/ 上注册时提供此项
    4. TwilioAuthToken:输入 Twilio 身份验证令牌 ID。
    5. BucketName:输入您要创建的存储桶的名称。此存储桶将存储事件警报的语音文件。
    6. PollyVoiceId:输入您希望呼入警报的 Amazon Polly 语音。默认语音为“Amy”。
    7. LambdaS3Bucket:存储 Lambda 函数 zip 文件的 Amazon S3 存储桶的名称。
    8. LambdaS3Key:Lambda 函数 zip 文件的名称。这是 S3 对象的完整路径,带有前缀。例如,“dir1/dir2/lambdafunction.zip”。Lambda 函数 zip 文件可以从此博客帖子的 Lambda 函数部分中的链接下载。
  4. 依次选择 Capabilities AcknowledgementCreate。此字段向堆栈提供权限来创建 IAM 角色和策略。这些角色和策略由 Lambda 函数用于执行特定操作,例如发布消息到 SNS 主题、列出账户别名等等。
  5. CloudFormation 堆栈完成之后,检查 output 中提供的 Lambda 函数名
  6. 现在,我们将触发器添加到此 Lambda 函数。转到 Lambda 控制台并选择刚刚创建的 Lambda 函数,然后选择 triggersadd trigger
  7. 在触发器框中,选择 SNS,并选择您希望用于电话呼叫的“事件检测和通知”系统的 SNS 主题。选择 Submit
  8. 现在,Lambda 函数已准备好,可由您的“事件检测和通知”系统的 SNS 主题触发。您可以根据需要,为各种事件检测和通知系统添加任意数量的触发器。在此处可以找到有关触发 AWS Lambda 的更多信息。

SNS 触发 Lambda 函数

在触发时,文本语音转换 Lambda 函数会解析 SNS 消息的主题。然后,它将此主题字段文本传递到 Amazon Polly 服务以将其转换为语音文件。将文本转换为语音文件之后,该文件存储在前一部分中由 CloudFormation 堆栈创建的 S3 存储桶内。

然后,它调用 Twilio API 进行电话呼叫,并播放来自 S3 存储桶的事件通知音频文件。

import boto3
import os
from contextlib import closing
import botocore.session
from botocore.exceptions import ClientError
session = botocore.session.get_session()
import logging
import uuid
import twilio
from twilio.rest import Client

import urllib
from urllib import request, parse
from urllib.parse import quote

logging.basicConfig(level=logging.DEBUG)
logger=logging.getLogger(__name__)

def lambda_handler(event, context):
    logger.setLevel(logging.DEBUG)
    logger.debug("Event is --- %s" %event)
    speak = event["Records"][0]["Sns"]["Subject"]
	
	# 将 SNS 消息的主题文本转换为 mp3 语音文件。
	
    polly = boto3.client('polly')
    response = polly.synthesize_speech( OutputFormat='mp3',
                                        Text = 'ALERT !' + speak,
                                        SampleRate='22050',
                                        VoiceId = os.environ['VoiceId']  
                                        )
    logger.debug("Polly Response is-- %s" %response)
    id = str(uuid.uuid4())
    logger.debug("ID= %s" %id)
    
    
    # 将 Amazon Polly 返回的语音流保存到 Lambda 的临时
    # 目录。如果有多个文本块,语音流
    # 将合并为单个文件。
    if "AudioStream" in response:
        with closing(response["AudioStream"]) as stream:
            filename=id + ".mp3"
            output = os.path.join("/tmp/",filename)
            with open(output, "wb") as file:
                file.write(stream.read())
	
	# 将语音 MP3 文件上传到 S3位置
	
    s3 = boto3.client('s3')
    s3upload_response = s3.upload_file('/tmp/' + filename, os.environ['BUCKET_NAME'],filename,ExtraArgs={"ContentType": "audio/mp3"})
    logger.debug("S3 UPLOAD RESPONSE IS--- %s" %s3upload_response)
    s3.put_object_acl(ACL='public-read', Bucket=os.environ['BUCKET_NAME'], Key= filename)
    
    location = s3.get_bucket_location(Bucket=os.environ['BUCKET_NAME'])
    logger.debug("Location response is -- %s" %location)
    region = location['LocationConstraint']
    
    if region is None:
    	url_begining = "https://s3.amazonaws.com/"
    else:
    	url = url_begining + str(os.environ['BUCKET_NAME']) + "/" + filename
    
    url = '{}/{}/{}'.format(s3.meta.endpoint_url, os.environ['BUCKET_NAME'], filename)
    
    #编码 URL
    encode_url = quote(url, safe='')
    logger.debug("ENCODED URL-- %s" %encode_url)
    
    # 从 http://twilio.com/user/account 获取这些凭证
    account_sid = os.environ['account_sid']
    auth_token = os.environ['auth_token']
    client = Client(account_sid, auth_token)
    
    # 使用 Twilio 进行电话呼叫
    call_response = client.api.account.calls.create(to=os.environ['ToPhoneNo'],  # 任意电话号码
    												from_=os.environ['FromPhoneNo'], # 必须是有效的 Twilio 号码
    												url="http://twimlets.com/message?Message%5B0%5D=" + encode_url + "&"
    												)
    												
    logger.debug("Call_response is-- %s" %call_response)

此 AWS Lambda 代码 zip 文件可从此处下载并用于 CloudFormation 堆栈部署。

解决方案验证

在接下来的示例语音中,我将演示在部署事件检测系统 (就根 API 活动进行通知) 并将其集成到文本到语音转换系统之后,每次在 AWS 账户上检测到根 API 时,我将收到电话呼叫报警。

由根触发的控制台登录警报电话呼叫示例:

立即收听

语音由 Amazon Polly 提供

然后,我使用根凭证创建 Amazon EBS 卷并获取另一个电话呼叫警报。

立即收听

语音由 Amazon Polly 提供

结论

在这篇帖子中,我演示了如何创建电话呼叫音频警报系统,该系统可集成到现有的警报和监视系统中。针对 AWS 账户中的关键事件,此框架在获取近乎实时的电话呼叫警报方面非常有用。

如需进一步了解,建议阅读以下内容:


作者简介

Sudhanshu Malhotra 在 AWS 专业服务团队担任解决方案架构师。Sudhanshu 乐于与客户协作,帮助他们在 AWS 中提供开发运营、基础设施即代码和配置管理等领域的复杂解决方案。在业余时间,Sudhanshu 喜欢与家人共享天伦之乐、徒步旅行和改装汽车。