Наши сетевые требования гласят, что ВСЕ сетевой трафик должен быть зашифрован.
Конфигурация сети выглядит так:
------------
/-- https --> | server 1 |
/ ------------
|------------| |---------------|/ ------------
| Client | --- https --> | Load Balancer | ---- https --> | server 2 |
|------------| |---------------|\ ------------
\ ------------
\-- https --> | server 3 |
------------
И он должен передавать клиентские сертификаты.
У меня есть конфигурация, которая может выполнять балансировку нагрузки с явными реальными серверами:
<VirtualHost *:8666>
DocumentRoot "/usr/local/apache/ssl_html"
ServerName vmbigip1
ServerAdmin jscheible@goeis.com
DirectoryIndex index.html
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLEngine on
SSLProxyEngine On
SSLCertificateFile /usr/local/apache/conf/server.crt
SSLCertificateKeyFile /usr/local/apache/conf/server.key
<Proxy balancer://mycluster>
BalancerMember http://1.2.3.1:80
BalancerMember http://1.2.3.2:80
# technically we aren't blocking anyone, but could here
Order Deny,Allow
Deny from none
Allow from all
# Load Balancer Settings
# A simple Round Robin load balancer.
ProxySet lbmethod=byrequests
</Proxy>
# balancer-manager
# This tool is built into the mod_proxy_balancer module allows you
# to do simple mods to the balanced group via a gui web interface.
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
ProxyRequests Off
ProxyPreserveHost On
# Point of Balance
# Allows you to explicitly name the location in the site to be
# balanced, here we will balance "/" or everything in the site.
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/ stickysession=JSESSIONID
</VirtualHost>
Мне нужно, чтобы серверы в моем балансировщике нагрузки были
BalancerMember https://1.2.3.1:443
BalancerMember https://1.2.3.2:443
Но это не работает. Я получаю ошибки согласования SSL.
Даже когда я заставлю это работать, мне нужно будет передать сертификаты клиентов.
Любая помощь будет оценена.
Ты просто не может использовать клиентский сертификат напрямую с внутренним узлом, который будет запрашивать сертификат пользователя и где балансировщик нагрузки «разорвет» соединение SSL / TLS от конечного пользователя.
Рукопожатие SSL / TLS с сертификатом клиента требует, чтобы клиент подписал все сообщения рукопожатия, которыми обмениваются клиент и сервер в конце, что означает, что клиент должен быть подключен непосредственно к фактическому серверу SSL / TLS, запрашивающему сертификат клиента. Если соединение SSL / TLS браузера идет только до балансировщика нагрузки, именно балансировщик нагрузки является клиентом для внутреннего узла. Внутренний узел увидит другое рукопожатие, и это не удастся.
Есть два возможных способа обойти это:
Используйте балансировщик нагрузки на основе DNS или TCP (например, что-то вроде ipchains
): в этом случае соединение SSL / TLS из браузера будет идти непосредственно к внутреннему узлу. Возможна прямая аутентификация по сертификату клиента.
Пусть балансировщик нагрузки выполнит проверку подлинности сертификата клиента и просто передаст эту информацию внутреннему узлу. Для этого требуется, чтобы серверный узел доверял балансировщику нагрузки, чтобы он правильно выполнил проверку, но если внутренний узел не может доверять балансировщику нагрузки, нет смысла его использовать.
mod_proxy_ajp
(или mod_jk
) может пересылать сертификат клиента как часть протокола AJP, но это в основном для контейнеров Java, и трафик AJP в любом случае не зашифрован.
Если вы используете mod_proxy_http
, вы можете добавить дополнительный заголовок с помощью mod_header
передать сертификат через заголовок HTTP, используя что-то вроде RequestHeader set X-ClientCert %{SSL_CLIENT_CERT}s
. Я не могу вспомнить точные детали, но важно убедиться, что этот заголовок очищен, чтобы он никогда не поступал из браузера клиента (который мог бы подделать его в противном случае). Какое бы приложение вы ни запускали на внутреннем узле, оно должно иметь возможность получать информацию об аутентификации из этого заголовка (и доверять ему как уже проверенному балансировщиком нагрузки).
В добавок к SSLVerifyClient
и SSLCACertificateFile/Path
директивы, которые необходимо настроить для нормальной проверки подлинности сертификата клиента на Apache Httpd с mod_ssl
, вам также необходимо настроить SSLProxyCheckPeerCN on
и SSLProxyCACertificateFile/Path
для настройки Apache Httpd в качестве клиента SSL / TLS для внутренних узлов (см. введение mod_proxy
документация, о SSLProxy*
директивы).
Если вы хотите, чтобы внутренние серверы были уверены, что запрос поступает от балансировщика нагрузки, а не от другого клиента (который может установить прямое соединение), вы можете заставить балансировщик нагрузки также использовать сертификат клиента (используя SSLProxyMachineCertificateFile
), чтобы аутентифицироваться на внутренней заметке. Обратите внимание, что это может сделать систему аутентификации на бэкэнде не более сложной: хотя фактическая аутентификация сертификата клиента, которую они получают, будет аутентификацией прокси (которую им нужно будет проверить, как обычно), приложения на этих серверы должны быть настроены на использование клиентского сертификата на основе заголовка, что касается пользователей приложений.
Ваша конфигурация SSL выглядит неполной. Для запроса клиентских сертификатов вам необходимо добавить
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile <your CA cert file>
Видеть Как заставить клиентов проходить аутентификацию с помощью сертификатов для подробностей.
Не уверен, что это обязательно, но вам также не хватает SSLCipherSuite директива. Если так поступить, вы сможете отсортировать слабые шифры и сделать все возможное против ЗВЕРЬ атака:
SSLHonorCipherOrder On
SSLCipherSuite RC4-SHA:ALL:!ADH:!EXPORT:!LOW:!MD5:!SSLV2:!NULL
Я хотел бы добавить в эту ветку, если у кого-то есть подобные проблемы. У меня были проблемы с такой настройкой, BigIP, выходящий на httpd 2.4 с SSLVerifyClient в файлах httpd ssl.conf.
Для меня это иногда срабатывало, а иногда - нет, у меня периодически прерывались соединения при съемке запросов из SoapUI, даже несмотря на то, что моя конфигурация была правильно настроена.
Проблема заключалась в том, что в BigIP была настроена сохраняемость сеанса на основе файлов cookie, что и вызывало эту ошибку. Как только мы все вместе отключили постоянство сеанса, он начал работать правильно.
Обратите внимание, что в моем случае BigIP - это маршрутизация балансировки нагрузки уровня 4, без разгрузки TLS, просто стандартная балансировка нагрузки циклического перебора и позволяющая экземплярам httpd обрабатывать проверку сертификата клиента.