Проверить источник HTTP-запроса

У меня две системы, которые нужно поговорить. Системы настроены:

System A , запускающая Django (Python 2.5) в Google App Engine (GAE)

System B , запускающая Django (Python 2.6) на Ubuntu / Linux поверх Lighttpd (возможно, nginx, позже)

Система A будет периодически делать запросы («заявки») системы B с использованием Url Fetch .

Система B имеет приложение Django для прослушивания этих запросов с urls.py с чем-то вроде:

 urlpatterns = patterns('producer.views', url(r'^requisition$', 'requisition', name='requisition'), ) 

И соответствующий views.py с чем-то вроде:

 import json from django.http import HttpResponse def requisition(request): " do something " response = HttpResponse() response['Content-type'] = 'application/json' response.write(json.dumps(...)) return response 

Это было бы ценным дополнением к безопасности системы, если система B ответила на заявки только из системы A.

Я хотел бы знать, какие опции доступны для системы B, чтобы проверить, что запросы поступают из системы A. Я рассмотрел следующее:

  • Убедитесь, что IP-адрес имеет значение GAE (однако я не знаю IP-адреса GAE, они могут меняться, и они могут быть подделаны)
  • Убедитесь, что обратный DNS IP от GAE (однако я не знаю, какие записи DNS GAE, если они будут меняться, и они могут быть подделаны)
  • Использовать сертификат клиента TLS из System A, но я не знаю, как это сделать с помощью GAE
  • Сделайте вызов / ответ на основе чего-то общего, например соли, с помощью pycrypto

В идеале я хочу получить views.py с чем-то подобным:

 ... from django.http import HttpResponseForbidden def requisition(request): " do something " if not verify_request_origin(): return HttpResponseForbidden("Denied.") response = HttpResponse() ... 

Где verify_request_origin () возвращает true, когда запрос, отправленный в System B был из System A в GAE.

Спасибо, и я с нетерпением жду ваших мыслей.

Вы находитесь на месте, первые два пулевых пункта бесполезны.

Пароль, как говорит Андрей, достаточно хорош, если вы не беспокоитесь о проблемах с кешами браузера. Если вы тогда, вы все равно должны использовать SSL, но для аутентификации одного приложения другому через, например, hmac , и использовать его для создания общего секрета для сеанса. Секрет должен находиться в коде, а не переданных данных.

Похоже, что было бы достаточно использовать SSL по ссылке и включить пароль в строку запроса.

SSL хранит снифферы, и вы не собираетесь раскрывать запросы за пределами систем под вашим контролем, поэтому общий секрет будет (и будет более безопасным, чем IP-отслеживание, поскольку другие сайты GAE будут использовать эти адреса).

Система A может отправлять HTTPS-запросы через urlfetch.fetch – просто введите параметр URL с https:// . Однако это не аутентифицирует его в системе B (это предотвращает снифферы и атаки «человек-в-середине»); нет возможности использовать клиентский сертификат TLS.

Проверка того, что запрос поступает от GAE (что было бы вполне осуществимо: просто используйте собственный DNS-сервер Google в 8.8.8.8 – если кому-то удастся установить собственный DNS Google, их способность обмануть вашу систему B будет наименьшей из беспокоит 😉 не помогает ни по одной и той же причине: это может быть любое приложение GAE (все они разделяют кучу IP-адресов, и данный IP-адрес может использоваться любым количеством приложений GAE в течение короткого периода времени ).

Поэтому шифрование полезной нагрузки общим секретом кажется простейшим из-за ограничений GAE. PyCrypto – возможно, с exPyCrypto впереди – может быть хорошо; или, возможно, вы захотите попробовать SlowAES (у меня, конечно, слабое место для последнего ;-).

Один вариант проверки пули – это посмотреть на FOAF + SSL http://www.w3.org/wiki/Foaf%2Bssl/FAQ#What_is_FOAF.2BSSL