Django-Haystack 使用带有 IAM 凭证的 Amazon Elasticsearch 托管

Posted

技术标签:

【中文标题】Django-Haystack 使用带有 IAM 凭证的 Amazon Elasticsearch 托管【英文标题】:Django-Haystack using Amazon Elasticsearch hosting with IAM credentials 【发布时间】:2016-05-07 13:21:34 【问题描述】:

我希望使用 Amazon 的 Elasticsearch 服务器来支持在 Django 数据库中搜索长文本字段。但是,我也不想将这个搜索暴露给那些没有登录并且不想通过默默无闻或某些 IP 限制策略来依赖安全性的人(除非它可以很好地与现有的 heroku 应用程序一起使用,部署 Django 应用程序的位置)。

Haystack 在这方面似乎走了很长一段路,但似乎没有一种简单的方法可以将其配置为使用 Amazon 的 IAM 凭证来访问 Elasticsearch 服务。此功能确实存在于它使用的 elasticsearch-py 中。

https://elasticsearch-py.readthedocs.org/en/master/#running-with-aws-elasticsearch-service

from elasticsearch import Elasticsearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth

host = 'YOURHOST.us-east-1.es.amazonaws.com'
awsauth = AWS4Auth(YOUR_ACCESS_KEY, YOUR_SECRET_KEY, REGION, 'es')

es = Elasticsearch(
    hosts=['host': host, 'port': 443],
    http_auth=awsauth,
    use_ssl=True,
    verify_certs=True,
    connection_class=RequestsHttpConnection
)
print(es.info())

关于使用 HTTP 授权,我在 https://github.com/django-haystack/django-haystack/issues/1046 的问题下发现了这一点

from urlparse import urlparse
parsed = urlparse('https://user:pass@host:port')
HAYSTACK_CONNECTIONS = 
    'default': 
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': parsed.hostname,
        'INDEX_NAME': 'haystack',
        'KWARGS': 
            'port': parsed.port,
            'http_auth': (parsed.username, parsed.password),
            'use_ssl': True,
        
    

我想知道是否有一种方法可以将这两者结合起来,如下所示(正如预期的那样,它会给出错误,因为它不仅仅是用户名和密码):

from requests_aws4auth import AWS4Auth
awsauth = AWS4Auth([AACCESS_KEY],[SECRET_KEY],[REGION],'es')


HAYSTACK_CONNECTIONS = 
    'default': 
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': [AWSHOST],
        'INDEX_NAME': 'haystack',
        'KWARGS': 
            'port': 443,
            'http_auth': awsauth,
            'use_ssl': True,
            'verify_certs': True
        
    ,

这里的错误:

TypeError at /admin/
must be convertible to a buffer, not AWS4Auth

Request Method:     GET
Request URL:    http://127.0.0.1:8000/admin/
Django Version:     1.7.7
Exception Type:     TypeError
Exception Value:    

must be convertible to a buffer, not AWS4Auth

Exception Location:     /usr/lib/python2.7/base64.py in b64encode, line 53

关于如何实现这一点的任何想法?

【问题讨论】:

您是否尝试使用 AWS 凭证根据您的私有 ElasticSearch 实施对用户进行身份验证? 我为应用程序创建了一个 Amazon IAM 用户。我只希望那些可以访问该应用程序的人能够使用它向 Elasticsearch 服务器提交请求。所以只需要一个 AWS 凭证。 【参考方案1】:

您离成功仅一步之遥,将connection_class 添加到KWARGS,一切都会按预期进行。

import elasticsearch

HAYSTACK_CONNECTIONS = 
    'default': 
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': [AWSHOST],
        'INDEX_NAME': 'haystack',
        'KWARGS': 
            'port': 443,
            'http_auth': awsauth,
            'use_ssl': True,
            'verify_certs': True,
            'connection_class': elasticsearch.RequestsHttpConnection,
        
    ,

【讨论】:

请注意,我还没有在我的应用程序中使用 Haystack 的功能,但它确实解决了我在那个阶段遇到的问题。谢谢!【参考方案2】:

AWS Identity and Access Management (IAM) 允许您管理 AWS 服务 的用户和用户权限,以控制 AWS 本身的用户可以访问哪些 AWS 资源。

您不能使用 IAM 凭证通过 http_auth 在应用程序级别授权用户,因为您似乎正在尝试通过 Haystack 执行此操作。它们是针对不同服务的不同身份验证方案。它们不兼容。

在您的安全用例中,您已声明需要 1) 限制对您的应用程序的访问,以及 2) 保护 Elasticsearch 服务端口不被开放访问。这两个要求可以通过以下方法来满足:

限制对您的应用程序的访问

我也不想将这个搜索暴露给没有登录的人

对于前端搜索应用,您希望在 Web 服务器上使用服务器级别的 Basic access authentication(HTTP 身份验证)配置。这是您希望通过标准 http_auth 用户名和密码(同样,不是 IAM)控制用户登录访问您的应用程序的地方。这将在应用程序级别保护您的应用程序。

保护 Elasticsearch 服务端口

不想通过默默无闻或其他方式依赖安全性 IP 限制策略(除非它适用于现有的 heroku 应用程序,部署 Django 应用程序的位置)。

IP 限制正是在这里可以发挥作用的,并且符合 AWS 安全最佳实践。您想使用security groups and security group rules 作为防火墙来控制您的 EC2 实例的流量。

给定一个 Haystack 配置:

HAYSTACK_CONNECTIONS = 
    'default': 
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': 'http://127.0.0.1:9200/',
        'INDEX_NAME': 'haystack',
    ,

您将希望在该 IP 和端口 127.0.0.1 上的安全组和/或 ACL 级别实施 IP 限制,以限制仅来自您的 Django 主机或其他授权主机的访问。这将保护它免受服务级别的任何未经授权的访问。

在您的实施中,该 URL 可能会解析为公共或私有 IP,具体取决于您的网络架构。

【讨论】:

谢谢罗德里戈。有没有理由我不想将这些信息保存在我的 Heroku 配置变量中,然后将它们传递给视图,然后将请求发送到亚马逊?似乎这应该适用于限制访问,因为我可以要求用户登录才能访问搜索页面。 你打赌@Serioushouse 我不知道 Heroku 100% 并且不确定你是如何配置你的配置变量的。我知道它在 AWS 上运行。上述配置是执行这些类型的安全云实施的标准方式。什么类型的 http 服务器正在运行搜索应用程序?你在那里试过 http_auth 吗?

以上是关于Django-Haystack 使用带有 IAM 凭证的 Amazon Elasticsearch 托管的主要内容,如果未能解决你的问题,请参考以下文章

django-haystack插件

带有 iam_role 的 AWS Redshift COPY

如何使用带有 IAM 凭证的 psql 客户端访问 Amazon AWS Redshift

django-haystack全文检索

遇到502重新安装django-haystack

如何将django-haystack搜索方面与自定义属性一起使用?