71

TL;博士:

域的 DNS 解析必须映射到IP:port(s),而不仅仅是IP

例子,

sub1.example.com 1.2.3.4:567
sub2.example.com 1.2.3.4:678

我可以修改 DNS 记录。


我拥有“Arboristal.com”域。我还在 arboristal.com 上私下拥有所有子域。例如 lg.arboristal 或 ft.arboristal.com。

在我的 DNS 设置下,Arboristal.com 设置为访问我们当前托管我们网站的网络主机。

我家有三台服务器运行在一个公共 IP 地址下。(71.82.237.27)

我还有 Arboristal.com 的三个子域指向我的 IP 地址。

三台服务器中的每台都在各自的端口上运行(25565、25566、25567)

我希望每个子域都指向我的 IP 地址上的每个开放端口。

不幸的是,当您尝试使用其中一个子域连接到其中一台服务器时,它只会连接到您为其键入端口的服务器。

我的情况:

三台服务器,每台运行在不同的端口上。(所有端口转发并作为服务器工作)

  • 我的世界服务器一 (25565)

  • Minecraft 服务器二 (25566)

  • Minecraft 服务器三 (25567)

我的 DNS 提供商 (webs.com) 上运行了三个子域

  • mc.arboristal.com

  • tekkit.arboristal.com

  • pvp.artboristal.com

当您使用 Minecraft 连接到其中一个时,它会通过端口 25565 自动连接,这意味着无论您尝试连接什么 URL,它始终会使用端口 25565 访问我的 IP。将您连接到 Minecraft 服务器一。您可以手动输入端口,但我宁愿让它尽可能美观和专业。

那么,既然你知道了我的情况,有什么方法可以让 mc.arboristal.com、tekkit.arboristal.com 和 pvp.arboristal.com 都在不同的端口下访问我的 IP 地址,而无需指定每个端口在提供的 URL 中连接到用户端?

我可以将 MX、A(使用此连接到服务器)、CNAME 和 TXT 记录添加到 DNS 设置

如果我需要使用第三方作为我的 DNS 提供商,我还可以将名称服务器添加到 DNS 设置中。(如有必要我愿意做)

如果需要在 192.168.0.1 上配置任何内容,我还可以完全访问我的路由器。

我只是在上周才了解互联网的真正运作方式,所以我不确定这里是否真的有任何可能。我也可能没有关于互联网实际运作方式的正确信息。请原谅我可能假设的有关互联网的任何虚假信息。

4

5 回答 5

52

您可以使用SRV 记录

_service._proto.name. TTL class SRV priority weight port target.

服务:所需服务的符号名称。

Proto:所需服务的传输协议;这通常是 TCP 或 UDP。

名称:该记录有效的域名,以点号结尾。

TTL:标准 DNS 生存时间字段。

类:标准 DNS 类字段(始终为 IN)。

优先级:目标主机的优先级,值越低越优先。

权重:具有相同优先级的记录的相对权重。

端口:要在其上找到服务的 TCP 或 UDP 端口。

目标:提供服务的机器的规范主机名,以点结尾。

例子:

_sip._tcp.example.com. 86400 IN SRV 0 5 5060 sipserver.example.com.

所以我认为您正在寻找的是在您的DNS 主机文件中添加类似这样的内容:

_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25565 mc.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 30 25566 tekkit.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 30 25567 pvp.arboristal.com.

(Minecraft 支持 SRV 记录,从 1.3.1 开始,服务名称为minecraft

附带说明一下,我强烈建议您与托管公司合作,而不是自己托管服务器。它只是要求您的家庭连接(DDoS 和带宽/连接速度)出现问题,但这取决于您。

于 2013-10-01T11:36:27.260 回答
14

(我做这些东西已经有一段时间了。请不要盲目地假设下面的所有细节都是正确的。但我希望我不会错得太尴尬。:))


正如前面的答案所述,Minecraft 客户端(从 1.3.1 开始)支持使用服务名称和协议名称查找SRV 记录,这意味着如果您的区域文件看起来像这样......_minecraft_tcp

arboristal.com.                 86400 IN A   <your IP address>
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 20 25565 arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25566 arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25567 arboristal.com.

...然后,按照变更日志中的提示执行 SRV 记录查找的 Minecraft 客户端将优先使用端口 25566 和 25567(各占 40% 的时间),而不是端口 25565(占 20% 的时间)。我们可以假设找到并遵守这些 SRV 记录的 Minecraft 客户端将照常使用端口 25565。


但是,我认为使用负载均衡器(例如Nginx )实际上会更加“干净和专业” 。(我选择 Nginx 只是因为我以前使用过它。我并不是说它特别适合这项任务。出于某种原因,它甚至可能是一个糟糕的选择。)然后你不必弄乱你的 DNS,并且您可以使用相同的方法对任何服务进行负载平衡,而不仅仅是像 Minecraft 这样的服务,它们恰好完成了艰苦的客户端工作来查找和尊重 SRV 记录。要以 Nginx 的方式执行此操作,您可以在arboristal.com机器上运行 Nginx,其中包含以下内容/etc/nginx/sites-enabled/arboristal.com

upstream minecraft_servers {
    ip_hash;
    server 127.0.0.1:25566 weight=1;
    server 127.0.0.1:25567 weight=1;
    server 127.0.0.1:25568 weight=1;
}
server {
    listen 25565;
    proxy_pass minecraft_servers;
}

在这里,我们自己控制服务器端的负载平衡(通过 Nginx),因此我们不再需要担心行为不端的客户端可能更喜欢端口 25565 而不是其他两个端口。事实上,现在所有的客户都会交谈arboristal.com:25565!但是那个端口上的监听器不再是 Minecraft 服务器;它是 Nginx,秘密地将所有流量代理到同一台机器上的其他三个端口。

