有没有基于名称的虚拟主机SSH反向代理?

我在开发环境中非常喜欢HTTP反向代理,并发现基于DNS的虚拟主机反向代理非常有用。 只有一个端口(和标准端口)在防火墙上打开使得pipe理更容易。

我想find类似SSH连接的东西,但没有太多的运气。 我不想简单地使用SSH隧道,因为这需要打开标准以外的端口范围。 有什么可以做到的吗?

HAProxy可以做到吗?

我不认为基于名称的SSH是可能的,因为协议是如何工作的。

这里有一些替代品。

  • 你可以做的是设置主机,回答端口22作为一个网关。 然后你可以configurationssh服务器根据密钥将请求转发到里面。 SSH 网关示例与密钥

  • 您可以调整您的客户端以使用该主机作为代理。 也就是说,它将SSH网关主机,然后使用该主机连接到内部主机。 具有客户端configuration的 SSH代理。

  • 你也可以在边上设置一个简单的http代理。 然后使用它来允许传入的连接。 通过HTTP代理的 SSH。

显然,以上所有,确保您正确configuration和locking网关是非常重要的。

在过去的16个月里,我一直在寻找解决这个问题的方法。 但是每次我看,似乎都不可能用相关的RFC中规定的SSH协议来实现这一点,并通过主要的实现来实现。

但是,如果您愿意使用稍微修改过的SSH客户端,并且您愿意使用那些在devise时不完全适用的协议,则可以实现这一点。 更多关于这个下面。

为什么这是不可能的

客户端不会将主机名作为SSH协议的一部分发送。

它可能会发送主机名作为DNS查找的一部分,但可能会被caching,从客户端到parsing器到授权服务器的path可能不会跨越代理,即使这样做,也没有可靠的方法将特定的DNS查找与特定的SSH客户端。

SSH协议本身也没什么特别的。 你甚至没有看到来自客户端的SSH版本横幅,就select一台服务器。 在向客户端发送任何内容之前,您必须向客户端发送一个标语。 从服务器的横幅可能是不同的,你没有机会猜测,哪一个是正确的使用。

即使此横幅未经encryption发送,您也无法对其进行修改。 在连接设置过程中,该横幅的每一位都将被validation,所以你会导致连接失败。

对我的结论是非常清楚的,人们必须改变客户端的一些东西,以使这种连接工作。

大多数解决方法是将SSHstream量封装在不同的协议中。 人们也可以想象SSH协议本身的一个附加,其中由客户端发送的版本横幅包括主机名。 这可以与现有服务器保持兼容,因为部分横幅当前被指定为自由格式标识字段,并且虽然客户端通常在发送自己的服务器之前等待来自服务器的版本横幅,但该协议确实允许客户端发送他们的横幅第一。 一些最新版本的ssh客户端(例如Ubuntu 14.04上的那个版本)不会等待服务器横幅发送横幅。

我不知道任何客户端,已经采取措施,包括服务器的主机名在这个横幅。 我已经向OpenSSH邮件列表发送了一个补丁来添加这样的function。 但它被拒绝的基础是不希望任何人窥探SSHstream量的主机名。 由于秘密主机名与基于名称的代理的操作基本上是不兼容的,因此不要期望很快就会看到SSH协议的官方SNI扩展。

真正的解决scheme

最适合我的解决scheme实际上是使用IPv6。

在IPv6中,我可以为每个服务器分配一个单独的IP地址,因此网关可以使用目标IP地址找出将数据包发送到哪个服务器。 SSH客户端有时可能在networking上运行,只有通过使用Teredo才能获得IPv6地址。 已知Teredo是不可靠的,但只有当连接的本地IPv6端使用公共Teredo中继时。 可以简单地在网关上放置一个Teredo中继,在那里运行代理。 Miredo可以在不到五分钟的时间内安装和configuration为继电器。

解决方法

您可以使用跳转主机/堡垒主机。 此方法适用于您不希望将单个服务器的SSH端口直接公开给公共Internet的情况。 它在减lessSSH所需的外部IP地址的数量方面具有额外的好处,这就是为什么在这种情况下可以使用它的原因。 事实上,这是一个解决scheme的目的是为了安全起见添加另一层保护,并不妨碍您在不需要增加的安全性时使用它。

ssh -o ProxyCommand='ssh -W %h:%p user1@bastion' user2@target 

如果真正的解决scheme(IPv6)不在您的范围之内,那么这是一个肮脏的工作,以使其发挥作用

