Необходимо включить передачу соединения агента аутентификации (Опция "-A").
Пример:
hostA$ ssh -A hostB # agent forwarding enabled
hostB$ ssh-add
hostB$ ssh hostC # tries now the keys from hostA and the newly added
hostC$
Если Вы не хотите передавать ключ из соображений безопасности, Вы могли бы запустить новый экземпляр ssh-агента при помощи
hostB$ eval "$(ssh-agent)"
Если у Вас есть способ распознать, в какой сети Вы находитесь, то Вы можете использовать ключевое слово Match
в ~/.ssh/config
, чтобы сделать то, что Вы хотите. Для этого требуется OpenSSH ≥6.5.
Я использую нечто похожее на
Match originalhost gamma exec "[ x$(/sbin/iwgetid --scheme) != xMyHomeESSID ]"
HostName 192.168.1.100
Port 22
Host gamma
User andreas
Port 12345
HostName 55.22.33.99
Поэтому я использую идентификатор используемой wifi сети, чтобы решить, нахожусь ли я дома для целей SSH-соединения, но можно использовать и проверку IP-адреса, присвоенного вашему компьютеру, или что-то другое, что различает две сети.
Если у вас случайно есть приватные сервера имен на работе, и если вы используете один и тот же ноутбук из офиса и дома, вы можете воспользоваться этим для достижения этой цели:
nsswitch. conf
на вашей машине для проверки DNS сначала gamma
для разрешения до 192.168.1.100 в вашем личном DNS в офисе. gamma
до 55.22.33.99. Таким образом, когда вы ssh gamma
из офиса, он будет преобразовывать из DNS офиса в 192.168.1.100, а когда вы подключаетесь из дома, он будет преобразовывать в 55.22.33.99 из файла hosts.
P.S : Этот ответ предполагает, что вы не хотите, чтобы у гаммы была публичная DNS запись. Также, если вы используете SSHing на вашем сервере с машины под управлением Windows, я думаю, что должно быть место, эквивалентное файлу nssswitch.conf для переопределения записей в файле hosts.
Этого нельзя достичь в ~/.ssh/config
при использовании IP-адресов в качестве имен хостов. Дополнительное усложнение заключается в том, что вы подключаетесь не только к разным IP-адресам, но и к разным портам, так как это практически исключает любую подстройку вашего DNS resolver.
Я исправлен - вы можете использовать Match originalhost ... exec ....
комбо в ~/.ssh/config
- см. @ Ответ Михал-Политовского . Однако, несмотря на то, что OpenSSH будет отлично работать, вы не обязательно найдете аналогичную функциональность в других SSH-клиентах.
Вы можете обойти проблему, используя простую обертку (либо функцию оболочки, либо скрипт, если вам нужно использовать его из различных оболочек) для ssh
, которая проверит, в какой сети вы находитесь, и воспользуется соответствующей записью Host
. Большой вопрос заключается в том, как надежно определить, в какой сети вы находитесь. Локальный IP-адрес приходит на ум, но не является надежным, так как вы, возможно, подключаетесь из локальной сети, которая использует ту же подсеть, что и ваша рабочая сеть.
Если вы можете иметь один и тот же порт как для локальной, так и для удаленной сети, вы можете отредактировать свой /etc/resolv.conf
в зависимости от сети, в которой вы находитесь - очевидно, это должно быть сделано автоматически (скорее всего, с помощью скрипта перехвата сообщений вашего DHCP-клиента). Или - лучше - запустить локальный сервер имен (например, dnsmasq
) и снабдить его соответствующей конфигурацией. Однако это выходит за рамки данного вопроса.
Другой вариант - если вам нужно подключиться только интерактивно - это использовать завершение команды, которая будет сканировать ~/.ssh/config
. Это сэкономит вам немного времени на набор текста (особенно если у вас достаточно различных записей Host
). Что-то вроде этого (для инициализации bash
):
# complete session names for ssh
declare -g _ssh_complete_hostlist 2> /dev/null
function _ssh_complete_init () {
_ssh_complete_hostlist=$( \
sed -nr '/^\s*Host\s*=/{s/^[^=]+= *//;s/ /\n/g;p}' ~/.ssh/config \
| sort )
}
_ssh_complete_init
function _ssh_complete () {
local match=${COMP_WORDS[${COMP_CWORD}]}
local hosts=
local default=
for h in $_ssh_complete_hostlist; do
if [[ $h =~ ^$match ]]; then
hosts="$hosts $h"
fi
done
if ! (( ${COMP_CWORD} == ${#COMP_WORDS[@]}-1 )); then
default=$( compgen -f ${COMP_WORDS[${COMP_CWORD}]} )
fi
COMPREPLY=($hosts $default)
}
complete -F _ssh_complete ssh
Первая функция создает список, из которого завершается работа хостов (обычно достаточно запустить его один раз в каждой оболочке), вторая делает фактическое завершение, хотя и немного неуклюже - она завершает имя хоста только тогда, когда это последняя лексема в командной строке.
Все это говорит о том, что правильным способом решения этой проблемы является подключение к рабочей сети через VPN и, таким образом, доступ к локальному рабочему IP-адресу, как будто вы находитесь в офисе. Затем вы можете жестко связать адрес с любым уровнем, который вы предпочитаете: ~/.ssh/config
, /etc/resolv.conf
или (лучший вариант imho) сервер имен офиса.
Не знаю, возможно ли это сделать через ~/.ssh/config
, но другой подход будет заключаться в подключении к тому или иному устройству на основе вашего внешнего IP-адреса. Так как, предположительно, когда вы работаете, ваш IP будет 55.22.33.NNN
, вы можете запустить что-то вроде:
[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] &&
ssh 192.168.1.100 ||
ssh -p 12345 55.22.33.99
Еще более простой подход заключается в использовании вашего внутреннего IP. Я не знаю, как настроены две ваши сети, но если легко определить, работаете вы или нет по вашему IP (например, если у вас есть определенный IP на работе, такой как 192.168.1. 12
), вы можете сделать (изменить eth0
на любое имя вашей сетевой карты):
[[ $(ip address show dev eth0 | grep -Po 'inet \K[\d.]+') = '192.168.1.12' ]] &&
ssh 192.168.1.100 ||
ssh -p 12345 55.22.33.99
Что бы вы ни решили использовать, вы можете добавить его в качестве псевдонима в вашу оболочку (добавьте эту строку в файл инициализации оболочки, ~/. bashrc
, если вы используете bash
):
alias gamma="[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] && ssh 192.168.1.100 || ssh -p 12345 55.22.33.99
Вы также можете сделать это в скрипте, если хотите, чтобы другие скрипты имели к нему доступ (псевдонимы из .bashrc
не считываются при выполнении скрипта).
После того, как не удалось получить что-то, что работает во многих средах (, например. Hostname -I
не работает в git bash ), я остановился на чем-то более ручном, немного более надежном и немного менее причудливом:
Match originalhost gamma exec "[ -e ~/.ssh/gamma.local ]"
HostName 192.168.1.100
Port 22
Host gamma
User andreas
Port 12345
HostName 55.22.33.99
Затем touch ~/.ssh/gamma.local
на машинах в той же сети.