机遇与挑战
搜索无处不在。无论是在电子商务、社交媒体还是视频应用中,搜索都发挥了举足轻重的作用。搜索作为信息的入口,能够帮助用户快速从海量信息中找到想要的内容,极大地提高了终端用户的使用体验。Amazon OpenSearch(Amazon ElasticSearch) 提供了一个高度可扩展的系统,使用户可以有效地探索他们的数据, 从而快速而轻松地实现业务需求。
但是同时我们知道,安全性是您应用程序的首要任务。安全几乎贯穿了产品研发的每一个环节,作为产品架构设计人员,开发,运维人员,使用系统级别的安全防护手段,可以有效的提高产品的安全性。在本文中,我们将向您介绍如何使用 Amazon VPC,Amazon KMS,Amazon Lambda 以及Amazon OpenSearch(Amazon ElasticSearch) 保护您的数据。
操作步骤
建立VPC,并创建公有子网和私有子网
步骤 1: 为您的 NAT 网关创建弹性 IP 地址
NAT 网关需要您的公有子网中的弹性 IP 地址
- 打开 Amazon VPC 控制台。
- 在左侧导航窗格中,选择Elastic IPs。
- 选择分配
步骤 2: 运行 VPC 向导
VPC 向导 是一个简单的工具,可以帮助您创建具有公有和私有子网的 VPC,以及VPC相关资源,包括安全组、路由表、NAT 网关。
- 打开 Amazon VPC 控制台。
- 在左侧导航窗格中,选择 VPC 仪表板,然后单击橙色按钮 Launch VPC Wizard。
- 在左侧选择 VPC with Public and Private Subnets。
- 点击 Select
- 填写表格,设置如下图所示。 您可以使用任何您喜欢的 IP 地址,并输入您刚刚分配的弹性 IP。
- 选择创建vpc。
- 可以看到VPC向导创建的如下资源
- 创建更多子网可以有效提高高可用性,这部分内容在本文中就不进行展开,您可以参考下文进行了配置
Tutorial: Creating a VPC with Public and Private Subnets for Your Clusters.
步骤 3: 配置安全组规则
- 在左侧导航窗格中,选择安全组。 可以找到刚刚创建的安全组。
- 对于安全组,按照如下配置编辑入站规则,使其只接受 VPC 内特定端口的安全流量。
创建IAM role
创建 Lambda 函数将使用的角色(IAM Role)。 我们稍后创建好ElasticSearch 域后,会将策略附加到该角色。
使用 VPC 和 KMS 加密创建 ElasticSearch 域
- 打开 OpenSearch Service(Amazon Elasticsearch Service)控制台。
- 选择创建新域。
- 在选择开发类型中,选择开发和测试,因为我们不在生产中,只在一个可用区中创建了一个子网。 对于生产中的多个可用区,子网数必须与可用区数相同。
- 对于版本,选择 Elasticsearch 7.10
- 选择下一步。
- 输入域的名称。 此域名将成为您的 VPC 终端节点的一部分。
- 选择下一步。
- 选择VPC接入
- 对于 VPC,选择您创建的 VPC。
- 对于子网,选择您创建的私有子网。
- 使用 MyESRole 设置访问控制
- 对于 Access Control Policy, 选择JSON defined access policy.
输入如下策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::670164030314:role/MyESRole"
]
},
"Action": [
"es:ESHttpGet",
"es:ESHttpPost",
"es:ESHttpPut",
"es:ESHttpDelete"
],
"Resource": "arn:aws:es:us-west-1:670164030314:domain/my-es-domain/*"
}
]
14. 选择启用节点到节点加密和启用静态数据加密 和使用 AWS KMS Key。}
创建IAM 策略
- 创建 ElasticSearch 域后,您可以为 Lambda 函数创建策略以允许访问 ElasticSearch 域并执行操作。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"es:ESHttpPost",
"es:ESHttpGet",
"es:ESHttpDelete",
"es:ESHttpPut"
],
"Resource": "arn:aws:es:us-west-2:XXXXXXXXXXXX:domain/my-es-domain"
}
]
}
- 为 Lambda 创建策略以设置 VPC。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeNetworkInterfaces"
],
"Resource": "*"
}
]
}
- 为 Lambda 日志创建策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-west-1:670164030314:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-west-1:670164030314:log-group:/aws/lambda/my-es-lambda-function:*"
]
}
]
}
- 将上述策略附加到您之前创建的 IAM 角色(IAM ROLE)
在VPC中创建lambda
我们将在 VPC 中创建一个简单的 Python lambda 函数来在 ElasticSearch 上执行操作。
- 打开 Lambda 控制台,选择创建函数
- 对于运行时,选择 Python 3.8
- 选择 Change default execution role,选择您创建的 IAM 角色
- 在网络部分,对于 VPC,选择您创建的 VPC。
- 对于子网,选择您创建的公有子网。 在生产中,建议您在多个可用区中创建多个子网以获得高可用性。
- 对于安全组,选择您创建的安全组。 您可以看到入站规则和出站规则。
测试与验证
- 所需依赖
requirements.txt
boto3==1.12.39
requests==2.23.0
requests-aws4auth==0.9
- 上传数据
示例代码:
import json
import requests
import boto3
from requests_aws4auth import AWS4Auth
def lambda_handler(event, context):
region = "us-west-1"
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
host = "https://vpc-my-es-domain-6kw5zu33hepvneqdsgeqhjqphu.us-west-1.es.amazonaws.com"
index = "test-index"
url =host + '/' + index+ '/_doc/1'
headers = { "Content-Type": "application/json" }
input ={
"product": "toy",
"price": 5,
"description": "dog toy"
}
r = requests.put(url, auth=awsauth, headers=headers, data=json.dumps(input))
return {
'statusCode': 200,
'body': json.loads(r.content)
}
示例返回:
{
"statusCode": 200,
"body": {
"_index": "test-index",
"_type": "_doc",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
}
3. 搜索文件
示例代码:
import json
import requests
import boto3
from requests_aws4auth import AWS4Auth
def lambda_handler(event, context):
region = "us-west-1"
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
host = "https://vpc-my-es-domain-6kw5zu33hepvneqdsgeqhjqphu.us-west-1.es.amazonaws.com"
index = "test-index"
url =host + '/' + index+ '/_search'
headers = { "Content-Type": "application/json" }
query = {
"size": 250,
"query": {
"query_string": {
"query": "toy"
}
}
}
r = requests.post(url, auth=awsauth, headers=headers, data=json.dumps(query))
return {
'statusCode': 200,
'body': json.loads(r.content)
}
示例返回:
{
"statusCode": 200,
"body": {
"took": 658,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "test-index",
"_type": "_doc",
"_id": "1",
"_score": 0.2876821,
"_source": {
"product": "toy",
"price": 5,
"description": "dog toy"
}
}
]
}
}
}
总结:
本文通过网络层面的隔离,身份控制,安全组的加入,以及数据加密等方式,去管理和保护我们的数据,这是对应用程序和网站安全来说非常重要且有效的手段。但是,这仅仅只是冰山的一角,安全性是一项需要投入持续努力的工作。在您的开发和部署过程中,安全的重要性怎么强调都不为过。
希望本文可以帮助您,了解和掌握安全方面的一些知识,有效的提升和解决环境中的安全问题和隐患。
本篇作者