Статьи

Межсервисная связь с использованием аутентификации сертификата клиента

SSL - Безопасность золота Допустим, у нас есть сервис, такой как Google. У нас есть почтовое приложение и социальное приложение. Оба имеют возможность добавлять события в расписание. Мы не хотим заходить в почтовое приложение, чтобы увидеть оттуда события, добавленные в расписание, а затем переключиться на социальное приложение, чтобы увидеть события, добавленные оттуда. Вместо этого у нас есть другое приложение расписания, которое содержит все наши события из обоих приложений.

Эта сервис-ориентированная архитектура хороша, но как проверить, что клиент (запросчик) имеет разрешение на доступ к сервису? В этом случае приложение электронной почты имеет разрешение на создание событий в приложении расписания.

Введите SSL.

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

Сертификаты SSL имеют пару ключей (открытый и закрытый ключ) и тему, которая является личностью владельца сертификата / веб-сайта. Обычно предмет сертификата SSL будет содержать имя домена, название организации, адрес, город, штат и страну. В нем также будет указана дата истечения срока действия сертификата и сведения о центре сертификации, ответственном за выдачу сертификата. ( ПРИМЕЧАНИЕ . Все, что зашифровано с помощью закрытого ключа сертификатов, может быть расшифровано только с помощью открытого ключа и наоборот.)

Этот сертификат также используется для подтверждения того, что веб-сайт является тем, кем они говорят.
Наиболее распространенная ситуация — это браузер, показывающий значок замка, который сообщает пользователю, что личность веб-сайта подтверждена. Поскольку SSL-сертификат можно использовать для проверки того, кем является сервер, то мы должны иметь возможность использовать тот же подход для проверки клиента.

Типичный поток SSL для браузера и веб-сайта.

Центр сертификации: Verisign, Godaddy, DigiCert и т. Д.
Клиент: Браузер
Сервис: Сайт

  • Центр сертификации (ЦС) создает сертификат. Это ИХ сертификат, который используется для подтверждения личности ЦС.
  • Сервис создает CSR (Запрос на подпись сертификата). CSR будет иметь подробную информацию о личности веб-сайта и компании.
  • Служба затем отправит этот CSR в CA для подтверждения.
  • CA будет проверять детали в CSR.
  • CA использует свой сертификат для цифровой подписи CSR (запроса на подпись сертификата). Это создает сертификат SSL, который затем выдается службой.

Когда Клиент подключается к Сервису, он устанавливает зашифрованную ссылку с использованием SSL-сертификата. Клиент также пытается подтвердить личность Сервиса. Для этого Клиент получает SSL-сертификат от Службы и проверяет, что срок его действия не истек, используется для домена, который был выдан, и был выдан Центром сертификации, которому доверяет Клиент (Verisign, Godaddy, DigiCert, и т.д). Клиент хранит список всех сертификатов от CA, которым он доверяет, и сравнивает их с CA, который поставляется с SSL-сертификатом. (Примечание. Браузер решает, каким центрам сертификации он будет доверять, но вы также можете добавить свой собственный в браузер. Таким образом, ваш браузер доверяет самозаверяющему сертификату, например.)

Вместо того, чтобы Клиент хотел проверить личность Сервиса, мы хотим сделать наоборот.

Примечание. В первоначальном примере клиентом будет приложение электронной почты / социальной сети, а службой — приложение «Расписание».

Настройка SSL-аутентификации

Первое, что нам нужно сделать, это создать центр сертификации (сейчас мы являемся нашим собственным центром сертификации). Это будет использоваться для подписания CSR клиента. Поскольку мы все обращаем вспять, клиент выдает CSR вместо Сервиса.

Ниже описано, как сгенерировать закрытый ключ и запрос сертификата, а затем подписать сертификат самостоятельно.

openssl genrsa -out ca.key 1024
openssl req -new -key ca.key -out ca.csr
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

Затем вам нужно будет скопировать файл ca.crt в вашу Службу. Это наш список доверенных центров сертификации, состоящий только из нас.

Если вы используете apache, вам нужно установить параметры в файле httpd.conf :

 ...
SSLCACertificateFile /path/to/cacert/ca.crt
SSLVerifyClient require
...

Проверьте сайт Apache для получения дополнительной информации о других опциях.

Для NGINX добавьте следующее в файл nginx.conf :

 http {
    server {
      ……...

     ssl_client_certificate /path/to/cacert/ca.crt;
     ssl_verify_client    on;

     ……..
   }
}

Посетите сайт nginx , чтобы узнать больше вариантов.

Каждому клиенту потребуется собственный сертификат SSL. Клиент создаст CSR и отправит запрос в центр сертификации (который является нами).

Сгенерируйте закрытый ключ (в данном случае client.key) и запрос сертификата для клиента.

 openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr

Затем подпишите запрос, используя сертификат Центра сертификации и ключ, который мы создали (ca.crt, ca.key), и верните подписанный сертификат.

 openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

Теперь, когда клиент делает запрос в службу, он должен передать client.crt

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

 request = Faraday::Connection.new https://schedule.com, :ssl => {
      :verify => false,
      :client_cert => OpenSSL::X509::Certificate.new(File.read(/path/to/mail_client.crt)),
      :client_key => OpenSSL::PKey::RSA.new(File.read(/path/to/mail_client.key)),
    }
    request.headers['Accept'] = 'application/json'
    request.headers['Content-Type'] = 'application/json'
    response = request.post "/events", {event: {start_time:"2013-08-01T16:20:00+00:00", end_time:"2013-08-01T18:20:00+00:00", name:"Meeting"}}.to_json

:verify Если установлено значение true:ca_file => 'path/to/cafile' ca_file Если вы купили свой SSL-сертификат у Godaddy, вам нужно будет загрузить сертификат CA, который они использовали для создания вашего SSL-сертификата. (У них есть список здесь ).

Почему этот подход тогда вместо базового auth или oauth? Самое главное, что сервис не должен ничего делать при добавлении большего количества клиентов. Новый клиент просто создаст CSR и запросит SSL-сертификат у того же центра сертификации.

Изначально пришла идея из этого
Коллективная идея статьи.

Мы довольно рано в нашем подходе, но пока, это выглядит очень многообещающе.