🚰 SSH туннели и проброс портов
Оригинал: https://codex.so/ssh-tunnel
При администрировании серверов часто возникают следующие задачи:
- Получить доступ к локальному порту на сервере с рабочей машины.
- Обеспечить доступ к локальному порту рабочей машины с сервера.
Обе эти задачи решаются с помощью туннелирования, но иногда требуется организовать такой туннель быстро и без создания сложной дополнительной инфраструктуры. Решить такую задачу можно с помощью SSH.
Доступ к внутреннему порту сервера
Попробуем подключиться к порту, к которому нет доступа снаружи, но есть доступ с сервера
(например, MongoDB, которая слушает порт 27017
на интерфейсе localhost
сервера).
Для этого используется параметр -L
.
ssh -L 9999:localhost:27017 root@server_ip
После аутентификации, у нас на рабочей машине появляется порт 9999
,
который перенаправлен на порт 27017
локального интерфейса сервера.
Теперь можно подключиться к MongoDB напрямую, как будто она запущена у вас на компьютере.
mongo localhost:9999 -u user -p password
Туннель прервётся, если вы закроете SSH соединение.
Кстати, если оно вам не требуется, а нужен только туннель – можно добавить параметр -N
.
ssh -L 9999:localhost:27017 root@server_ip -N
Можно также открывать доступ не к локальному порту сервера, а к удаленному порту другой машины, которая доступна с сервера.
ssh -L 9999:another_ip:80 root@server_ip -N
В данном примере, вы можете делать запросы на порт 9999
, связанный с 80
портом машины another_ip
.
Доступ с сервера на локальный порт
Теперь представим ситуацию, что нужно с сервера обратиться к какому-нибудь сервису,
запущенному на локальном компьютере. Например, вам регулярно присылают HTTP запросы по 80
порту на сервер.
Вы можете прокинуть локальный веб-сервер со своей рабочей машины
(скажем с 3000
порта) на сервер так, что запросы будут идти напрямую к вам. За это отвечает параметр -R
.
ssh -R 80:localhost:3000 root@server_ip
После этой команды на сервере откроется 80
порт, запросы на который будут прокидываться вам на 3000
.
По умолчанию 80
порт откроется на всех интерфейсах.
Если вы желаете выбрать конкретный (скажем 192.168.0.1), его можно указать следующим образом.
ssh -R 192.168.0.1:80:localhost:3000 root@server_ip
Цепочка туннелей через несколько узлов
Если нужно пробросить на свою машину локальный порт с сервера №2, доступ к которому по SSH есть только с сервера №1, можно построить цепочку из SSH туннелей.
ssh -L 9999:localhost:27017 root@server2 # server1
ssh -L 9999:localhost:9999 root@server1 # client
Можно воспользоваться однострочной командой.
ssh -L 9999:localhost:9999 root@server1 ssh -L 9999:localhost:27017 -N root@server2
А в случае, если у вас есть SSH ключи для доступа к серверу №2, вы можете построить защищенный туннель так, что ваш трафик не будет виден на сервере №1.
ssh -L 9998:server2:22 -N root@server1
ssh -L 9999:localhost:27017 -N -p 9998 root@localhost
В данном примере вы пробрасываете себе на порт 9998
порт с сервера №2,
обращаясь к нему через сервер №1.
А затем пробрасываете порт 27017
с сервера №2 на локальный 9999
.
В данной конфигурации вам уже не нужен сервер №1, так как порт SSH уже у вас на локальном 9998
.
SOCKS прокси
С помощью параметра -D
можно создать на локальной машине сокет для прослушивания динамического порта.
ssh -D localhost:8123 root@server_ip
Теперь достаточно добавить хост localhost
и порт 8123
в браузер для использования в качестве прокси.