Как настроить ярлык для подключения SSH через туннель SSH
Серверы моей компании (FOO, BAR ...) расположены за двумя серверами шлюза (A, B). Чтобы подключиться к серверу FOO, мне нужно открыть ssh-соединение с сервером A или B с моим именем пользователя JOHNDOE, затем с A (или B) я могу получить доступ к любому производственному серверу, открыв SSH-соединение со стандартным именем пользователя (назовем его Webby).
Итак, каждый раз мне приходится делать что-то вроде:
ssh [email protected]
...
ssh [email protected]
...
# now I can work on the server
Как вы можете себе представить, это хлопот, когда мне нужно использовать scp
или мне нужно быстро открыть несколько подключений.
Я настроил ssh-ключ, а также я использую .ssh /config для некоторых ярлыков.
Мне было интересно, могу ли я создать какую-то конфигурацию ssh для ввода
ssh foo
и пусть SSH открывает /переводит все соединения для меня. Возможно ли это?
Edit
Ответ womble - это именно то, что я искал, но кажется, что сейчас я не могу использовать 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
8 ответов
Как более конкретная версия ответа Кайла, вы хотите добавить в свой файл ~/.ssh/config
:
host foo
User webby
ProxyCommand ssh a nc -w 3 %h %p
host a
User johndoe
Затем, когда вы запустите «ssh foo», SSH попытается выполнить SSH на [email protected]
, запустите netcat
(nc
), затем выполните SSH для [email protected]
через этот туннель. Магия!
Конечно, для этого netcat необходимо установить на сервере шлюза; этот пакет доступен для каждого основного дистрибутива и ОС.
Вы можете использовать директиву ProxyCommand в файле ~ /.ssh /config, например, чтобы использовать netcat в качестве реле:
host server2
ProxyCommand ssh server1 nc server2 22
Вы просто используете 'ssh server2'. Информация о man-странице для этой директивы находится в 'man ssh_config'
Я предпочитаю другой подход, который поддерживает туннель с предварительной аутентификацией на сервере шлюза. В ~/.ssh/config
:
Host a
ControlMaster auto
ControlPath ~/.ssh/control-master/%[email protected]%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/[email protected]:22 ]]
then
echo "Deleting stale socket..."
rm ~/.ssh/control-master/[email protected]:22
fi
echo "Opening master session..."
if ssh -Nf a
then
ssh -t a ssh $1
fi
fi
}
Итак, чтобы подключиться к foo:
s foo
При первом подключении он будет аутентифицировать вас против «a» и открыть постоянный туннель ssh. Последующие вызовы «s» откроются почти мгновенно через предварительно пропущенный туннель.
Отлично работает.
Этот тип функциональности существует в новых версиях OpenSSH и может использоваться при выполнении
ssh -W server2 server1
Где server2
- ваш предназначенный пункт назначения и server1
- ваш прокси-узел. Вы можете сделать это проще, используя опцию ProxyCommand
в вашей конфигурации ssh, например:
host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1
Если 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 на (т.е. с помощью команды -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
и basename
может не решить проблему с разными именами пользователей?
Это можно сделать, выполнив ssh -At [email protected] ssh [email protected]
. Команда -A
перенаправляет ваш агент ssh (так что вы можете избежать повторной аутентификации на прокси-сервере), а -t
гарантирует наличие терминала в прокси-сервере. Может оказаться полезной следующая функция bash:
ssh-bounce () {
local cmd=""
for i in "[email protected]"; do
cmd+="ssh -At $i "
done
$cmd
}
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found
Netcat не установлен на a
. Когда вы запускаете ssh host "command arg"
, command
на host
, а не на вашем локальном компьютере.
Так как OpenSSH 7.3 (2016-08-01) опция ProxyJump
и соответствующий -J
, чтобы обеспечить более простую косвенность через один или несколько бастионов SSH или «прыгать с хостов».
Это удаляет зависимость от внешней команды nc
, как показано в Решение Womble .
ssh -J [email protected] [email protected]
установит SSH-соединение с вашей рабочей станции на сервер шлюза a
как пользователь johndoe и туннелирует сеанс SSH для размещения foo для пользователя Вебби над этим.
Чтобы упростить создание определений хостов в вашем ~/.ssh/config
, и вы можете просто выполнить ssh foo
Host a
User johndoe
Host foo
User Webby
ProxyJump a