SSH від A до B до C, використовуючи приватний ключ на B


59

Я шукаю простий шлях до SSH з моєї локальної машини, A, через проксі, B, до хоста призначення, C. Приватний ключ, який йде із відкритим ключем на C, знаходиться на B, і я не можу покладіть цей ключ на мою локальну машину. Якісь поради?

Також я хотів би це зробити за допомогою ~ / .ssh / config.

Дякую!


1
Ви хочете сказати, що хочете перейти від A до B, а потім SSH до C? Або проксі - це справжня ситуація проходження?
thinice

Я хочу ssh від A до C, проходячи через B. Моя відповідь нижче працює для проходження частини, але вона все ще намагається шукати IdentityFile на моєму локальному комп'ютері, а не на B, хостовому проході.
wrangler

Відповіді:


74

Схематично:

    ssh       ssh
A ------> B ------> C
    ^          ^
 using A's   using B's
 ssh key     ssh key

Передумови:

  • A працює ssh-агент;
  • Aможе отримати доступ B;
  • Bможе отримати доступ C;
  • Aвідкритий ключ ssh присутній у B:~/.ssh/authorized_keys
  • Bвідкритий ключ ssh присутній у C:~/.ssh/authorized_keys

В ~/.ssh/configна A, додати

Host C
    ProxyCommand ssh -o 'ForwardAgent yes' B 'ssh-add && nc %h %p'

Якщо ваш приватний ключ ssh на B знаходиться у нестандартному місці, додайте його шлях після ssh-add.

Тепер ви можете мати доступ Cіз A:

A$ ssh C
C$

13
Минуло лише 4 роки, але схоже, що у нас є відповідь! Awesome
wrangler

3
Починаючи з openssh v.7.3, ви можете просто використовувати ProxyJump B. джерело: wikibooks
Кіт

2
Чи можна це визначити таким чином: Хост user1 @ c ProxyCommand ssh -o 'ForwardAgent так' user2 @ B 'ssh-add && nc% h% p'
Равіндранат Акіла

2
Як змінилося б рішення, якщо машини Б немає nc?
mjalajel

1
@DrewVS Добре, потрібно додати , ForwardAgent yes перш ніж в ProxyJumpкоманді.
Грайфер

22

Перевірте, чи працює наступне.

ssh -t B ssh C

Використовуйте наступну команду, якщо ви хочете використовувати ключ, збережений на B.

ssh -t B ssh -i /path/to/identity_on_B C

Тут ми вказуємо команду, тобто ssh -i /path/to/identity_on_B Cвиконуватись на B замість оболонки для входу.


Це працює, але він не підбирає IdentityFile від B. Він все ще виглядає на A.
wrangler

@DrewVS Я оновив відповідь. Перевірте, чи працює він для вас.
Сахін Дівекар

Сахін, дуже розумний. Це спрацювало чудово. Дуже дякую!
wrangler

@DrewVS рада почути, що це працювало на тебе. тому прийміть відповідь.
Сачин Дівекар

Однак, схоже, це не працює з ключами rsa, захищеними паролем. Введення пароля приховано, і змушує користувача додати ключ до свого ssh-ключа, щоб цей підхід працював. Будь-які ідеї?
wrangler

10

Я зараз це розробив. Ось рішення, яке досить прямолінійне. Я повинен був бачити це раніше:

~ / .ssh / config:

Host B
  HostName 1.2.3.4
  User myuser
  IdentityFile ~/.ssh/rsa_key
  ControlMaster auto
  ControlPath ~/.ssh/socket/master-%l-%r@%h:%p

Host C.*
  User customer_username
  Port customer_port
  IdentityFile remote/path/to/ssh/key
  ForwardAgent yes
  ProxyCommand ssh accessable.server nc %h %p

Host C.server-1
  HostName 2.3.4.5

'B' - це проксі-сервер, через який ви переходите. Він повинен бути налаштований так, як зазвичай налаштовував би доступ до сервера.

"C" - хост призначення. Це потрібно налаштувати для використання "B" у процесі з'єднання. Файл посвідчення у "C" - це шлях до ключа ssh на "B". ProxyCommand використовує Netcat для відкриття з'єднання до "C" з "B". Netcat або nc потрібно буде встановити на "B".

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


