基于主机名或始发IP的dynamic端口转发

我是一个程序员,试图找出一些超出我的领域的东西:

说我有一台机器,客户端将使TCP(但不是http!)连接到它。 我想根据他们连接到的主机名将客户端redirect到他们自己的端口。 例如,client1连接到client1.myserver.com并连接到端口1234. client2.myserver.com – > 1235,client3.myserver.com – > 1236等

我想dynamic地控制主机y的端口x实际上指向物理机器上的端口z。

当search这个信息,我看到防火墙,代理,反向代理的参考。 我真的需要哪些软件? 现有的软件是否允许按需更改(我听说防火墙需要一天的更改)?

如果我想自己编写这样一个层(因为它可能有点特定于应用程序),是否可以在java或node.js中完成(我的意思是可以使用更高级别的API来完成,或者我必须开始拆分ip包)? 我怎么知道客户端连接到哪个主机名,因为所有的主机名都parsing到同一台机器上?

我会很欣赏任何阅读材料的指针。

在IP层面上,不存在主机名。 主机名是IP地址的应用程序级别抽象,在Internet或传输层,它们不具有任何意义。

在HTTP共享主机中,这个技巧在处理HTTP会话的过程中被抽象出来,这发生 TCP会话开始之后。 正是由于这个原因,运行SSL服务器需要一个专用IP地址很长时间,因为SSL会话发生在HTTP之前(这已经在更新的TLS版本中被修复,其中HOSTNAME现在可以作为SSL协商的一部分包括在内)。

对于一个共享主机的HTTP实例,这些协议大致按这个顺序进行协商:

TCP -> SSL -> HTTP 

每个协议直到早期的协议完成才能启动。 直到最近,只有链中的最后一步才知道主机名,这就是为什么由Web服务器软件来处理主机名与IP的多对一关联。

对于一个dynamic的端口转发,只有当应用程序协议知道主机名的时候,这才是可行的。 某些设备(无论是软件还是硬件)处理与客户端的初始TCP连接以及应用协议的第一步(不pipe是什么),并根据接收到的内容将连接转发到最终目的地。

所需的确切步骤取决于应用程序协议本身。 有些像HTTP一样,包含一个HOSTNAME头,表示客户希望与之通话的主机名。 其他,像一些微软协议,利用基于DNS的SRVlogging来确定一个精确的IP 端口组合。 由于听起来您可能正在devise自己的应用程序协议,所以我build议遵循HTTP的要求,并在初始协议谈判步骤中包含一个HOSTNAME标头。

您可以使用DNS中的SRVlogging轻松实现这一点:

http://en.wikipedia.org/wiki/SRV_record

你能用更清楚的术语来描述你想要做什么,为什么? “为什么”将有很大的帮助。 什么是客户? 协议是什么?

根据协议和数据stream,有很多方法可以做到这一点。

考虑pf,iptables或者ebtables注入,例子见“ssh黑名单”。 看看LVS,HAproxy和其他负载平衡器的一般redirect。

一个古老的伎俩是一个“唤醒”系统。 这对于SSH或者其他encryption的协议非常有用,这使得它更加强大的cpu来确定源域。(解docker)这样只有一个端口在没有连接的情况下运行。

  • SSH到一个单一的开放端口(不需要terminal支持)
  • 以userXlogin系统(最好是使用密钥),这将运行一个脚本,在端口XXXXX上启动另一个服务器实例,并用新的端口号
  • “端口XXXXX打开”消息被传回客户端,初始ssh会话closures
  • 客户端或客户端应用程序,然后重新连接使用现在打开的端口XXXXX
  • 当客户端断开时,端口XXXXX上的备用实例closures和/或端口XXXXXclosures。

特定的端口可以根据键/用户进行分配,反向查找,消息传递等。有些只是使用pf / iptables防火墙注入来使实例运行并打开/closures。 其他人使用防火墙规则来扩展这个规则,以触发服务启动,并且没有初始的SSH(或其他服务)运行,直到指定的端口被特定types的数据包占用。 我更喜欢“最近匹配”的自定义防火墙规则来阻止stream氓数据包,并停止/启动服务器实例,以便与防火墙进行dynamic交互。

这个想法可以用任何可以编码或编写脚本的协议和服务。

TCP / IPnetworking阅读材料:W. Richard Stevens撰写或推荐的任何内容。 http://www.kohala.com/start/

不要使用SSH隧道作为开发中的优势。 这些可以实现您无需代码所需的一切。 你的应用程序是什么? 不应该是沟通安全吗? 你将如何黑名单脚本小子黑客? 这是更多,你将不得不编写和debugging。 你应该把你的代码分隔开来,所以使用SSH作为传输,端口转发,encryption,使用日志logging,黑名单等来开发所有的东西。然后当其他事情完成时,编写你自己的networking协议机制来代替SSH。 网关SSH服务器上的用户不需要使用terminal接入来使用隧道。