У меня 3 сервера, A является общедоступным сервером в Интернете. B Размещает веб-службу, к которой я хочу получить доступ. C имеет права доступа для подключения к A и B.
Теперь я хочу, чтобы, если клиент D пытается получить доступ к специальному порту на A, он будет перенаправлен на B.
A:
B:
C:
D:
+------------+ +------------+
| Client (D) +--------> Public (A) |
+------------+ +-----^------+
|
+----------------+ +-----------+
| Webservice (B) <----+ Proxy (C) |
+----------------+ +-----------+
Какой ssh Команды туннеля мне нужно выполнить на C , чтобы при попытке открыть 1.0.0.1:443 на D я получил службу, размещенную на 1.0.0.2:444?
На C вы можете запустить
ssh -fNR 1.0.0.1:443:1.0.0.2:444 root@1.0.0.1
. Он будет работать только в том случае, если вы войдете в систему как пользователь root
, потому что 443
- это привилегированный порт. Более того, он работает, только если sshd
на A настроен с GatewayPorts
, установленным на yes
или clientpecified
. (По умолчанию нет
, и использование да
не рекомендуется, поэтому, если вы хотите сделать это таким образом, я рекомендую с указанием клиентов
).
Это не совсем то, как работают туннели SSH. Вы можете приблизиться к тому, что вы описываете, но не совсем так, как вы это делаете.
Вам доступны 2 варианта:
- используйте L переадресацию портов
- используйте D динамическую переадресацию портов
Это требует от вас изменения подхода: туннель должен открываться из клиента, из D на вашей диаграмме. этого легко добиться, на клиенте (D) просто выполните
ssh -L 443:1.0.0.2:444 user@1.0.0.3
, конечно, для чего вам потребуется:
Я объясню динамическую переадресацию портов чуть позже
@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.
Таким образом, локальный пользователь на A теперь может выполнить wget https: // localhost: 445 --no-check-certificate
, чтобы получить индексную страницу вашего веб-сервиса.
Однако это еще не публично доступно.
(на случай, если вам интересно: порт 445 правильный, я должен использовать какой-то неиспользуемый порт для следующей части)
Итак, я создал сервер nginx на A , который будет перенаправлять любой трафик с порта 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: // proxy ..com: 443 и получить результат от своего веб-сервиса. IP-адрес proxy..com должен быть 1.0.0.1.
Что мне здесь не нравится, так это то, что мне нужно создать новый веб-сервер, который будет создавать новый зашифрованный сеанс вместо того, чтобы просто перенаправлять один из моих веб-сервисов, расположенных на B . Однако это хороший обходной путь, пока я не найду лучшее решение.