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

时间:2022-03-23 23:47:50

I am hoping to use Amazon's Elasticsearch server to power a search of longtext fields in a Django database. However, I also don't want to expose this search to those who don't have a log in and don't want to rely on security through obscurity or some IP restriction tactic (unless it would work well with an existing heroku app, where the Django app is deployed).

我希望使用亚马逊的Elasticsearch服务器来支持Django数据库中的longtext字段的搜索。但是,我也不想将此搜索公开给那些没有登录并且不想通过默默无闻或某些IP限制策略依赖安全性的人(除非它适用于现有的heroku应用程序,部署Django应用程序的地方)。

Haystack seems to go a long way toward this, but there doesn't seem to be an easy way to configure it to use Amazon's IAM credentials to access the Elasticsearch service. This functionality does exist in elasticsearch-py, whichi it uses.

Haystack似乎对此有很大帮助,但似乎没有一种简单的方法来配置它来使用Amazon的IAM凭证来访问Elasticsearch服务。这个功能确实存在于elasticsearch-py中,它使用它。

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

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())

Regarding using HTTP authorization, I found this under issues at https://github.com/django-haystack/django-haystack/issues/1046

关于使用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,
        }
    }
}

I am wondering if there is a way to combine these two, something like the following (which, as expected, gives an error since it's more than just a user name and password):

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

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
        }
    },
}

The error here:

这里的错误:

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

Any ideas on how to accomplish this?

有关如何实现这一目标的任何想法?

2 个解决方案

#1


8  

You are one step from success, add connection_class to KWARGS and everything should work as expected.

你是成功的一步,将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,
        }
    },
}

#2


0  

AWS Identity and Access Management (IAM) allows you to manage users and user permissions for AWS services, to control which AWS resources users of AWS itself can access.

AWS身份和访问管理(IAM)允许您管理AWS服务的用户和用户权限,以控制AWS自身的用户可以访问的AWS资源。

You cannot use IAM credentials to authorize users at the application level via http_auth, as it appears you are trying to do via Haystack here. They are different authentication schemes for different services. They are not compatible.

您无法使用IAM凭据通过http_auth在应用程序级别对用户进行授权,因为您在此处尝试通过Haystack进行操作。它们是针对不同服务的不同认证方案。它们不兼容。

In your security use case, you have stated the need to 1) restrict access to your application, and 2) to secure the Elasticsearch service port from open access. These two requirements can be met using the following methods:

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

Restrict access to your application

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

I also don't want to expose this search to those who don't have a log in

我也不想将此搜索公开给那些没有登录的人

For the front-end search app, you want to use a server level Basic access authentication (HTTP auth) configuration on the web server. This is where you want to control user login access to your app, via a standard http_auth username and password (again, not IAM). This will secure your app at the application level.

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

Secure the Elasticsearch service port

保护Elasticsearch服务端口

don't want to rely on security through obscurity or some IP restriction tactic (unless it would work well with an existing heroku app, where the Django app is deployed).

不想通过默默无闻或一些IP限制策略来依赖安全性(除非它适用于部署Django应用程序的现有heroku应用程序)。

IP restriction is exactly what would work here, and consistent with AWS security best practices. You want to use security groups and security group rules as a firewall to control traffic for your EC2 instances.

IP限制正是在这里工作的,并且与AWS安全最佳实践一致。您希望将安全组和安全组规则用作防火墙来控制EC2实例的流量。

Given a Haystack configuration of:

鉴于Haystack配置:

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

you will want to implement an IP restriction at the security group and/or ACL level on that IP and port 127.0.0.1, to restrict access from only your Django host or other authorize hosts. This will secure it from any unauthorized access at the service level.

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

In your implementation, the URL will likely resolve to a public or private IP, depending on your network architecture.

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

#1


8  

You are one step from success, add connection_class to KWARGS and everything should work as expected.

你是成功的一步,将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,
        }
    },
}

#2


0  

AWS Identity and Access Management (IAM) allows you to manage users and user permissions for AWS services, to control which AWS resources users of AWS itself can access.

AWS身份和访问管理(IAM)允许您管理AWS服务的用户和用户权限,以控制AWS自身的用户可以访问的AWS资源。

You cannot use IAM credentials to authorize users at the application level via http_auth, as it appears you are trying to do via Haystack here. They are different authentication schemes for different services. They are not compatible.

您无法使用IAM凭据通过http_auth在应用程序级别对用户进行授权,因为您在此处尝试通过Haystack进行操作。它们是针对不同服务的不同认证方案。它们不兼容。

In your security use case, you have stated the need to 1) restrict access to your application, and 2) to secure the Elasticsearch service port from open access. These two requirements can be met using the following methods:

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

Restrict access to your application

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

I also don't want to expose this search to those who don't have a log in

我也不想将此搜索公开给那些没有登录的人

For the front-end search app, you want to use a server level Basic access authentication (HTTP auth) configuration on the web server. This is where you want to control user login access to your app, via a standard http_auth username and password (again, not IAM). This will secure your app at the application level.

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

Secure the Elasticsearch service port

保护Elasticsearch服务端口

don't want to rely on security through obscurity or some IP restriction tactic (unless it would work well with an existing heroku app, where the Django app is deployed).

不想通过默默无闻或一些IP限制策略来依赖安全性(除非它适用于部署Django应用程序的现有heroku应用程序)。

IP restriction is exactly what would work here, and consistent with AWS security best practices. You want to use security groups and security group rules as a firewall to control traffic for your EC2 instances.

IP限制正是在这里工作的,并且与AWS安全最佳实践一致。您希望将安全组和安全组规则用作防火墙来控制EC2实例的流量。

Given a Haystack configuration of:

鉴于Haystack配置:

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

you will want to implement an IP restriction at the security group and/or ACL level on that IP and port 127.0.0.1, to restrict access from only your Django host or other authorize hosts. This will secure it from any unauthorized access at the service level.

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

In your implementation, the URL will likely resolve to a public or private IP, depending on your network architecture.

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