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

то це вже справді допоможе.

Чи є спосіб зробити це простіше?

Відповіді:


195

-LОпція може бути вказана кілька разів в межах однієї і тієї ж команди. Щоразу з різними портами.


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

Звичайно, ніщо не заважає вам перетворити це в сценарій або автоматизувати його, якщо у вас є багато різних хостів / портів для переадресації та до певних конкретних.

Сподіваюся, це допомагає.


Прекрасне доповнення до відповіді Нани. Дякую.
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.


Мені подобається такий підхід.
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. Це посилання дає чудовий опис того, як це зробити. Тут я хотів би зробити деякий підсумок та розширення для всіх вас, хлопці.

Ситуація 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 порт_А та порт_В можуть бути однаковими для спрощення процедури.


Нагадування, один і той же порт на різних серверах - це різні порти. Отже, це завжди може полегшити ситуацію, вказавши ідентичний номер порту!
Фей Яо

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 на доступній машині відповідають однаковим портам цільового (вони розміщують два веб-сервіси в моєму випадку ).


1

Я розробив loco для допомоги у переадресації ssh. Він може бути використаний для обміну портами 5000 і 7000 на віддалених локально на тих же портах:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.