Nginx Proxy передает сертификат аутентификации в MS IIS

Nginx 1.9.5 (linux Centos7) -> MS IIS 8.5 Поэтому я пытаюсь использовать nginx в качестве обратного прокси-сервера для IIS, где требуется проверка подлинности сертификата клиента на уровне IIS. nginx: 443 - >> IIS: 443 + аутентификация сертификата клиента.

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

location ^~ /test/ {
#proxy_buffering off;
#proxy_http_version 1.0;
#proxy_request_buffering off;
#proxy_set_header Connection "Keep-Alive";
#proxy_set_header X-SSL-CERT $ssl_client_cert;
# proxy_ssl_name domain.lv;
#proxy_ssl_trusted_certificate /etc/nginx/ssl/root/CA.pem;
#proxy_ssl_verify_depth 2;

proxy_set_header HOST domain.com;
proxy_ssl_certificate /etc/nginx/ssl/test.pem;
proxy_ssl_certificate_key /etc/nginx/ssl/test_key.pem;
proxy_ssl_verify off;
proxy_pass https://10.2.4.101/;

 }

У IIS все просто.

  1. создать новый сайт.
  2. импортировать сертификат CA в доверенный корень.
  3. установить требуемый сертификат ssl.

Проверьте, что я получаю:

  1. Требуется напрямую браузер для сертификата клиента IIS - работал.
  2. Требуется сертификат Nginx для другого клиента nginx - работал.
  3. Nginx для игнорирования сертификата клиента IIS - работал
  4. Требуется сертификат клиента Nginx для IIS или принимается - НЕ работает

ОШИБКА: сторона Nginx: * 4622 тайм-аут восходящего потока (110: тайм-аут соединения) при чтении заголовка ответа со стороны восходящего потока IIS: 500 0 64 119971

Надеюсь, кто-нибудь знает, почему?

РЕДАКТИРОВАТЬ 1. также попробуйте с другого сервера с nginx 1.8 ничего не помогло ..

proxy_ssl_verify off;
proxy_ssl_certificate /etc/nginx/ssl/test/test.pem;
proxy_ssl_certificate_key /etc/nginx/ssl/test/test_key.pem;
proxy_pass https://domain.com;

2. попробуйте то же самое с apache 2.4, все работало с

SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
SSLProxyMachineCertificateFile /etc/httpd/ssl/test.pem
ProxyPass "/test" "https://domain.com"

Может что то с пересогласованием ssl в nginx ???


person Agris    schedule 25.10.2015    source источник


Ответы (1)


Ваша догадка насчет повторного согласования TLS верна. Nginx не разрешает повторное согласование TLS с версии 0.8.23 (см. http://nginx.org/en/CHANGES). Однако по умолчанию IIS будет использовать повторное согласование TLS при запросе сертификата клиента. (Причин найти не удалось - был бы признателен, если бы кто-нибудь меня просветил!)

Вы можете использовать анализатор пакетов, такой как wirehark, чтобы увидеть это в действии:

  1. IIS и Nginx сначала выполняют квитирование TLS, используя только сертификат сервера.
  2. Nginx запрашивает ресурс.
  3. Ресурс требует аутентификации клиента, поэтому IIS отправляет сообщение Hello Request в Nginx, чтобы инициировать повторное согласование TLS.
  4. Nginx не отвечает на запрос Hello, поскольку повторное согласование TLS отключено.
  5. Затем IIS закрывает соединение, поскольку не получает ответа. (См. Раздел о повторных переговорах на странице https://technet.microsoft.com/en-us/library/cc783349(v=ws.10).aspx)

Чтобы решить эту проблему, вы должны заставить IIS запрашивать сертификат клиента при первоначальном рукопожатии TLS. Вы можете сделать это с помощью утилиты netsh из PowerShell или командной строки:

  1. Откройте командную строку PowerShell с правами администратора.
  2. Введите netsh
  3. Введите http
  4. Введите show sslcert. Вы должны увидеть список всех текущих привязок SSL на вашем компьютере:

netsh http show sslcert output

  1. Запишите IP: порт и хэш сертификата сертификата, для которого вы хотите включить согласование сертификата клиента. Теперь мы собираемся удалить эту привязку и снова добавить ее, установив для свойства Negotiate Client Certificate значение enabled. В этом примере IP: порт - 0.0.0.0:44300, а хэш сертификата - 71472159d7233d56bc90cea6d0c26f7a29db1112.
  2. Введите delete sslcert ipport=[IP:port from above]
  3. Введите add sslcert ipport=[IP:port from above] certhash=[certificate hash from above] appid={[any random GUID (can be the same one from the show sslcert output)]} certstorename=MY verifyclientcertrevocation=enable verifyrevocationwithcachedclientcertonly=disable clientcertnegotiation=enable
  4. Теперь вы можете подтвердить, что это сработало, снова запустив show sslcert. Вы должны увидеть почти идентичный результат, но для сертификата клиента Negotiate установлено значение Включено:

введите описание изображения здесь

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

person Dave C    schedule 10.01.2016
comment
Большое спасибо. Это РАБОТАЕТ. это то, что я хотел получить на работу. У меня уже был установлен apache между iis и nginx для временного разрешения. Если кому-то это нужно для указания имени сервера, измените некоторые строки текста Дейва, удалите sslcert hostnameport = domain.com: 443, добавьте sslcert hostnameport = domain.com: 443. - person Agris; 11.01.2016
comment
IIS запрашивает сертификат после повторного согласования, поскольку администратор может сделать клиентские сертификаты обязательными для подмножества ресурсов на сервере, оставив все другие ресурсы незащищенными. Следовательно, имеет смысл запрашивать сертификат только тогда, когда известно имя ресурса. - person gfv; 16.08.2016