我经常从不同的物理位置(因此是不同的物理机器)连接到多台机器。大部分操作都是通过 ssh 完成的,有时需要一台或两台网关机器(我通过ProxyCommand
in调用~/.ssh/config
)。我想知道是否有一种方法可以识别在远程端调用初始连接的机器(即我正在使用的机器)的 IP 或主机名?
- 我不想发送环境变量,因为有些机器我没有根权限来设置
PermitUserEnvironment
。 - 环境
$SSH_CLIENT
变量对于直接连接很有用,但只列出最近的网关。
我目前的解决方案是抓取$SSH_CLIENT
,通过 ssh 连接到它,找到该机器的$SSH_CLIENT
值并重复,直到它不存在;然后抓取主机名并以某种方式将其拉回来。
虽然这看起来有点像黑客行为;有人有更好的方法吗?
我主要在 bash shell 中工作,但我也很高兴听到任何不使用它的建议。
答案1
我从未尝试过,但我能想到一个可能有效的方法:不要让 SSH 启动你的登录 shell,而是自己处理。你可以告诉 SSH 运行任意命令。而不是
ssh remote_host
你会运行类似
ssh remote_host -t "
. /etc/profile;
. /etc/bash.bashrc;
DAT_ORIGIN_HOST=$(ifconfig eth0|grep -Po 't addr:\K[\d.]+') /bin/bash -l -i"
这样做的目的是,它让 SSH 可以做其他事情,而不是启动登录 shell。这个事情是一个字符串,它将作为命令远程运行。我们使用它以一种非常特殊的方式启动 shell:我们给它一个环境变量DAT_ORIGIN_HOST
,其中包含我们在 eth0 上的 ip(您可能需要更改它)。
我们采用的技巧是将要远程执行的命令放在双引号中"
。双引号(至少在 Bash 中)意味着,在将字符串传递给 SSH 之前,我们的 shell 会对其进行扫描并在适当的情况下执行扩展/替换。这意味着我们的 shell 将评估 `$(ifconfig ...) 部分,将其转换为我们当前的 ip 地址,并向 ssh 传递一个字符串,该字符串包含具有我们本地 ip 地址的环境变量的定义。
一旦登录到远程机器,echo $DAT_ORIGIN_HOST
就应该打印您的 IP 地址。
为了开发对 SSH 的调用,我厚颜无耻地从此处用于提取 IP 地址和这里是 -t 以及如何启动交互式的东西
免责声明:我不确定-l
和-i
选项/bin/bash
。也许你需要省略它们。
答案2
如果我理解正确,您是通过跳数直接从源计算机连接到目的地的proxycommand
。因此,这里有三个技巧供您使用(第三个是在使用场景评论后添加的)。第一)使用远程端口转发,允许您使用-R remotemachineport:dstonlocalnet:dstportonlocalnet
ssh -R 2222:localhost:22 user@target
# on "target" you can now do this to get back to origin host
ssh user2@localhost -p 2222
第二)滥用AcceptEnv LC_*
目标。虽然不太好,但即使在 AcceptUserEnviconment 不可用的情况下也允许 LOCALE 变量,这很常见。所以现在你可以这样做:
export LC_SOURCEHOST=my.ip.addr.or:something
ssh user@target
# on tathet:
echo $LC_SOURCEHOST
第三)使用 ssh remote forward 来识别主机或主机类型。
# Here is an example what you can use on target machine.
# This will modify your PS1 variable (prompt) based on source host (port forwarding)
# Add this to .bash_profile
function checkHost {
RET=""
## loop over test port numbers 17891-17895 in my example
for x in $(seq 1 5); do
# if netstat is not available test port some other way like with nc or something
## && RET= will set RET = 1-5
/bin/netstat -lnt|/bin/grep -q 127.0.0.1:1789$x && RET=$x;
done
# return RET
# please note that if you have multiple open connections with different port numbers
# this method cannot not distinguish between them
echo $RET
}
# get 1-5 number from function above
VAL=$(checkHost)
# do something like set PS1 var or map vim file or something
export PS1='\[\033k\033\\\]\u@\h: \w\$ '$VAL
现在连接端口转发:
### this will still enable ssh forwarding back. Change 22 to something else like
### 24 to disable it (if nothing is listening on your source machines 24 port)
ssh -R 17891:localhost:22 user@target
答案3
您可以who -m
在远程端输入以获取有关当前登录用户的信息(包括主机名)。who
为您提供有关登录用户的信息,并且开关-m
显示“仅与 stdin 关联的主机名和用户”。
答案4
您尝试过以下操作吗?
netstat -an | grep " 22 "