Обратный прокси-сервер Nginx проходит через сертификат клиента

Я пытаюсь настроить балансировщик нагрузки через обратный прокси-сервер Nginx. Мое приложение использует клиентские сертификаты для аутентификации клиентов. Я хочу, чтобы обратный прокси-сервер пересылал сертификат клиента на мои внутренние серверы. Я добавил эту строку в конфигурацию обратного прокси-сервера для хранения информации о сертификате клиента в настраиваемом HTTP-заголовке:

proxy_set_header X-SSL-CERT $ssl_client_cert

Однако $ ssl_client_cert использует несколько строк для хранения сертификата, и мой внутренний сервер nginx не распознает это должным образом как один HTTP-заголовок. Как лучше всего пересылать мои клиентские сертификаты?

Этот вопрос задавали в 2013 году на этом форуме, но пока нет реального решения: https://forum.nginx.org/read.php? 2,236546,236546

Спасибо!

3
задан 9 July 2016 в 18:52
5 ответов

Итак, я нашел решение. Я удаляю все символы новой строки в сертификате и отправляю их как один HTTP-заголовок с прокси на серверную часть, как описано здесь:

https://forum.nginx.org/read.php?2,236546, 236546

В моем сервере я восстанавливаю сертификат, добавляя новую строку каждые 64 символа. Обновленный код для обратного прокси-сервера выглядит следующим образом и работает до 26 строк:

map $ssl_client_raw_cert $a {
   "~^(-.*-\n)(?<st>[^\n]+)\n((?<b>[^\n]+)\n)?((?<c>[^\n]+)\n)?((?<d>[^\n]+)\n)?((?<e>[^\n]+)\n)?((?<f>[^\n]+)\n)?((?<g>[^\n]+)\n)?((?<h>[^\n]+)\n)?((?<i>[^\n]+)\n)?((?<j>[^\n]+)\n)?((?<k>[^\n]+)\n)?((?<l>[^\n]+)\n)?((?<m>[^\n]+)\n)?((?<n>[^\n]+)\n)?((?<o>[^\n]+)\n)?((?<p>[^\n]+)\n)?((?<q>[^\n]+)\n)?((?<r>[^\n]+)\n)?((?<s>[^\n]+)\n)?((?<t>[^\n]+)\n)?((?<v>[^\n]+)\n)?((?<u>[^\n]+)\n)?((?<w>[^\n]+)\n)?((?<x>[^\n]+)\n)?((?<y>[^\n]+)\n)?((?<z>[^\n]+)\n)?(-.*-)$" $st;
}

server {
   location / {
      proxy_set_header X-cert $a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$s$t$v$u$w$x$y$z;
      proxy_pass http://localhost:8000;
   }
}

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

4
ответ дан 3 December 2019 в 05:23

Я вижу здесь 2 решения:

  1. Включите сценарии LUA и переформатируйте строка в формате без конца строки.
  2. Используйте плагин Set Misc и используйте base64_encode для этой переменной.
1
ответ дан 3 December 2019 в 05:23

Похоже, что в более новых версиях nginx все \ n заменяются на \ t в переменной $ ssl_client_cert . Переменная $ ssl_client_raw_cert доступна, если вы не хотите, чтобы это преобразование применялось.

См .: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables

1
ответ дан 3 December 2019 в 05:23

Вот решение LUA, которое сработало для меня:

set_by_lua $client_cert "return ngx.var.ssl_client_raw_cert and ngx.var.ssl_client_raw_cert:gsub('\\n',' ') or nil";
proxy_set_header X-SSL-CERT $client_cert;

Кроме того, если вы используете Ubuntu, nginx-extra имеет плагин LUA по умолчанию, поэтому нет необходимости в дополнительной настройке: https://stackoverflow.com/questions/22193852/running-lua-in-nginx-config

0
ответ дан 3 December 2019 в 05:23

Я считаю, что теперь это способ решения исходной проблемы:

proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

Согласно документам:

$ssl_client_escaped_cert возвращает сертификат клиента в формате PEM (urlencoded) для установленного соединения SSL (1.13.5);

0
ответ дан 2 October 2021 в 17:15

Теги

Похожие вопросы