SSH от A до B на C, используя закрытый ключ на B

60

Я ищу простой способ SSH с моего локального компьютера A через прокси-сервер B на хост назначения C. Закрытый ключ, который идет с открытым ключом на C, находится на B, и я не могу положи этот ключ на мою локальную машину. Какие-нибудь советы?

Кроме того, я хотел бы иметь возможность сделать это с помощью ~ / .ssh / config.

Спасибо!

спорщик
источник
1
Ты хочешь сказать, что хочешь ssh от A до B, а затем SSH к C? Или прокси - настоящая сквозная ситуация?
худенький
Я хочу ssh из A в C, проходя через B. Мой ответ ниже работает для проходной части, но он все еще пытается найти IdentityFile на моем локальном компьютере, а не на B, промежуточном хосте.
спорщик

Ответы:

74

Схема:

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

Предпосылки:

  • A работает ssh-agent;
  • Aможет получить доступ B;
  • Bможет получить доступ C;
  • Assh публичный ключ присутствует в B:~/.ssh/authorized_keys
  • Bssh публичный ключ присутствует в 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 года, но, похоже, у нас есть ответ! Круто
спорщик
3
Начиная с openssh v.7.3, вы можете просто использовать ProxyJump B. источник: wikibooks
Кит
2
Может ли это быть определено так: Хост user1 @ c ProxyCommand ssh -o 'ForwardAgent yes' user2 @ B 'ssh-add && nc% h% p'
Равиндранат Акила
2
Как изменится решение, если машина B не имеет 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 Я обновил ответ. Пожалуйста, проверьте, работает ли он для вас.
Сачин Дивекарь
Сачин, очень умный. Это сработало отлично. Спасибо!
спорщик
@DrewVS рад слышать, что это работает для вас. поэтому, пожалуйста, примите ответ.
Сачин Дивекарь
Однако, похоже, что это не работает с ключами RSA, защищенными паролем. Ввод пароля скрыт, что заставляет пользователя добавлять ключ к своему ssh-ключу, чтобы этот подход работал. Есть идеи?
спорщик
10

Я решил это сейчас. Вот решение, которое довольно просто. Я должен был увидеть это раньше:

~ / .Ssh / конфигурации:

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-agent, поэтому я подумал, что он работает. В вышеупомянутом ключ для 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/
wcc526
источник
1

Сделать:

ssh someuser@IP_D

такой, что

A -> B-> C -> D где A - хост, на котором вы находитесь,

отредактируйте ваш локальный файл ~ / .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'

Этот ответ основан на выбранном ответе. Я должен был выяснить, как различные пользователи вписываются в весь сценарий.

Это работает для меня. НТН.

Равиндранат Акила
источник
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'
Даниэль А.А. Пельсмакер
источник