ssh -L пересылать несколько портов

129

В настоящее время у меня есть несколько:

sudo ssh -L PORT:IP:PORT root@IP

где IP - это цель защищенной машины, а PORT представляет порты, которые я пересылаю.

Это потому, что я использую много приложений, к которым я не могу получить доступ без этой пересылки. После этого я могу получить доступ через localhost:PORT.

Основная проблема возникла теперь, когда у меня на самом деле есть 4 из этих портов, которые я должен пересылать.

Мое решение - открыть 4 оболочки и постоянно искать в моей истории в обратном направлении, чтобы точно определить, какие порты необходимо перенаправить и т. Д., А затем запустить эту команду - по одной в каждой оболочке (необходимо вводить пароли и т. Д.).

Если бы я только мог сделать что-то вроде:

sudo ssh -L PORT1+PORT2+PORT+3:IP:PORT+PORT2+PORT3 root@IP

тогда это уже действительно поможет.

Есть ли способ сделать это проще?

PascalVKooten
источник

Ответы:

195

-LОпция может быть указана несколько раз в пределах одной и той же команды. Каждый раз с разными портами.

NaN
источник
20
Сначала я не понял этого ответа. Так что разместите здесь пример на случай, если кто-то страдает так же. Автор имел в виду «ssh -L port0: ip: port0 -L port1: ip: port1 ...»
Mong H. Ng
96

Именно на то, что ответил NaN , вы указываете несколько аргументов -L. Я все время это делаю. Вот пример переадресации нескольких портов:

ssh remote-host -L 8822:REMOTE_IP_1:22 -L 9922:REMOTE_IP_2:22

Примечание : это то же самое, как -L localhost:8822:REMOTE_IP_1:22если бы вы не указали localhost.

Теперь с этим вы можете (с другого терминала) делать:

ssh localhost -p 8822

подключиться к REMOTE_IP_1порту22

и аналогично

ssh localhost -p 9922

подключиться к REMOTE_IP_2порту22

Конечно, ничто не мешает вам обернуть это в сценарий или автоматизировать его, если у вас есть много разных хостов / портов для пересылки и к определенным конкретным.

Надеюсь это поможет.

jbchichoko
источник
Отличное дополнение к ответу Нэн. Спасибо.
AFP_555
1
Будьте осторожны: «Примечание: это то же самое, что и -L localhost: 8822: REMOTE_IP_1: 22, если вы не укажете localhost». Это верно, только если для параметра GatewayPorts установлено значение «нет», что, по общему признанию, является значением по умолчанию. Но учитывая последствия, если это не так, вам следует проверить настройку или, что еще лучше, указать явно и использовать "-L localhost: 8822 ...".
Дэвид
Я согласен с @David By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address: ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com ssh.com/ssh/tunneling/example
Карл Покус
24

Вы можете использовать следующую функцию bash (просто добавьте ее в свой ~/.bashrc):

function pfwd {
  for i in ${@:2}
  do
    echo Forwarding port $i
    ssh -N -L $i:localhost:$i $1 &
  done  
}

Пример использования:

pfwd hostname {6000..6009}
Юваль Ацмон
источник
2
Использовать -fдля работы в фоновом режиме
Карл Покус
Эммм ... почему ты хочешь сделать это таким образом?
Антон Бессонов
14

Для людей, которые перенаправляют несколько портов через один и тот же хост, можно настроить что-то подобное в своем ~ / .ssh / config.

Host all-port-forwards Hostname 10.122.0.3 User username LocalForward PORT_1 IP:PORT_1 LocalForward PORT_2 IP:PORT_2 LocalForward PORT_3 IP:PORT_3 LocalForward PORT_4 IP:PORT_4

и становится просто ssh all-port-forwardsпрочь.

RajaRaviVarma
источник
Мне нравится такой подход.
BMW
8

jbchichoko и yuval предложили жизнеспособные решения. Но ответ jbchichoko не является гибким ответом как функция, и открытые туннели с помощью ответа yuval не могут быть закрыты, ctrl+cпотому что он работает в фоновом режиме. Ниже я даю свое решение, устраняющее оба недостатка:

Определение функции в ~/.bashrcили~/.zshrc :

# fsshmap multiple ports
function fsshmap() {
  echo -n "-L 1$1:127.0.0.1:$1 " > $HOME/sh/sshports.txt
  for ((i=($1+1);i<$2;i++))
  do
    echo -n "-L 1$i:127.0.0.1:$i " >> $HOME/sh/sshports.txt
  done
  line=$(head -n 1 $HOME/sh/sshports.txt)
  cline="ssh "$3" "$line
  echo $cline
  eval $cline
}

Пример запуска функции:

fsshmap 6000 6010 hostname

Результат этого примера:

Вы можете получить доступ так 127.0.0.1:16000~16009же, какhostname:6000~6009

Том
источник
3

Одним из преимуществ входа на сервер с переадресацией портов является облегчение использования Jupyter Notebook. Эта ссылка дает отличное описание того, как это сделать. Здесь я хотел бы сделать некоторые выводы и дополнения для всех вас, ребята.

