Назад | Перейти на главную страницу

Проблема с картой SSH обратного прокси NGINX

В нашей компании работает несколько виртуальных (Ubuntu) серверов. У каждого есть свое сетевое соединение с мостом, поэтому он получает свой собственный IP-адрес от маршрутизатора (зарезервирован DHCP). Нам нужно запустить несколько веб-сайтов с собственными поддоменами.

У нас есть главный домен (скажем, example.com)

Затем у нас есть sub1.example.com, sub2.example.com и sub3.example.com.

Казалось, что самый простой способ сделать это - запустить обратный прокси-сервер (чтобы в будущем мы могли перенести некоторые из них в облако и использовать балансировку нагрузки).

Я установил новую виртуальную машину с Ubuntu 20.04 LTS под управлением NGINX и настроил ее как обратный прокси.

Сейчас у меня 3 конфигурации:

redirect_https:

server {
    listen 80;
    listen [::]:80;
    
    server_name *.example.com;
    return 301 https://$host$request_uri;
}

ssl-прокси:

server {
    listen 443 ssl;
    server_name example.com;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded_Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass https://10.10.x.y;
        proxy_http_version 1.1;
    }
    
    ssl_certificate        /etc/<path_to_cert>/fullchain.pem;
    ssl_certificate_key    /etc/<path_to_cert>/privkey.pem;
}

ssl-прокси-поддомены:

server {
    listen 443 ssl;
    server_name sub1.example.com sub2.example.com sub3.example.com;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded_Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass https://10.10.x.y;
        proxy_http_version 1.1;
    }
    
    ssl_certificate        /etc/<path_to_cert>/fullchain.pem;
    ssl_certificate_key    /etc/<path_to_cert>/privkey.pem;
}

Все работает нормально.

Чтобы иметь возможность редактировать наши сайты из дома, я хотел настроить прокси для передачи SSH-трафика, вот где я запутался.

Я прочитал несколько сообщений здесь, на других сайтах, в документации NGINX, я, кажется, не понимаю этого.

Я последовал примеру прямо из документации: https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

Кажется довольно простым.

Моя конфигурация практически идентична (только измененные части, относящиеся к моей компании, например IP-адреса и т. Д.)

Для полноты картины использованный мной пример озаглавлен Выбор восходящего потока на основе имени сервера

Моя конфигурация (измененная):

map $ssl_preread_server_name $name {
    example.com           backend_main;
    sub1.example.com      backend_1;
    sub2.example.com      backend_2;
    sub3.example.com      backend_3;
    default               backend_proxy;
}

upstream backend_main { server 10.10.x.y:22; }
upstream backend_1 { server 10.10.x.y:22; }
upstream backend_2 { server 10.10.x.y:22; }
upstream backend_3 { server 10.10.x.y:22; }
upstream backend_proxy { server 10.10.x.y:22; }

server {
    listen      2222;
    proxy_pass  $name;
    ssl_preread on;
}

log_format proxy '$remote_addr [$time_local] '
    '$protocol $status $bytes_sent $bytes_received '
    '$session_time "$upstream_addr" '
    '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

access_log /var/log/nginx/proxy-access.log proxy;
error_log /var/log/nginx/proxy-error.log;

Приведенный выше фрагмент кода находится внутри stream {...} блокировать в /etc/nginx/nginx.conf после html {...} блок (прямо перед прокомментированным mail {...} блок).

Маршрутизатор берет внешний порт 22 и перенаправляет его на внутренний порт 2222 обратного прокси.

Проблема, с которой я столкнулся, заключается в том, что map всегда выбирает дефолт вариант. Если я удалю / прокомментирую значение по умолчанию, я вообще не смогу подключиться. Если я изменю IP-адрес по умолчанию, он соединит меня с этим сервером, но опять же, только то, что "по умолчанию".

Конечная цель - иметь возможность использовать ssh напрямую в один из поддоменов (например, ssh user@sub1.example.com). На данный момент мне нужно подключиться по ssh к одному серверу, к которому я дал себе внешний доступ, а затем использовать ssh для внутреннего.

Единственное, что приходит в голову, это то, что это может не работать с существующим прокси HTTPS, но, возможно, stream модуль также должен иметь возможность обрабатывать их (и если это так, смогу ли я установить заголовки? в противном случае серверные ВМ будут видеть только запросы, поступающие от обратного прокси).

У меня есть подозрение, что это простая проблема и что я что-то упустил, но, потратив 8 часов на чтение и пробуя разные вещи, я чувствую, что пора попросить о помощи ...

Клиент SSH не использует расширения SNI протокола TLS, которые были разработаны для поддержки общего хостинга с HTTPS. Вы можете попробовать настроить свой ssh-клиент следующим образом:

Host example.com *.example.com
    ProxyCommand openssl s_client -quiet -servername %h -connect example.com:2222

Однако я не знаю, сработает ли это. Вы можете узнать больше о s_client команда openssl Вот. Также взгляните на эту статью: Прокси-сервер SSH с использованием TLS / SNI и NGINX.

Очевидно, что ssh - это не https, и его протокол не отправляет имя хоста, с которым вы можете выполнять сопоставление, как вы можете с https.

У меня есть несколько хостов с аналогичными ограничениями, поскольку они являются виртуальными машинами, у которых нет глобального IPv4-адреса. Для этого я обращаюсь к ним через ssh с IPv6. Если по какой-то причине вы не развернули IPv6, значит, вы отстаете на несколько лет ...