Як налаштувати ярлик для з'єднання SSH через тунель SSH


22

Сервери виробництва моєї компанії (FOO, BAR ...) розташовані за двома серверами шлюзу (A, B). Для того, щоб підключитися до сервера FOO, я повинен відкрити ssh-з'єднання з сервером A або B з моїм іменем користувача JOHNDOE, тоді з A (або B) я можу отримати доступ до будь-якого виробничого сервера, що відкриває SSH-з'єднання зі стандартним ім'ям користувача (назвемо це WEBBY).

Отже, кожен раз, коли мені доводиться робити щось на кшталт:

ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server

Як ви можете собі уявити, це клопот, коли мені потрібно використовувати scpабо якщо мені потрібно швидко відкрити декілька з'єднань.

Я налаштував ключ ssh, а також використовую .ssh / config для деяких ярликів.

Мені було цікаво, чи можу я створити якусь конфігурацію ssh для того, щоб набрати

ssh foo

і дозволь SSH відкрити / переслати всі з'єднання для мене. Це можливо?

Редагувати

відповідь uterble - це саме те, що я шукав, але здається, зараз я не можу використовувати netcat, оскільки він не встановлений на сервері шлюзу.

weppos:~ weppos$ ssh foo -vv
OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/xyz/.ssh/config
debug1: Applying options for foo
debug1: Reading configuration data /etc/ssh_config
debug2: ssh_connect: needpriv 0
debug1: Executing proxy command: exec ssh a nc -w 3 foo 22
debug1: permanently_drop_suid: 501
debug1: identity file /Users/xyz/.ssh/identity type -1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_rsa type 1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_dsa type 2
bash: nc: command not found
ssh_exchange_identification: Connection closed by remote host

Відповіді:


36

Як більш конкретна версія відповіді Кайла, що ви хочете помістити у свій ~/.ssh/configфайл, це:

host foo
  User webby
  ProxyCommand ssh a nc -w 3 %h %p

host a
  User johndoe

Потім, коли ви запустите "ssh foo", SSH спробує SSH до johndoe@a, run netcat( nc), а потім виконати SSH webby@fooчерез цей тунель. Магія!

Звичайно, для цього потрібно netcat встановити на сервері шлюзу; цей пакет доступний для всіх основних дистрибутивів та ОС.


Відмінно! Я намагався це зрозуміти, я ніколи раніше не стикався з такою точною ситуацією. Я буду тримати свою відповідь там, якщо це може допомогти комусь із менш конкретною ситуацією в майбутньому.
Кайл Брандт

Я оновив своє первісне запитання, включаючи багатослівний вихід мого з'єднання. Здається, я не можу використовувати netcat. Чи має бути доступним за замовчуванням?
Сімоне Карлетті

Не завжди у вас є сила її встановити? Ви можете це зробити і з telnet, я ніколи цього не пробував ...
Кайл Брандт

Можливо, ви також зможете завантажити netcat у свій домашній каталог і скласти його там. Тоді ви можете просто скористатися повним шляхом у команді проксі, тобто / home / userName / bin / nc
Кайл Брандт,

Я щойно перевірив налаштування системи. У Ubuntu netcat, здається, доступний за замовчуванням, на жаль, сервери шлюзу працюють від OpenSUSE. Я також розглядаю можливість встановлення netcat на шлюзових серверах.
Сімоне Карлетті

7

Ви можете використовувати директиву ProxyCommand у файлі ~ / .ssh / config, наприклад використовувати netcat як реле:

host server2
    ProxyCommand ssh server1 nc server2 22

Ви просто використовуєте 'ssh server2'. Інформація про чоловічу сторінку цієї директиви міститься в "man ssh_config"


5

Я віддаю перевагу іншому підходу, який підтримує попередньо автентифікований тунель до сервера шлюзу. В ~/.ssh/config:

