<!--StartFragment-->
[Amazon WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 是一种托管的、安全的桌面即服务 (DaaS) 解决方案。默认情况下,[Amazon WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 允许用户从任何国家登录, 不提供地理限制功能。 这可能并不适用于一些有安全考量的客户。当用户从未经批准的国家连接时,顾客希望被告知或者限制用户登录,这个概念称为地理封锁。
[Amazon Workspaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 当前不支持地理封锁/阻止黑名单连接。此博客文章提供了一个示例, 我们将创建一个黑名单规则,该规则将拒绝访问位于澳大利亚的 IP 地址。而此解决方案涉及一个 Amazon Cloudwatch 事件,该事件触发 Amazon Lambda 函数。函数检查 IP 位置来源,如果源 IP 位置来自黑名单区域,则该 Amazon Lambda 执立即关闭 WorkSpace。
下面说明如何部署解决方案:
当用户成功登录到 [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 时, [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 登录事件发送到 CloudWatch Events
此 CloudWatch Event 可用于触发 Lambda 函数(用 Python 编写),该 Lambda 函数执行以下操作:
* 使用公共 API 执行源 IP 地址的 IP 查找,以获取源 IP 地址的位置
* 如果返回的位置在“列入黑名单”的区域中,则该 Lambda 函数尝试停止 WorkSpace
[![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/amazon-workspaces-automatically-detects-logins-from-blacklisted-countries1.png)](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/amazon-workspaces-automatically-detects-logins-from-blacklisted-countries1.jpg)\
该解决方案部署了以下亚马逊云科技资源:
* 适用于 [Amazon WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 登录的 CloudWatch 事件
* 由 CloudWatch 事件触发的 Lambda 函数
* IAM 执行角色来向函数提供运行所需的权限
我们可以利用 Amazon CloudFormation 部署 Lambda 函数:
`AWSTemplateFormatVersion: '2010-09-09'`
`Transform: AWS::Serverless-2016-10-31`
`Description: Lambda function to validate Workspaces client connections`
`Resources:`
`ValidateWorkspaceSource:`
`Type: AWS::Serverless::Function`
`Properties:`
`Handler: validate_workspace_source.lambda_handler`
`Runtime: python3.7`
`Description: Validate source connections of Workspace launches`
`MemorySize: 256`
`Timeout: 600`
`Environment:`
`Variables:`
`IP_LOOKUP_URL: https://extreme-ip-lookup.com/json/`
`BLACKLISTED_REGIONS: Australia`
`SLEEP_DURATION: '30'`
`RETRY_LIMIT: '10'`
`Events:`
`WorkSpacesAccessEvent:`
`Type: CloudWatchEvent`
`Properties:`
`Pattern:`
`source:`
`- aws.workspaces`
`detail-type:`
`- WorkSpaces Access`
`Policies:`
`- ReadOnlyAccess`
`- Version: '2012-10-17'`
`Statement:`
`- Effect: Allow`
`Action:`
`- logs:CreateLogGroup`
`- logs:CreateLogStream`
`- logs:PutLogEvents`
`- workspaces:StopWorkspaces`
`- sns:Publish`
`Resource: '*'`
`Outputs:`
`LambdaArn:`
`Description: Lambda Arn`
`Value:`
`Ref: ValidateWorkspaceSource`
`Export:`
`Name: validate-workspace-source-lambda-arn`
以下是 Lambda 函数:
首先导入 json, boto3, requests, time, OS。
Lambda 函数具有以下环境变量:
| 环境变量 | 说明 |
| ------------------- | --------------------------------- |
| IP_LOOKUP_URL | 用于检索有关源 IP 地址的信息 |
| BLACKLISTED_REGIONS | 用逗号隔开的黑名单国家列表(例如,澳大利亚,新西兰) |
| SLEEP_DURATION | Lambda 函数在尝试再次关闭 [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 之前应休眠的秒数 |
| RETRY_LIMIT | Lambda 函数应尝试关闭工作区的次数 |
确保 SLEEP_DURATION 和 RETRY_LIMIT 值在 Lambda 函数的超时值之内。
`import json`
`import boto3`
`import requests`
`import time`
`import os`
`workspaces_client = boto3.client('workspaces')`
`ip_lookup_url = os.environ['IP_LOOKUP_URL']`
`blacklisted_regions = list(os.environ['BLACKLISTED_REGIONS'].split(","))`
`workspace_stop_success = False`
`sleep_duration = int(os.environ['SLEEP_DURATION'])`
`retry_limit = int(os.environ['RETRY_LIMIT'])`
以下代码获取 [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 启动事件和 WorkSpaces IP 地址。然后查找 API 以获取源 IP 地址的位置, 如果源 IP 地址的位置在黑名单国家中, Lambda 函数自动关闭用户的 [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail)。
`def lambda_handler(event, context):`
`source_ip_address = (event['detail']['clientIpAddress'])`
`complete_ip_lookup_url = ip_lookup_url + str(source_ip_address)`
`# Get Workspace launch event`
`workspaces_response = workspaces_client.describe_workspaces(`
`WorkspaceIds=[event['detail']['workspaceId']`
`])`
`print ("Cloudwatch Event triggered....")`
`print (event)`
`print ("Workspace Information....")`
`print (workspaces_response)`
`print ("Source ip address:",source_ip_address)`
`# Lookup API to obtain the location of the source ip address`
`print ("Invoking API:",complete_ip_lookup_url)`
`ip_lookup = requests.get(complete_ip_lookup_url)`
`ip_lookup_result = ip_lookup.json()`
`source_ip_country = ip_lookup_result['country']`
`print ("Source ip country:",source_ip_country)`
`# If the location of the source ip address is in a blacklisted region`
`if source_ip_country in blacklisted_regions:`
`stop_workspace(event)`
`else:`
`print ("User has logged in from a safe region")`
`print (ip_lookup_result)`
`return 'End Function'`
以下函数将尝试关闭 [WorkSpaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail),尝试直到成功停止或达到重试限制为止。
`def stop_workspace(event):`
`print ("Warning! User is logging in from blacklisted region")`
`# Try to stop the Workspace until either the stop attempt is succesfull or until the retry limit specified`
`for i in range (retry_limit):`
`print ("Attempting to stop Workspace attempt", i)`
`stop_workspace_response = workspaces_client.stop_workspaces(`
`StopWorkspaceRequests=[`
`{`
`'WorkspaceId': event['detail']['workspaceId']`
`}])`
`# if workspace stop attempt is succesfull, exit the loop`
`if (stop_workspace_response["FailedRequests"]) == []:`
`workspace_stop_success = True`
`print (stop_workspace_response)`
`break`
`# else if the workspace stop attempt is not succesfull`
`else:`
`print ("Stop Request Failed")`
`print (stop_workspace_response)`
`# pause the function for the duration specified before attempting to stop the Workspace again`
`time.sleep(sleep_duration)`
`if workspace_stop_success:`
`print ("Succesfully stopped Workspace")`
`elif not workspace_stop_success:`
`print ("Stop request failed after",retry_limit*sleep_duration,"seconds")`
`return workspace_stop_success`
### **最后总结**
入侵检测可以采取多种形式。通过 IP 地理位置数据检测,可以识别用户和计算机的地理位置。
自动检测来自黑名单国家的登录,最主要的目的是帮助客户降低安全风险。 关闭 [Workspaces](https://aws.amazon.com/cn/ec2/?trk=cndc-detail) 是阻止用户登录的一种方法。客户可以利用其他选择,例如 利用 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) Alarm 在发生海外黑名单登录时第一时间通知管理员, 管理员再进行调查, 或向用户发送电子邮件通知用户,告知用户并确认用户是否在黑名单国家/地区进行登录活动。
<!--EndFragment-->