通过 PHP/CGI/等确定 SSH Web 隧道上的原始主机

通过 PHP/CGI/等确定 SSH Web 隧道上的原始主机

我有许多具有动态 IP 地址的主机,它们需要能够在我确定的不同时间访问某个本地网站上的内容。允许访问的时间总是不同的。我管理所有将连接的主机。

当我希望主机能够访问私有网站时,我将从每个主机启动到 Web 主机上的帐户的 SSH 隧道。现在,用户将能够通过http://本地主机。当该机器不再能够访问该网站时,隧道将被关闭。

在私人网站上,我可以运行 PHP 脚本/Python/CGI/等。我需要能够识别连接的主机,因为我提供的信息将根据连接的主机而不同。如果我在 PHP 中执行主机名查找,我当然会获得 Web 服务器的主机名。每个客户端连接都会发生这种情况。我希望能够访问客户端主机名。更糟糕的是,客户端将具有动态主机名。我并不真正关心该名称。我为每个主机都有一个固定名称,该名称位于系统上的一个文件中 - 例如 /etc/fixedhostname。

当我创建 SSH 连接时,我可以存储哪些信息,以便从 PHP/CGI/Python/等。我可以查询连接主机的主机名。

更新:
为了让我的疑问不那么神秘...客户端是不同计算机实验室的学生机器(由我运行)。Web 服务器提供实验室测试的测试问题。不同的实验室可能同时处理不同的测试。我想找到一种方法来找出“真正的”源主机(无需询问学生)。我可以将其传入:http://localhost?host=myhost,但另一个测试的学生只需更改 URL 就可以看到另一个测试的问题。我可以对主机名进行编码,然后对其进行解码,但学生仍然可以共享 URL。只有测试模式下的主机才能访问 Web 服务器。最初,我想使用 OpenVPN 来实现这一点,但我认为创建 CA 并管理所有不同的密钥仅仅是为了管理对网站的访问,这似乎有点小题大做,但也许并非如此。我认为 SSH 可能更容易。我最初认为我可能只需传递一些 PHP 可能能够访问的信息来确定主机的真实身份。

答案1

如果您的学生从基于 Linux 的机器连接,您可以使用此连接脚本:

#!/bin/bash ssh student@webserver -R 5000:localhost:22 ssh user@localhost sh -c 'hostname >> hostnames.txt; date >> hostnames.txt' ssh student@webserver -L 80:localhost:80

这里有两个 ssh 命令。

第一个用于将有关学生机器主机名和连接时间戳的信息写入hostname.txtWeb 服务器机器上的文件。 student@webserver是学生通过 ssh 登录 Web 服务器的 ssh 地址, 是user@localhost通过反向隧道从 Web 服务器登录学生机器的地址。 应使用 ssh 密钥进行此反向连接,以便摆脱密码调用(只需使用Web 服务器的ssh-keygen -r RSA命令来创建基于密钥的身份验证)。ssh-copy-id [email protected]

第二个 ssh 命令用于建立主隧道,以便学生可以使用localhost:80ie连接到 Web 服务器的 80 端口http://本地主机/在他的本地机器上。

您可以将远程命令(主机名和日期)组合到某个远程脚本中,以防止学生对其进行可能的更改。此外,您还可以hostname.txt使用 grepedifconfig命令或类似命令将一些 IP 相关信息添加到文件中。

如果您的学生从基于 Windows 的机器连接,您可以在服务模式下将轻量级 freeSSHd 服务器安装到 Windows 中,并进行基于密钥的身份验证以进行反向隧道连接。

答案2

假设可以使用 https,您可以创建一个 CA 并使用客户端证书,其中每个客户端都有一个唯一的证书,其属性可以记录(例如 common_name)。

话虽如此,我想知道是否有更好的策略是放弃 SSH 隧道并改用 OpenVPN。这样,您可以为每个设备提供自己的(私有)静态 IP,并且可以使用 iptables 规则控制访问时间。这也意味着您可以使用标准 PHP 指令(如 $_SERVER["remote_addr"])使编程更容易。您还可以继续使用 http(同时仍受益于加密),并且在客户端以编程方式使用它要容易得多。

答案3

用户可以通过以下方式访问网站内容http://本地主机

您可以使用类似域名lvh.me(我认为是“本地虚拟主机”的缩写)来代替 localhost。有人将其注册为映射到 127.0.0.1 的全局 DNS(因此,无需对文件进行任何黑客攻击hosts),并且它支持子域名,例如http://user1.lvh.me或者,如果您不信任用户尝试其他子域,则可以使用一些随机的难以猜测的子域。最后,在您的服务器端代码中,使用标Host头查看谁在连接。

相关内容