我将要描述的黑客只能作为绝对最后的手段。 在你考虑使用这个黑客之前,我强烈build议你为每一台你想通过SSH从外部访问的服务器获取一个IPv6地址。 使用IPv6作为访问您的SSH服务器的主要方法,并且只在需要从仅对IPv4部署IPv6没有任何影响的IPv4networking上运行SSH客户端时才使用此黑客技术。

这个想法是,客户端和服务器之间的stream量需要是完全有效的SSHstream量。 但是代理只需要充分了解数据包的stream识别主机名。 由于SSH没有定义发送主机名的方式,所以可以考虑其他提供这种可能性的协议。

HTTP和HTTPS都允许客户端在服务器发送任何数据之前发送主机名。 现在的问题是,是否可以构build一个同时适用于SSHstream量和HTTP和HTTPS的字节stream。 HTTPs几乎是不起步的,但是HTTP是可能的(对于HTTP的足够自由的定义)。

 SSH-2.0-OpenSSH_6.6.1 / HTTP/1.1 $: Host: example.com 

这看起来像SSH还是HTTP给你? 它是SSH并且完全符合RFC(除了一些二进制字符被SF渲染弄坏了一点)。

SSH版本string包含一个注释字段,其中上面的值为/ HTTP/1.1 。 换行符后,SSH有一些二进制数据包的数据。 第一个数据包是由客户端发送并被服务器忽略的MSG_SSH_IGNORE消息。 有效载荷被忽略的是:

 : Host: example.com 

如果一个HTTP代理的接受程度足够自由,那么相同的字节序列将被解释为一个名为SSH-2.0-OpenSSH_6.6.1的HTTP方法,并且在该忽略消息开始时的二进制数据将被解释为一个HTTP标题名称。

代理将不理解HTTP方法或第一个头。 但它可以理解Host头,这是find后端所需要的。

为了实现这个function,代理服务器的devise原则是只需要了解足够的HTTP以查找后端,一旦发现后端代理服务器将简单地传递原始字节stream,并保留真正的终止HTTP连接由后端完成。

对HTTP代理做出如此多的假设听起来有些费解。 但是,如果您愿意安装一个旨在支持SSH的新开发的软件,那么HTTP代理的要求听起来不会太糟糕。

在我自己的情况下,我发现这种方法工作在一个已经安装的代理,没有改变代码,configuration,否则。 这是一个代理只写HTTP和没有SSH的头脑。

概念客户端和代理的certificate。 (免责声明代理服务是由我操作的服务,一旦确认任何其他代理支持此用法,请随时更换链接。)

注意这个黑客

  • 不要使用它。 最好使用真正的解决scheme,即IPv6。
  • 如果代理尝试了解HTTPstream量,那肯定会中断。
  • 依靠修改后的SSH客户端并不好。

我不相信这是可能的,至less是你描述的方式,尽pipe我很乐意被certificate是错误的。 看起来,客户端并没有发送它希望连接到的主机名(至less在明文中)。 SSH连接的第一步似乎是设置encryption。

此外,您将有主机密钥validation问题。 SSH客户端将根据IP地址以及主机名来validation密钥。 您将拥有多个不同密钥的主机名,但是您要连接的是同一个IP。

一个可能的解决scheme将是有一个“堡垒”的主机,客户端可以SSH进入该机器,得到一个正常的(或限制,如果需要)壳,然后可以ssh到内部主机从那里。

我想知道是否无法修改具有代理模式的Honeytrap(低交互蜜jar)来实现这一点。

这蜜jar能够将任何协议转发到另一台计算机。 添加一个基于名称的虚拟主机系统(由Apache实施)可以使它成为任何协议的完美反向代理不?

我没有这方面的技能,但也许这可能是一个伟大的项目。

随着您想要访问防火墙的端口/主机数量的增加,VPN的便利性也随之增加。

不过,我不喜欢VPN。

因为如何ssh的作品,我认为这是不可能的。 与https类似,你将不得不为不同的主机设置不同的(外部)IP,因为网关不知道你要连接到哪里,因为ssh中的所有东西都被encryption了

这个街区有一个新的孩子。 SSH piper将根据预定义的用户名来路由你的连接,这应该被映射到内部主机。 这是逆向代理的最佳解决scheme。

SSH吹笛者在github上

我的第一个testing证实,SSH和SFTP都可以工作。