我公司的生产服务器(FOO、BAR……)位于两台网关服务器(A、B)后面。为了连接到服务器 FOO,我必须使用我的用户名 JOHNDOE 与服务器 A 或 B 打开 ssh 连接,然后从 A(或 B)我可以使用标准用户名(我们称之为 WEBBY)打开 SSH 连接来访问任何生产服务器。
所以,每次我都要做类似的事情:
ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server
你可以想象,当我需要使用scp
或者需要快速打开多个连接时,这很麻烦。
我已经配置了 ssh 密钥,并且我正在使用 .ssh/config 作为一些快捷方式。
我想知道我是否可以创建某种 ssh 配置以便输入
ssh foo
并让 SSH 为我打开/转发所有连接。可以吗?
编辑
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
答案1
作为 Kyle 答案的更具体版本,您想要在文件中放入的内容~/.ssh/config
是:
host foo
User webby
ProxyCommand ssh a nc -w 3 %h %p
host a
User johndoe
然后,当您运行“ssh foo”时,SSH 将尝试通过 SSH 连接到johndoe@a
,运行netcat
( ),然后通过此隧道nc
执行 SSH 连接到。太神奇了!webby@foo
当然,为了做到这一点,需要在网关服务器上安装 netcat;这个软件包适用于每个主要发行版和操作系统。
答案2
您可以在 ~/.ssh/config 文件中使用 ProxyCommand 指令,例如使用 netcat 作为中继:
host server2
ProxyCommand ssh server1 nc server2 22
您只需使用“ssh server2”。此指令的手册页信息可在“man ssh_config”中找到
答案3
我更喜欢一种不同的方法,即维护到网关服务器的预认证隧道。在~/.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”的调用将几乎立即通过预先验证的隧道打开。
效果很好。
答案4
当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
应该给你一个shell machine2
,通过隧道传输machine1
。
我想知道使用自定义sed
命令是否dirname
不能解决basename
不同用户名的问题?