Ситуация 1. Войдите с локального компьютера с именем Host-A (например, с вашего собственного ноутбука) на удаленный рабочий компьютер с именем Host-B.

ssh user@Host-B -L port_A:localhost:port_B
jupyter notebook --NotebookApp.token='' --no-browser --port=port_B

Затем вы можете открыть браузер и ввести: http: // localhost: port_A /, чтобы выполнять свою работу на Host-B, но видеть его в Host-A.

Ситуация 2. Войдите с локального компьютера с именем Host-A (например, с вашего собственного ноутбука) на удаленный компьютер с именем Host-B и оттуда войдите на удаленный рабочий компьютер с именем Host-C. Обычно это характерно для большинства аналитических серверов в университетах и ​​может быть достигнуто с помощью двух ssh -Lсвязанных с -t.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C
jupyter notebook --NotebookApp.token='' --no-browser --port=port_C

Затем вы можете открыть браузер и ввести: http: // localhost: port_A /, чтобы выполнять свою работу на Host-C, но видеть это в Host-A.

Ситуация 3. Войдите с локального компьютера с именем Host-A (например, с вашего собственного ноутбука) на удаленный компьютер с именем Host-B и оттуда войдите на удаленный рабочий компьютер с именем Host-C и, наконец, войдите на удаленный рабочий компьютер Host- D. Обычно это не так, но когда-нибудь может случиться. Это продолжение ситуации 2, и ту же логику можно применить на большем количестве машин.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C -t ssh -L port_C:localhost:port_D user@Host-D
jupyter notebook --NotebookApp.token='' --no-browser --port=port_D

Затем вы можете открыть браузер и ввести: http: // localhost: port_A /, чтобы выполнять свою работу на Host-D, но видеть это в Host-A.

Обратите внимание, что port_A, port_B, port_C, port_D могут быть случайными числами, кроме общих номеров портов, перечисленных здесь . В Ситуации 1 port_A и port_B могут быть одинаковыми для упрощения процедуры.

Фэй Яо
источник
Напоминаем, что один и тот же порт на разных серверах - это разные порты. Следовательно, всегда можно было упростить задачу, указав идентичный номер порта!
Фэй Яо,
3

В моей компании и мне, и членам моей команды нужен доступ к 3 портам недостижимого «целевого» сервера, поэтому я создал постоянный туннель (то есть туннель, который может работать в фоновом режиме неограниченное время, см. Параметры -fи -N) от доступного сервера к целевой. В командной строке доступного сервера я выполнил:

ssh root@reachableIP -f -N  -L *:8822:targetIP:22  -L *:9006:targetIP:9006  -L *:9100:targetIP:9100

Я использовал пользователя, rootно ваш собственный пользователь будет работать. Вам нужно будет ввести пароль выбранного пользователя (даже если вы уже подключены к доступному серверу с этим пользователем).

Теперь порт 8822 доступной машины соответствует порту 22 целевой машины (для ssh / PuTTY / WinSCP), а порты 9006 и 9100 на достижимой машине соответствуют тем же портам целевой машины (в моем случае на них размещены две веб-службы. ).

Pino
источник
1

Я разработал локомотив для помощи с пересылкой ssh. Его можно использовать для совместного использования портов 5000 и 7000 на удаленном локальном компьютере на одних и тех же портах:

pip install loco

loco listen SSHINFO -r 5000 -r 7000
PascalVKooten
источник
1

Если вам нужно простое решение, которое работает в фоновом режиме и его легко убить - используйте управляющий сокет.

# start
$ ssh -f -N -M -S $SOCKET -L localhost:9200:localhost:9200 $HOST
# stop
$ ssh -S $SOCKET -O exit $HOST
Карл Покус
источник
1

Вот решение, вдохновленное решением Ювала Ацмона.

У него есть несколько преимуществ по сравнению с исходным решением:

  • сначала он создает один фоновый процесс, а не по одному на порт
  • он генерирует псевдоним, который позволяет вам уничтожать ваши туннели
  • он связывается только с 127.0.0.1, что немного более безопасно

Вы можете использовать его как:

  • tnl your.remote.com 1234
  • tnl your.remote.com {1234,1235}
  • tnl your.remote.com {1234..1236}

И, наконец, убить их всех с помощью tnlkill.

function tnl {
  TUNNEL="ssh -N "
  echo Port forwarding for ports:
  for i in ${@:2}
  do
    echo " - $i"
    TUNNEL="$TUNNEL -L 127.0.0.1:$i:localhost:$i"
  done
  TUNNEL="$TUNNEL $1"
  $TUNNEL &
  PID=$!
  alias tnlkill="kill $PID && unalias tnlkill"
}
Вилфрид Копп
источник
-1

Вы можете использовать эту функцию zsh (вероятно, работает и с bash) (вставьте ее ~/.zshrc):

ashL () {
    local a=() i
    for i in "$@[2,-1]"
    do
        a+=(-L "${i}:localhost:${i}")
    done
    autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NT "$1" "$a[@]"
}

Примеры:

ashL db@114.39.161.24 6480 7690 7477

ashL db@114.39.161.24 {6000..6050} # Forwards the whole range. This is simply shell syntax sugar.

Счастливое лицо
источник