3
Я говорив занадто рано. Це рішення не бачить працювати. Ключ був завантажений у ssh-агент, тому я подумав, що він працює. У вищесказаному, ключ для C все ще повинен бути на A, а не на B.
wrangler

2

Я написав простий скрипт, в основному перерахував мої ключі ssh на віддаленому екземплярі, а потім додав вибраний я до свого локального агента ssh. Це не дуже чисто, але дозволяє мені тримати всі клавіші на віддаленому місці, а не локально.

Ось сценарій, якщо когось цікавить:

#!/usr/bin/ruby

require "rubygems"
require "fileutils"

# Get key list
key_list = (`ssh jumpbox "cd ~/.ssh/ ; ls id_rsa*" | sed 's/id_rsa_/  /g' | sed     's/id_rsa//g'`)
puts ' '
puts 'Available customer keys:'
puts key_list

# Get customer name input
puts ' '
puts 'Enter customer name: '
customer_name = gets.chomp

# Add key to ssh-agent
key_name = "~/.ssh/id_rsa_#{customer_name}"
puts ' '
puts "Adding #{key_name} to local ssh-agent"
`ssh jumpbox "ssh-add ~/.ssh/id_rsa_#{customer_name}"`
exit 0

Я думаю, що додавання ключа можна трактувати як ідентичне, тим самим усуваючи необхідність отримати список ключів.
dmourati

Ви повинні прийняти serverfault.com/a/701884/127993, який робить саме те, що ви хочете.
sjas

1
#!/usr/bin/env bash
target_host=10.121.77.16
target_port=22
target_user=vagrant

bastion_user=yourusername
bastion_host=10.23.85.245
bastion_port=32780

scp -P $target_port -o ProxyCommand="ssh -o 'ForwardAgent yes' $bastion_user@$bastion_host -p $bastion_port 'ssh-add ~/.ssh/*.rsa && nc %h %p'" /tmp/x.txt $target_user@$target_host:/tmp/

1

Робити:

ssh someuser@IP_D

такий, що

A -> B-> C -> D де А - господар, на якому ви перебуваєте,

відредагуйте локальний ~ / .ssh / config так:

Host IP_D
  ProxyCommand ssh -o 'ForwardAgent yes' userX@IP_C 'ssh-add && nc %h %p'
Host IP_C
  ProxyCommand ssh -o 'ForwardAgent yes' userY@IP_B 'ssh-add && nc %h %p'

Ця відповідь ґрунтується на обраній відповіді. Мені довелося розібратися, як різні користувачі підходять до всього сценарію.

Це працює для мене. HTH.


0

Відповідь Снігової кулі дуже допомогла. Однак я вніс деякі зміни в команду і хотів пояснити, як вона працює. З огляду на таку ситуацію:

    ssh        ssh
A -------> B -------> C
     ^          ^
  using A's  using B's
  ssh key    ssh key

Змініть ~/.ssh/configфайл і додайте хост, Bчерез який ви хочете перейти, як саме ви налаштували хост:

Host B
 User myusername
 HostName b.mycompany.com

Потім ви додаєте хост, на Cякому хочете закінчитись:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 && nc %h %p'

Зверніть увагу ProxyCommand, де:

  • ssh -T -qвказує, що він не повинен виділяти псевдо-TTY ( -T) і бути тихим ( -q);
  • одного разу на хості стрибка Bдодаємо ключ до клавіш SSH Aчерез ssh-add;
  • яка працює лише тому, що ми переслали агент SSH за допомогою -o 'ForwardAgent yes'.
  • ssh-add -t 1 вказує, що я хочу, щоб ключ був доданий лише протягом 1 секунди, необхідної для аутентифікації до кінцевого хоста C;
  • і, нарешті, nc %h %pініціює netcatз'єднання з кінцевим хостом %hу порту %p(обидва вони будуть заповнені SSH на основі інформації у ~/.ssh/configфайлі).

Якщо вам потрібно вказати спеціальний ключ Bдля використання, ви можете зробити це, змінивши ssh-addдеталь:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 ~/.ssh/mykey && nc %h %p'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.