Как реализовать TLS между микросервисами

Может ли кто-нибудь прокомментировать, проверить, покритиковать или иным образом заполнить дыры в дизайне безопасности микросервисов, который я рассматриваю?

Допустим, у меня есть три микросервиса, каждый из которых общается с двумя другими через конечные точки REST. Каждый микросервис содержит хранилище ключей. В этом хранилище ключей содержится пара закрытый/открытый ключ микросервиса, подписанная доверенным центром сертификации. Также в этом хранилище ключей находятся сертификаты открытых ключей двух других микросервисов, экспортированные из пары подписанных/доверенных ключей исходного микросервиса.

Эта реализация работает, но что-то в ней не совсем пахнет.

А именно, каждый раз, когда я ввожу новую микрослужбу, я должен добавить а) сертификат открытого ключа каждой существующей микрослужбы в его хранилище ключей и б) сертификат открытого ключа новой микрослужбы в каждую другую микрослужбу (предполагается, что новая микрослужба должна взаимодействовать в двух направлениях, и безопасно, с каждым существующим микросервисом).

Теперь повторите приведенный выше шаблон для второй пары ключей, которая используется для подписи/проверки токенов аутентификации, предоставленных в вызовах REST.

Мне интересно, если вместо вышеперечисленного а) целесообразно и б) безопасно использовать один доверенный сертификат открытого ключа между всеми микросервисами? Что-то совсем другое?

Пожалуйста, будьте вежливы. Я ни в коем случае не специалист в этой области.

РЕДАКТИРОВАТЬ: после прочтения ответов/комментариев к моему исходному сообщению мне пришло в голову, что я упустил детали, которые могли бы сделать проблему более ясной, и, следовательно, комментаторы могли лучше решить ее:

  1. Рассматриваемые микросервисы существуют в частной интрасети и будут доступны только клиентам (браузерам или другим микросервисам) в этой интрасети.

  2. На самом деле существует доверенный ЦС, а именно компания, которой принадлежит эта интрасеть, и именно этот ЦС подписывает пары ключей микросервисов.

Решение этой проблемы, кажется, подразумевается в первом комментарии @Andreas, в котором он написал: «Пока ЦС, выпустивший их, является доверенным, им тоже будут доверять».

Пока каждый новый микросервис развертывается с а) собственными парами ключей, подписанными ЦС (один для подписи, а другой для шифрования) и б) сертификатом ЦС, я могу развертывать новые микросервисы с разумной уверенностью, что они будут безопасно взаимодействовать с все остальные микросервисы (разумные из-за других потенциальных уязвимостей, о которых я даже не знаю).

Каким-то образом мне пришло в голову, что мне придется создать новый сертификат для каждой пары ключей микросервиса и включить их в хранилища ключей других микросервисов (повторить для каждого нового микросервиса). Вместо этого все, что мне нужно, — это один сертификат центра сертификации, который подписывает пары ключей, в хранилище ключей каждого микросервиса.


person divaconhamdip    schedule 17.05.2018    source источник
comment
Зачем вам нужно добавлять общедоступный сертификат каждой службы? Пока выдавший их ЦС является доверенным, им тоже будут доверять. Так устроена сама сеть, так почему бы это не сработать для вас?   -  person Andreas    schedule 18.05.2018
comment
Спасибо, что использовали TLS, а не что-то еще, что все используют по ошибке, но, пожалуйста, удалите его из тега. А также java и tls1.2, т.к. ваш вопрос не специфичен для этих случаев.   -  person Patrick Mevzek    schedule 18.05.2018
comment
@Andreas, который плохо работает, когда вам нужно аутентифицировать клиента (для аутентификации сервера это легко). Сервер должен заранее немного знать о сертификате или использовать частную PKI, иначе любой может предъявить любой сертификат, подписанный любым центром сертификации.   -  person Patrick Mevzek    schedule 18.05.2018
comment
Если вы можете, полагайтесь на инфраструктуру для обеспечения безопасной связи. Например, если вы используете Docker Swarm, вы можете активировать шифрование соединения для сети: docs.docker.com/network/overlay/   -  person Constantin Galbenu    schedule 18.05.2018
comment
Шифрование @ConstantinGalbenu не является взаимной аутентификацией   -  person Marged    schedule 19.05.2018


Ответы (2)


Один из способов сделать это (ваш вопрос широк, и без кода он может быть более актуальным для SoftwareEngineering, чем здесь) заключается в следующем:

  1. создать свой ЦС
  2. (необязательно, создайте суб-ЦС только для своих микросервисов)
  3. генерировать все сертификаты этим ЦС
  4. сделать так, чтобы ваш код доверял всем сертификатам от этого CA, вместо того, чтобы проверять сам сертификат (но вы все равно должны проверять даты, правильность подписи и т. д.)

Таким образом, когда вы вводите новую микрослужбу, у вас есть только один сертификат для нее, и ничего не нужно менять в других микрослужбах, что является целью, которую вы должны достичь, иначе ею нельзя будет управлять.

Делая это таким образом, вы даже можете перемещать некоторые из ваших микросервисов за пределы ваших систем, если это необходимо. Их просто нужно отправить с открытым ключом CA.

Я бы не советовал повторно использовать один и тот же сертификат для разных микросервисов, так как это приведет только к проблемам.

Кроме того, слабо связано, но обязательно прочитайте это: https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf показывает различные подводные камни при использовании TLS за пределами Интернета. Это открытие. Этот Internet-Draft (https://datatracker.ietf.org/doc/draft-gutmann-tls-lts/) может дать полезную информацию о том, как правильно реализовать TLS1.2 с некоторыми безопасными вариантами по умолчанию. Часть «LTS» конкретно означает «Долгосрочная поддержка».

Посмотрите также на этот связанный вопрос: https://security.stackexchange.com/questions/175627/securing-internal-micro-services-letsencrypt-vs-self-signed-certificates-be и ответ, дающий вам другие идеи, такие как использование хранилища.

person Patrick Mevzek    schedule 17.05.2018
comment
Вау, спасибо за отличную ссылку. Не могу дождаться, чтобы прочитать это. Я уверен, что это полностью разрушит мой подход. Вы попали в самую точку: использование TLS за пределами Интернета меня немного сбивает с толку. - person divaconhamdip; 18.05.2018

Если ваши микросервисы не доступны в Интернете, вы можете создать для этой цели самоподписанные сертификаты. Самоподписанные сертификаты используются для внутренних вызовов. Вы можете создать их на сайте sslshopper.

Кроме того, не используйте одни и те же сертификаты для всех микросервисов. Я реализовал аналогичное решение, в нашем случае мы настроили подписанную службу как другую микрослужбу, которая будет обслуживать другие микрослужбы. Эта самоподписанная служба будет подключаться к модулям HSM или аппаратной безопасности. Все сертификаты хранятся внутри принадлежащих HSM. к профилям. Вы можете погуглить HSM и создать его профиль.

Хранилища доверия используются для хранения общедоступных сертификатов, а хранилища ключей используются для хранения закрытых ключей. Это стандарт, а не универсальный, но в идеальном сценарии.

person Ankur Srivastava    schedule 18.05.2018