机遇与挑战
 
       搜索无处不在。无论是在电子商务、社交媒体还是视频应用中,搜索都发挥了举足轻重的作用。搜索作为信息的入口,能够帮助用户快速从海量信息中找到想要的内容,极大地提高了终端用户的使用体验。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"
                }
                }
            ]
        }
    }
}
 
         
        
 
       总结:
 
       本文通过网络层面的隔离,身份控制,安全组的加入,以及数据加密等方式,去管理和保护我们的数据,这是对应用程序和网站安全来说非常重要且有效的手段。但是,这仅仅只是冰山的一角,安全性是一项需要投入持续努力的工作。在您的开发和部署过程中,安全的重要性怎么强调都不为过。
 
       希望本文可以帮助您,了解和掌握安全方面的一些知识,有效的提升和解决环境中的安全问题和隐患。
 
        
 
       本篇作者