Host a
    ControlMaster auto
    ControlPath ~/.ssh/control-master/%r@%h:%p

Потім у .bashrc:

s () {
        if ( ssh -O check a 2>&1 > /dev/null 2>&1 )
        then
                ssh -t a ssh $1
        else
                if [[ -S ~/.ssh/control-master/insyte@a:22 ]]
                then
                        echo "Deleting stale socket..."
                        rm ~/.ssh/control-master/insyte@a:22
                fi
                echo "Opening master session..."
                if ssh -Nf a
                then
                         ssh -t a ssh $1
                fi
        fi
 }

Отже, для підключення до foo:

s foo

Перший раз, коли ви підключите його, ви автентифікуєте вас проти "a" та відкриєте стійкий фоновий тунель ssh. Подальші дзвінки на "s" відкриються майже миттєво через попередньо встановлений тунель.

Чудово працює.


2

Цей тип функціональності існує в новіших версіях OpenSSH і може бути використаний тим самим

ssh -W server2 server1

Де server2ваше місце призначення та server1ваш проксі-хост. Ви можете зробити це простіше, скориставшись ProxyCommandопцією в своєму ssh config, наприклад:

host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1

Здається, що для цього вам потрібно OpenSSH 5.4+ у всіх трьох місцях: настільний, посередницький, пункт призначення. (Ну, перше і останнє, звичайно).
Стів Беннетт

@SteveBennett: Я вже деякий час використовую цей метод, він працює досить чудово. Мені довелося повернутися до методу netcat для пари систем RHEL5, що дратувало.
Скотт Пак

2

Якщо netcatнедоступний проксі, спробуйте цей фокус:

host foo
  User webby      
  ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!'

host a
  User johndoe

Тоді ви повинні вміти ssh foo.

Крім того, якщо у вас є остання версія ssh на a (тобто з -Wкомандою для пересилання стандартного вводу та виводу), ви можете використовувати:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

Нарешті, тільки тому, що я вважаю, що це круто (а не тому, що це буде працювати у вашому конкретному випадку, через відмінності в імені користувача), в блозі друга знайомого , як зробити таку річ динамічною та рекурсивно ланцюговою SSH-проксі (разом із деякими речами які не працюють добре):

host */*
  ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p

І тоді ssh machine1/machine2слід дати вам снаряд machine2, прокладений через нього machine1.

Цікаво, чи використання спеціальних sedкоманд замість dirnameі basenameможе не вирішить проблему з різними іменами користувачів?


2

Це можна досягти, роблячи ssh -At johndoe@a ssh webby@foo. -AКоманда пересилає ваш SSH агент (так що ви можете уникнути необхідності повторної аутентифікації на проксі - сервері), в той час як -tзабезпечує термінал існує на проксі - сервері. Наступна функція bash може бути корисною:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}

Це, безумовно, найпростіше рішення. Зараз йому просто потрібно ще 35 грошей. (Btw -A не робить нічого для мене.)
Стів Беннетт

0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

Netcat не встановлено a. При запуску ssh host "command arg", commandвиконується на host, а нема на локальному комп'ютері.


Так, я знаю. Про це я саме повідомив у коментарі до відповіді жінки. :)
Симоне Карлетті

0

З часу OpenSSH 7.3 (2016-08-01) були доступні ProxyJumpопція та відповідний -Jпрапор командного рядка, щоб дозволити більш просту непряму передачу через один або кілька бастіонів SSH або "стрибати хости".

Це знімає залежність від зовнішньої ncкоманди, знайденої в рішенні Womble .

ssh -J johndoe@a webby@foo 

встановить SSH-з'єднання з вашої робочої станції до сервера шлюзу aяк користувач johndoe та тунель сеансу SSH для розміщення foo для Webby користувача через це.

Для спрощення створення дефініцій хостів як для вашого, так ~/.ssh/configі для ви можете просто виконатиssh foo

Host a
    User johndoe

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