查找原始计算机(ssh)的IP或主机名


10

我不断地从不同的物理位置(以及不同的物理计算机)连接到许多计算机。大多数操作都是通过ssh完成的,有时需要一两台网关计算机(我通过ProxyCommandin 调用~/.ssh/config)。我想知道是否有一种方法可以识别在远端调用初始连接(即我正在使用的计算机)的计算机的IP或主机名?

  • 我不想发送环境变量,因为有些机器我没有root可以设置PermitUserEnvironment
  • $SSH_CLIENT环境变量是用于直接连接有用,但只列出最近的网关。

我目前对解决方案的想法是抓取$SSH_CLIENT,ssh到它,找到该机器的$SSH_CLIENT值并重复执行直到不存在为止。然后获取主机名并以某种方式将其拉回。

不过,这似乎有点骇人听闻。有谁有更好的方法?

我主要是在bash shell中工作,但是对于不使用它的任何建议我也很满意。


ProxyCommand的目的之一当然是隐藏(或忘记)原始主机(例如,无论如何都无法与最终主机路由)
Hagen von Eitzen

您能否举个例子,说明在何处或为何需要此信息?可能还有其他非显而易见的解决方案。
Manwe

@Manwe我最终想要在诸如.bashrc之类的内容中设置特定于语言环境的部分。现在,我要做的就是根据我在哪台计算机上自动在vim中设置三个键盘布局之一。
Geodesic

Answers:


3

我从未尝试过,但是我能想到一些可行的方法:您不要让SSH启动登录外壳程序,而是自己处理问题。您可以告诉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(您可能需要更改它)。

我们执行的技巧是将命令放在double qoutes中远程执行"。双引号(至少用Bash表示)表示,在将字符串传递给SSH之前,我们的shell会对其进行扫描并在适当的情况下执行扩展/替换。这意味着我们的外壳将评估`$(ifconfig ...)部分为我们当前的IP地址,并向ssh传递一个字符串,该字符串包含带有我们本地IP地址的环境变量的定义。

登录到远程计算机后,echo $DAT_ORIGIN_HOST应打印您的IP地址。

为了开发对SSH的调用,我毫不客气地从这里提取IP地址,从这里提取-t以及如何启动交互功能

免责声明:我不确定的-l-i选项/bin/bash。也许您需要忽略它们。


您可能会喜欢这里的东西!我会玩一会儿再给你。
Geodesic

我正在标记此答案,因为伪tty和远程命令都可以使用。最终,根据远程命令建议,我使用^ E回调解决了我的特殊情况-最终它变得更干净,更通用了。谢谢!
Geodesic

2

Id我正确理解,您是直接从源计算机通过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远程转发来识别主机或主机类型。

# 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

感谢您的建议,但至今仍未完全满意。远程端口转发不是一个坏主意,但必须假设所有主机上的用户名都相同。这里不是这种情况,我也不能改变。第二:我无法使它正常工作。你是说AcceptEnv LC_*一般允许的,但不是一个标准的,由默认设置?
Geodesic

好吧,LC_被击中了。我无法评论这种情况的普遍性,但这可能是可行的..(请记住在ssh连接之前导出LC_SOURCEHOST)。
Manwe,

测试了LC_ *,它可以工作。它可以是AcceptEnv指令中列出的任何变量/etc/ssh/sshd_configsshd如果此文件被更改,请记住重新启动。
david.perez

1

您可以who -m在远端键入以获取有关当前登录用户(包括主机名)的信息。who为您提供有关已登录用户的信息,并且该-m开关将向您显示“仅主机名和与stdin关联的用户”。


但是,这仅在我不通过网关计算机进行隧道传输时才有用。
Geodesic

0

您尝试了以下吗?

 netstat -an | grep " 22 "

此方法仅对单跳连接有用,因此对我没有用。
Geodesic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.