Мы проксируем бэкэнд, который мы не контролируем, и бэкэнд запрашивает сертификат клиента при подключении по https.
Когда мы запрашиваем эти страницы через прокси-сервер, время ожидания соединения истекает без ответа от серверной части, однако страницы работают нормально, если мы обходим прокси. Это проблема с nginx, обрабатывающим сертификат клиента, или нам нужно искать в другом месте?
Конфигурация Nginx:
server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/webserver.pem;
ssl_certificate_key /etc/nginx/ssl/webserver.key;
location / {
proxy_pass https://www.backendsite.com;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
}
}
Я не уверен, понимаете ли вы это или нет, но то, что вы делаете, это атака Man-In-The-Middle на www.backendsite.com
.
Чтобы понять, почему это не работает в вашем сценарии, нам нужно будет объяснить фактическую роль сертификатов и ключей в TLS. Итак, поехали.
Прежде всего, нам нужно установить ключ в открытом виде. У нас нет и по соображениям эффективности не может быть защищенного канала, поэтому мы используем протокол Diffie Hellman в качестве протокола обмена ключами. Ранее мы могли установить параметры, которые используем. Современное мышление говорит, что это плохая идея, давайте придумываем что-нибудь в процессе. Это называется DHE (эфемерный Диффи Хеллман). Если вам действительно нравится, вы можете сделать это через EC (EC-DHE).
Теперь вопрос в том, откуда вы знаете я отправил вам параметры, которые я сделал, используя DH? Чтобы проверить это, нам нужен алгоритм цифровой подписи, чтобы вы могли иметь некоторую общедоступную информацию обо мне, чтобы убедиться, что подпись, сделанная с помощью моего закрытого ключа, может быть сделана только мной.
Материал ключа сервера предоставляет это для серверной части - закрытый ключ и открытый ключ (содержащийся в сертификате вместе с подписями CA, говорящими «да», мы тоже этому доверяем).
ОБЫЧНО, клиент может просто сгенерировать пару открытого / закрытого ключей для анонимных подключений по своему усмотрению. Итак, при обычных обстоятельствах:
Однако теперь клиент предоставляет определенную пару ключей. Эта пара ключей используется для защиты параметров протокола, поэтому происходит следующее:
Причина, по которой это не совсем работает, заключается в том, что nginx пытается действовать как http-прокси, снимая и повторно применяя https по мере необходимости, и с доверенными сертификатами, установленными на обоих концах, TLS предотвращает MITM по дизайну.
Есть несколько альтернативных проектных решений, которые инженеры могут принять, когда серверная часть находится под их контролем. Я оказался здесь, потому что хотел подключиться к сокету unix, передав некоторую информацию о сертификате вперед. Это можно сделать с помощью эти заметки по аутентификации сертификатов с помощью nginx и это наблюдение в заголовках HTTP (не передавайте весь необработанный сертификат).