从 Lambda 访问 ElasticSearch 的权限?
Permissions to access ElasticSearch from Lambda?
我正在尝试使用 Elasticsearch 为连接到 Alexa Skills Kit 的 Lambda 函数存储数据。 Lambda 在没有 Elasticsearch 的情况下工作正常,但 ES 提供了急需的模糊匹配。
我能够从 Lambda 访问它的唯一方法是启用 Elasticsearch 全局访问,但这是一个非常糟糕的主意。我还能够通过开放访问策略或 IP 地址策略从我的计算机进行访问。有没有办法通过 Lambda 进行只读访问并通过 IP 进行读写?
在 IAM 上,我授予了我的 Lambda 角色 AmazonESReadOnlyAccess。在 ES 方面,我尝试了这个,但它只适用于 IP 地址:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::NUMBER:root",
"arn:aws:iam::NUMBER:role/lambda_basic_execution"
]
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:NUMBER:domain/NAME/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:NUMBER:domain/NAME/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "MY IP"
}
}
}
]
}
这个 forum post 问了同样的问题,但没有人回答。
我知道的唯一方法是在您的 ES 域上使用基于资源的策略或基于 IAM 的策略。这将限制对特定 IAM 用户或角色的访问。但是,要完成这项工作,您还需要使用 SigV4 将您的请求签署到 ES。
有些库可以为您完成此签名,例如 this one 扩展了流行的 Python 请求库以通过 SigV4 对 ElasticSearch 请求进行签名。我相信其他语言也存在类似的库。
AWS Lambda 在 public EC2 实例上运行。因此,简单地将 IP 地址白名单添加到 Elasticsearch 访问策略是行不通的。一种方法是向 Lambda 执行角色授予对 Elasticsearch 域的适当权限。确保 Lambda 执行角色对 ES 域具有权限,并且 ES 域访问策略具有允许此 Lambda 角色 ARN 执行适当操作的语句。一旦完成,您所要做的就是在访问 ES 端点时通过 SigV4 签署您的请求
希望对您有所帮助!
对于您的 Elasticsearch 集群的外部(AWS 外部)访问,您希望创建具有基于 IP 的访问策略的集群。类似下面的内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"<<IP/CIDR>>"
]
}
},
"Resource": "arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
}
]
}
对于您的 Lambda 函数,使用以下策略片段创建 Lambda 函数将承担的角色。
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:DescribeElasticsearchDomain",
"es:DescribeElasticsearchDomains",
"es:DescribeElasticsearchDomainConfig",
"es:ESHttpPost",
"es:ESHttpPut"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:ESHttpGet"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_all/_settings",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_cluster/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/<<INDEX>>*/_mapping/<<TYPE>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes/*/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/<<INDEX>>*/_stats"
]
}
我认为您可以更轻松地将上述两个政策声明浓缩为以下内容:
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:DescribeElasticsearchDomain",
"es:DescribeElasticsearchDomains",
"es:DescribeElasticsearchDomainConfig",
"es:ESHttpPost",
"es:ESHttpGet",
"es:ESHttpPut"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
]
}
我设法从以下来源拼凑了以上内容:
您需要进入Lambda的访问策略并提供AWS ARN进行连接
现在可以从您的代码中使用 elasticsearch.js. Before you try it, you must install http-aws-es 模块。
const AWS = require('aws-sdk');
const httpAwsEs = require('http-aws-es');
const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
host: 'YOUR_ES_HOST',
connectionClass: httpAwsEs,
amazonES: {
region: 'YOUR_ES_REGION',
credentials: new AWS.EnvironmentCredentials('AWS')
}
});
// client.search({...})
当然,在使用之前,配置elasticsearch域的访问权限:
我正在尝试使用 Elasticsearch 为连接到 Alexa Skills Kit 的 Lambda 函数存储数据。 Lambda 在没有 Elasticsearch 的情况下工作正常,但 ES 提供了急需的模糊匹配。
我能够从 Lambda 访问它的唯一方法是启用 Elasticsearch 全局访问,但这是一个非常糟糕的主意。我还能够通过开放访问策略或 IP 地址策略从我的计算机进行访问。有没有办法通过 Lambda 进行只读访问并通过 IP 进行读写?
在 IAM 上,我授予了我的 Lambda 角色 AmazonESReadOnlyAccess。在 ES 方面,我尝试了这个,但它只适用于 IP 地址:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::NUMBER:root",
"arn:aws:iam::NUMBER:role/lambda_basic_execution"
]
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:NUMBER:domain/NAME/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:NUMBER:domain/NAME/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "MY IP"
}
}
}
]
}
这个 forum post 问了同样的问题,但没有人回答。
我知道的唯一方法是在您的 ES 域上使用基于资源的策略或基于 IAM 的策略。这将限制对特定 IAM 用户或角色的访问。但是,要完成这项工作,您还需要使用 SigV4 将您的请求签署到 ES。
有些库可以为您完成此签名,例如 this one 扩展了流行的 Python 请求库以通过 SigV4 对 ElasticSearch 请求进行签名。我相信其他语言也存在类似的库。
AWS Lambda 在 public EC2 实例上运行。因此,简单地将 IP 地址白名单添加到 Elasticsearch 访问策略是行不通的。一种方法是向 Lambda 执行角色授予对 Elasticsearch 域的适当权限。确保 Lambda 执行角色对 ES 域具有权限,并且 ES 域访问策略具有允许此 Lambda 角色 ARN 执行适当操作的语句。一旦完成,您所要做的就是在访问 ES 端点时通过 SigV4 签署您的请求
希望对您有所帮助!
对于您的 Elasticsearch 集群的外部(AWS 外部)访问,您希望创建具有基于 IP 的访问策略的集群。类似下面的内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"<<IP/CIDR>>"
]
}
},
"Resource": "arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
}
]
}
对于您的 Lambda 函数,使用以下策略片段创建 Lambda 函数将承担的角色。
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:DescribeElasticsearchDomain",
"es:DescribeElasticsearchDomains",
"es:DescribeElasticsearchDomainConfig",
"es:ESHttpPost",
"es:ESHttpPut"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:ESHttpGet"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_all/_settings",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_cluster/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/<<INDEX>>*/_mapping/<<TYPE>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_nodes/*/stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/_stats",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/<<INDEX>>*/_stats"
]
}
我认为您可以更轻松地将上述两个政策声明浓缩为以下内容:
{
"Sid": "",
"Effect": "Allow",
"Action": [
"es:DescribeElasticsearchDomain",
"es:DescribeElasticsearchDomains",
"es:DescribeElasticsearchDomainConfig",
"es:ESHttpPost",
"es:ESHttpGet",
"es:ESHttpPut"
],
"Resource": [
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>",
"arn:aws:es:<<REGION>>:<<ACCOUNTID>>:domain/<<DOMAIN_NAME>>/*"
]
}
我设法从以下来源拼凑了以上内容:
您需要进入Lambda的访问策略并提供AWS ARN进行连接
现在可以从您的代码中使用 elasticsearch.js. Before you try it, you must install http-aws-es 模块。
const AWS = require('aws-sdk');
const httpAwsEs = require('http-aws-es');
const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
host: 'YOUR_ES_HOST',
connectionClass: httpAwsEs,
amazonES: {
region: 'YOUR_ES_REGION',
credentials: new AWS.EnvironmentCredentials('AWS')
}
});
// client.search({...})
当然,在使用之前,配置elasticsearch域的访问权限: