Nginx ходит к upstream по HTTPS: включаем SNI и проверку сертификата
Внешний HTTPS сайта работает, но после перевода backend на HTTPS Nginx возвращает 502. Клиентский сертификат сайта не объясняет эту ошибку: между Nginx и backend создаётся отдельное TLS-соединение. У него собственные имя сервера, доверенные центры и параметры проверки.
Опишите идентичность backend отдельно
upstream backend_tls {
server 10.20.0.15:8443;
}
server {
listen 8080;
server_name app.example;
location / {
proxy_pass https://backend_tls;
proxy_ssl_server_name on;
proxy_ssl_name backend.internal.example;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/backend-ca.pem;
proxy_set_header Host backend.internal.example;
}
}
Это фрагмент контекста http для учебной проверки входа по 8080. TLS-терминация внешнего входа настраивается отдельно. Группа upstream задаёт сетевой адрес. proxy_ssl_name задаёт имя, по которому проверяется сертификат backend и которое передаётся как SNI при включённом server_name.
Host относится к HTTP после завершения TLS. Его значение может отличаться от TLS-имени, если этого требует контракт приложения. В простом примере они совпадают. Одна настройка Host не заменяет SNI: выбор сертификата на backend происходит раньше обработки HTTP-заголовков.
Задайте доверие явно
В стандартной конфигурации proxy_ssl_verify выключен. Само наличие https в proxy_pass не означает проверенную подлинность upstream. Включите проверку и укажите утверждённый набор CA. Конечный сертификат backend должен содержать backend.internal.example, быть действующим и иметь пригодную цепочку.
Проверьте глубину цепочки proxy_ssl_verify_depth под используемый центр и сертификаты. Если она недостаточна для вашей иерархии, проверка может завершиться ошибкой при правильном корне. Не увеличивайте значение произвольно вместо изучения фактической цепочки: сначала получите её с того же сетевого участка.
Разберите причину 502 по журналу
Ошибка handshake, несовпадение имени и невозможность проверить издателя — разные ситуации. Сопоставьте запись error log со временем внешнего запроса. Затем выполните строгую проверку backend с машины Nginx, задав нужное server name и CA. Это поможет отделить серверную цепочку от параметров самого прокси.
openssl s_client -connect 10.20.0.15:8443 -servername backend.internal.example -verify_hostname backend.internal.example -CAfile /etc/nginx/backend-ca.pem -verify_return_error
Например, сообщение о несовпадении имени при сертификате на backend.internal.example может появиться, если Nginx проверяет имя группы backend_tls. Сетевое соединение здесь уже возможно, поэтому менять IP не требуется: задайте ожидаемую идентичность через proxy_ssl_name. Если строгий вызов тоже отвергает имя, проверьте SAN самого сертификата и правильность выбранного backend.
Другой результат — невозможность построить цепочку до доверенного издателя. Сравните присланные intermediate с CA-файлом и утверждённой иерархией организации. Исправлением будет полноценная цепочка на backend либо правильный набор доверия у Nginx. Выключение verify лишь скроет причину и лишит второй участок проверки подлинности.
Если прямое соединение с указанным именем и CA работает, проверьте фактически применённую конфигурацию Nginx. Возможно, запрос попадает в другой location или унаследовал иное значение. Если backend требует mTLS, дополнительно нужны клиентские сертификат и ключ прокси; это отдельная аутентификация, которую приведённый пример не задаёт.
Перед применением проверьте конфигурацию через nginx -t. После согласованного включения выполните запрос к внешнему входу и подтвердите обращение к нужному backend. На тестовом стенде полезно проверить, что заведомо неподходящее имя приводит к отказу: так видно, что проверка upstream действительно включена.
Разбирайте каждый сетевой участок сервиса отдельно. Откройте программу Linux и Bash для DevOps-инженеров. Практика сети, DNS и HTTP поможет связать параметры клиента, прокси и приложения в последовательную диагностику.
Ещё по теме
Продолжить на практике
- Linux и Bash для DevOps-инженеров ↗
Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.
