6

Spero di utilizzare il server Elasticsearch di Amazon per alimentare una ricerca di campi longtext in un database Django. Tuttavia, non voglio nemmeno esporre questa ricerca a coloro che non hanno un accesso e non vogliono fare affidamento sulla sicurezza attraverso l'oscurità o qualche tattica di restrizione IP (a meno che non funzioni bene con un'app di heroku esistente, dove viene distribuita l'app Django).Django-Haystack utilizzando Amazon Elasticsearch hosting con credenziali IAM

Haystack sembra fare molto per questo, ma non sembra essere un modo semplice per configurarlo per utilizzare le credenziali IAM di Amazon per accedere al servizio Elasticsearch. Questa funzionalità esiste in elasticsearch-py, che usa.

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

Per quanto riguarda utilizzando l'autorizzazione HTTP, ho trovato questo sotto questioni in https://github.com/django-haystack/django-haystack/issues/1046

from urlparse import urlparse 
parsed = urlparse('https://user:[email protected]: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, 
     } 
    } 
} 

Mi chiedo se c'è un modo per unire questi due, qualcosa di simile a quanto segue (che , come previsto, dà un errore poiché è più di un semplice nome utente e 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 
     } 
    }, 
} 
.210

L'errore qui:

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 

Tutte le idee su come ottenere questo risultato?

+0

Stai tentando di utilizzare le credenziali AWS per autenticare gli utenti contro l'implementazione privata di ElasticSearch? –

+0

Ho creato un utente Amazon IAM per l'app. Voglio che solo coloro che possono accedere all'app possano utilizzarlo per inviare richieste al server Elasticsearch. Quindi è necessaria una sola credenziale AWS. – Serioushouse

risposta

8

Sei ad un passo dal successo, aggiungi connection_class a KWARGS e tutto dovrebbe funzionare come previsto.

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

Nota che non ho ancora utilizzato le funzionalità di Haystack nella mia app, ma ha risolto il problema che avevo riscontrato in quella fase. Grazie! – Serioushouse

0

AWS Identity and Access Management (IAM) consente di gestire gli utenti e le autorizzazioni utente per i servizi AWS, per controllare quali risorse AWS possono accedere gli utenti di AWS.

Non è possibile utilizzare le credenziali IAM per autorizzare gli utenti a livello di applicazione tramite http_auth, come sembra si stia tentando di fare tramite Haystack qui. Sono diversi schemi di autenticazione per diversi servizi. Non sono compatibili.

Nel caso di utilizzo della protezione, è stato necessario 1) limitare l'accesso alla propria applicazione e 2) per proteggere la porta del servizio Elasticsearch dall'accesso aperto. Queste due esigenze possono essere soddisfatte utilizzando i seguenti metodi:

limitare l'accesso alla propria applicazione

Anche io non voglio esporre questa ricerca a coloro che non hanno un registro in

Per l'app di ricerca front-end, si desidera utilizzare una configurazione del server Basic access authentication (autenticazione HTTP) sul server Web. Qui è dove si desidera controllare l'accesso di accesso utente alla propria app, tramite un nome utente e una password standard http_auth (di nuovo, non IAM). Ciò garantirà la tua app a livello di applicazione.

Fissare la porta di servizio elasticsearch

non vogliono fare affidamento sulla sicurezza attraverso l'oscurità o qualche IP restrizione tattica (a meno che non avrebbe funzionato bene con un app Heroku esistente, dove il Django app è schierato).

La restrizione IP è esattamente ciò che funzionerebbe qui e coerente con le best practice di sicurezza di AWS. Si desidera utilizzare security groups and security group rules come firewall per controllare il traffico delle istanze EC2.

Data una configurazione di Haystack di:

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

si vuole attuare una restrizione IP al gruppo di protezione e/o il livello di ACL su quel IP 127.0.0.1 e la porta, per limitare l'accesso da solo il tuo Django host o altri host autorizzati. Questo lo proteggerà da qualsiasi accesso non autorizzato a livello di servizio.

Nella tua implementazione, l'URL probabilmente si risolverà in un IP pubblico o privato, a seconda dell'architettura di rete.

+0

Grazie Rodrigo. C'è una ragione per cui non vorrei salvare quell'informazione nella mia Heroku config vars e quindi passarle a una vista che poi invia la richiesta ad Amazon? Sembra che dovrebbe funzionare per limitare l'accesso, perché posso richiedere agli utenti di accedere per visitare la pagina di ricerca. – Serioushouse

+0

Hai scommesso su @Serioushouse che non conosco Heroku al 100% e non sono sicuro di come hai configurato la tua configurazione. So che funziona su AWS. La configurazione di cui sopra è il modo standard per eseguire questi tipi di implementazioni cloud sicure. Che tipo di server http sta eseguendo l'app di ricerca? Hai provato http_auth lì? –