У меня 3 Сервера, А это общедоступный сервер в Интернете. B Размещает веб-сервис, к которому я хочу получить доступ. C имеет права доступа для подключения к A и B.
Теперь я хочу, чтобы клиент D пытается получить доступ к специальному порту на A, который перенаправляется на B.
А:
B:
C:
D:
+------------+ +------------+
| Client (D) +--------> Public (A) |
+------------+ +-----^------+
|
+----------------+ +-----------+
| Webservice (B) <----+ Proxy (C) |
+----------------+ +-----------+
Какие команды туннеля ssh мне нужно выполнить C так что если я попытаюсь открыть 1.0.0.1:443 на D я размещаю службу на 1.0.0.2:444?
Это не совсем так, как работают туннели SSH: вы можете приблизиться к тому, что вы описываете, но не совсем так, как вы это рисуете.
Вам доступны 2 варианта:
- использовать Lперенаправление портов
- использовать Dдинамическое перенаправление портов
Это требует, чтобы вы изменили свой подход: туннель нужно открывать от клиента, от D на вашей диаграмме. этого легко добиться, на клиенте (D) просто выполните
ssh -L 443:1.0.0.2:444 user@1.0.0.3
конечно, это требует от вас:
Я объясню динамическую переадресацию портов через минуту
На C вы можете запустить
ssh -fNR 1.0.0.1:443:1.0.0.2:444 root@1.0.0.1
Это будет работать, только если вы войдете как root
пользователь, потому что 443
это привилегированный порт. Более того, это работает, только если sshd
на A настроен с GatewayPorts
установлен в yes
или clientspecified
. (По умолчанию no
и используя yes
нельзя рекомендовать, поэтому, если вы хотите сделать это так, я рекомендую clientspecified
).
@kasperd упомянул, что вы можете установить GatewayPorts для пользователя, чтобы вам не нужно было использовать nginx. Я оставляю обходной путь для других.
Добавьте это в /etc/ssh/sshd_config
Match User <username>
GatewayPorts yes
Я нашел решение для достижения этого с помощью ssh и nginx. Это не идеально, потому что мне нужно установить сервер nginx на A с прокси. Мне пришлось включить ssl и дать этому экземпляру nginx собственный сертификат ssl.
Итак, Решение будет выглядеть так: C выполнит следующую команду для создания реле между A и B:
ssh -R 445:1.0.0.2:444 user@1.0.0.1 -p 22
Это приведет к тому, что любой ввод на порт 445 в 1.0.0.1 будет перенаправлен на 1.0.0.2:444. Итак, локальный пользователь на А теперь можно выполнитьwget https://localhost:445 --no-check-certificate
чтобы получить индексную страницу вашего веб-сервиса. Однако это еще не публично доступно. (в случае, если вам интересно: порт 445 правильный, я должен использовать какой-то неиспользуемый порт для следующей части)
Итак, я создал сервер nginx на А который перенаправит любой трафик с порта 443 на порт 445. И использовал следующую конфигурацию:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
server_name proxy.<your-domain>.com;
location / {
proxy_pass https://127.0.0.1:445;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}
Теперь вы можете использовать свой веб-браузер (в режиме инкогнито в Firefox для предотвращения проблем с сертификатом), чтобы https: // прокси..com: 443 и получите результат от своего веб-сервиса. IP-адрес proxy..com должен быть 1.0.0.1.
Что мне здесь не нравится, так это то, что мне нужно создать новый веб-сервер, который будет создавать новый зашифрованный сеанс, а не просто перенаправлять один из моих веб-сервисов, расположенных на B. Однако это хороший обходной путь, пока я не найду лучшее решение.