В нашей компании работает несколько виртуальных (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, значит, вы отстаете на несколько лет ...