NGINX proxy_pass: Ошибка "SSL_do_handshake() failed ... unknown protocol"

Стоит задача проксировать запросы к nginx, выполняя балансировку на основе заголовка.

Например, в REST API есть ресурсы, которые занимаются только отдачей контента. Их запросы проходят методом GET. Такие запросы можно отдавать на зеркала, которые read only.

И есть некоторые ресурсы, которые пишут в БД. Они принимают запросы методами POST, PUT, DELETE. Их нужно перенаправлять на мастер-сервер, где идёт запись в БД.

И есть засада: некоторые ресурсы обрабатывают сразу все методы. Т.е. по заголовку определяют, читать или писать.

Написал следующий конфиг:

upstream flask_serv {
    server unix:/tmp/flask.sock;
}

upstream read_api {
    server api.server.ru;
}

map $request_method $upstream_location {
    GET         read_api;
    default     flask_serv;
}

server {
    listen 443 ssl;
    server_name server.ru;

    root /var/www/server;

    include uwsgi_params;
    include proxy_params;

    location / {
        if ($http_referer !~* ^($|http://|https://) ){
             return 403;
        }
        uwsgi_pass flask_serv;
        uwsgi_read_timeout 300;
    }

    location /rest/v1/ {
        if ($upstream_location = "flask_serv") {
            uwsgi_pass unix:/tmp/flask.sock;
        }
        if ($upstream_location = "read_api") {
            proxy_pass https://$upstream_location;
        }
    }

    ssl_certificate /etc/letsencrypt/live/server.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/server.ru/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/server.ru/chain.pem;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  "RC4:HIGH:!aNULL:!MD5:!kEDH";
    add_header Strict-Transport-Security 'max-age=600';
}

Проблема в том, что сервер api.server.ru требует https. При обработке proxy_pass https://$upstream_location; получаю в логах ошибку:

SSL_do_handshake() failed (SSL: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol) while SSL handshaking to upstream

В чём проблема?


Ответы (1 шт):

Автор решения: Timur Irdyneev

попробуйте указать порт в настройках upstream

upstream read_api {
    server api.server.ru:443;
}

более подробно о настройке SSL для upstream-ов здесь securing-http-traffic-upstream/#complete-example

→ Ссылка