我们基于客户端 IP 地址 ( ip_hash) 的哈希进行负载平衡,因此如果客户端断开连接然后稍后重新连接,它很有可能会重新连接到它之前拥有的同一个 Minecraft 服务器。(我不知道这对 Minecraft 有多重要,或者启用 SRV 的客户端如何编程来处理这方面的问题。)

请注意,我们曾经在端口 25565 上运行 Minecraft 服务器;我已将其移至端口 25568,以便我们可以将端口 25565 用于负载平衡器。

Nginx 方法的一个可能缺点是它使 Nginx 成为系统中的瓶颈。如果 Nginx 出现故障,则所有三个服务器都将无法访问。如果系统的某些部分无法跟上单个端口 25565 上的流量,那么所有三台服务器都会变得不稳定。更不用说,Nginx 是您生态系统中的一个重要的新依赖项。也许您不想再引入另一个具有复杂配置语言和巨大攻击面的大型软件。我可以尊重这一点。

Nginx 方法的一个可能优势是……它使 Nginx 成为系统中的瓶颈!您可以通过 Nginx 应用全局策略,例如拒绝超过特定大小的数据包,或使用静态网页响应端口 80 上的 HTTP 连接。您还可以从 Internet 上屏蔽端口 25566、25567 和 25568,因为现在它们应该只能由 Nginx 通过环回接口与之交谈。这会在一定程度上减少您的攻击面。

Nginx 还可以更轻松地将新的 Minecraft 服务器添加到您的后端;现在您只需server在配置中添加一行,然后service nginx reload. 使用旧的基于端口的方法,您必须向您的 DNS 提供商添加新的 SRV 记录(86400客户端可能需要几秒钟才能注意到更改),然后还要记住编辑您的防火墙(例如/etc/iptables.rules)以允许该新端口上的外部流量。

Nginx 还让您在进行操作更改时不必考虑 DNS TTL。假设您决定将您的三个 Minecraft 服务器拆分到三个具有不同 IP 地址的不同物理机器上。使用 Nginx,您可以完全通过对server线路的配置更改来做到这一点,并且您可以将这些新机器保留在防火墙内(仅通过私有接口连接到 Nginx),并且根据定义,更改将立即生效。然而,使用 SRV 记录,您必须将您的区域文件重写为类似这样的内容......

arboristal.com.                 86400 IN CNAME mc1.arboristal.com.
mc1.arboristal.com.             86400 IN A   <a new machine's IP address>
mc2.arboristal.com.             86400 IN A   <a new machine's IP address>
mc3.arboristal.com.             86400 IN A   <a new machine's IP address>
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 20 25565 mc1.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25565 mc2.arboristal.com.
_minecraft._tcp.arboristal.com. 86400 IN SRV 10 40 25565 mc3.arboristal.com.

...并且您必须将所有三台新机器都留在防火墙之外,以便它们可以接收来自 Internet 的连接。而且您必须等待86400几秒钟才能让您的客户注意到更改,这可能会影响您的推出计划的复杂性。如果您在 上运行任何其他服务(例如 HTTP 服务器)arboristal.com,现在您必须将它们移动到mc1.arboristal.com机器上,因为我是如何使用 CNAME 的。我这样做只是为了那些不尊重 SRV 记录并且仍将尝试连接到arboristal.com:25565.


所以,我认为两种方式(SRV 记录和 Nginx 负载平衡)都是合理的,您的选择将取决于您的个人喜好。我将这些选项讽刺为:

  • SRV 记录:“我只需要它工作。我不想要复杂性。而且我了解并信任我的 DNS 提供商。”
  • Nginx:“我预见到arboristal.com会接管世界,或者至少有一天会搬到更大的机器上。我不害怕学习新工具。什么是区域文件?”
于 2017-12-28T19:28:51.690 回答
9

因为我在理解这篇文章时遇到了麻烦,所以这里是对像我这样的人的简单解释。在以下情况下很有用:

  • 您不需要负载平衡。
  • 您不想使用 nginx 进行端口转发。
  • 您确实想根据使用 SRV 记录的特定子域进行 PORT FORWARDING。

然后这是你需要做的:

SRV 记录:

_minecraft._tcp.1.12          IN SRV    1 100 25567 1.12.<your-domain-name.com>.
_minecraft._tcp.1.13          IN SRV    1 100 25566 1.13.<your-domain-name.com>.

(我不需要 1.14 的 srv 记录,因为我的 1.14 minecraft 服务器已经在 25565 端口上,这是 minecraft 的默认端口。)

A记录:

1.12                          IN A      <your server IP>
1.13                          IN A      <your server IP>
1.14                          IN A      <your server IP>
于 2019-11-05T19:21:47.433 回答
0

使用 SRV 记录。如果您使用的是 freenom,请访问 cloudflare.com 并将您的 freenom 服务器连接到 cloudflare(freenom 不支持 srv 记录)使用 _minecraft 作为服务 tcp 作为协议和您的 ip 作为目标(您需要“a”记录才能使用您的 ip。我建议不要将您的“Arboristal.com”域用作“a”记录。如果您使用“Arboristal.com”作为“a”记录,黑客可以进入您的路由器设置并破解您的网络)优先级 - 0,权重 - 0和端口 - 您要使用的端口。(我知道这一点是因为我处于同样的情况)对任何域提供商都这样做。(对不起,如果我拼写错误)

于 2021-01-21T08:22:39.463 回答
0

可能的解决方案:

  1. 使用服务器上的 nginx 作为代理,将侦听端口 A 并多路复用到端口 B 或 C。

  2. 如果您使用 AWS,您可以使用负载均衡器将请求重定向到基于主机的特定端口。

于 2018-11-18T11:03:37.957 回答