通过单独的网卡进行通信

假设您有一个带有两个网卡(及其相关端口)的networking服务器,我们称它们为A和B.这个想法是将一个端口(A)连接到互联网,另一个连接到另一个(B)各种计算。 这似乎是比较常见的,一个networking暴露在互联网上,用于实际的信息发送和接收以及一个用于安全数据存储,pipe理控制等的专用networking。

如何通过一个或另一个指挥交通? 我所见过的唯一的一面是代码方面,在我熟悉的所有语言中,通过提供一个目标地址而不是一个起始地址来启动通信(比如TCP)。 如果你想和一个特定的机器(通过交换机)连接到一个端口或另一个端口,你将如何指定? 而且,如果你有通过A和B连接的机器,但是一些stream量(可能是财务信息)需要通过B发送,而其他stream量(例如REST数据)会更适合A?

你可能会用路由做到这一点 – 在端口A上有一个子网,在端口B上有另一个子网。然后操作系统根据它需要到达的服务通过正确的接口路由数据包。

目前还不清楚你需要做什么和为什么。

如果您有2个网卡,您的机器将有2个networking连接和2个IP地址。 当您通过该机器的IP地址与其他某台机器通信时,服务器将根据本地路由策略(例如度量)select出接口。

示例1:您连接到2个networking:

  • 10.0.0.0,你有IP地址10.10.10.2
  • 192.168.1.0,你有IP地址192.168.1.2

现在,如果你想连接到192.168.1.5,你的web服务器很可能会select第二个networking(192.168.1.0),因为目的地在那里是可以直接到达的。

示例2:仅连接到1个networking:

  • 192.168.1.0,你有IP地址192.168.1.2和网关192.168.1.1

现在,如果你想连接到10.10.10.2,你的web服务器将只发送数据包到默认网关(路由器),因为10.10.10.2不在你的networking(192.168.1.0)中。 您的服务器不知道网关上的数据包会发生什么情况,以及网关(路由器)如何将其传递到最终目的地。 这只是网关(路由器)的头痛。

对于第二个示例,服务器上的本地路由表看起来相当简单:

  • 192.168.1。*直接连接
  • 0.0.0.0(一切)通过192.168.1.1连接(你的网关)

结论:

从代码方面来说,如果你不写一个路由软件,你不能select出接口。 这是合理的,因为你的应用程序不知道路由协议,信息和规则。 操作系统根据路由表为您做出select。 路由表是由操作系统根据您的networking连接状态,策略,规则,路由协议(如果您的服务器充当路由器)等创build和更新的。

如果您需要通过两个不同的出站接口与相同的目标进行通信,则取决于目标PORT,则应该在服务器上configuration路由。 Linux示例: https : //unix.stackexchange.com/questions/21093/output-traffic-on-different-interfaces-based-on-destination-port

这就是为什么您通常将不同的主机名或不同的子域分配给不同的接口的原因。

假设你的主机名为host001和host002,你的networking如下所示:

<-----internet --------+------------------------------+-------whatever else---> | | 157.38.5.6 | 157.38.5.7 | +---------------+--+ +-------------+--+ | host001 | | host002 | +---------------+--+ +-------------+--+ 192.168.1.1 | 192.168.1.2 | +------------------------------+-------admin lan---> 

157.38.5 / 24是您的提供商分配给您的地址范围。 这两个主机都可以从互联网上,你会放

 host001.mycompany.com. IN A 157.38.5.6 host002.mycompany.com. IN A 157.38.5.7 

进入你的官方DNSlogging。

(请注意,你的互联网应该有一个很大的防火墙 ,你可能不应该在你的防火墙上的任何地方使用公开的可路由地址,但是为了清晰起见,我想要区分内部/外部)。

进入公司内部的DNS服务器,其logging不在互联网上发布,你会放

 host001.dmz.company.com IN A 157.38.5.6 host002.dmz.company.com IN A 157.38.5.7 host001.mgm-net.company.com IN A 192.168.1.1 host002.mgm-net.company.com IN A 192.168.1.2 

现在,只要你想通过内部networking打开一个连接,你就可以使用mgm-net域中的一个主机名。 这将select192.168.1地址,并且由于每个主机都有自己的地址,所以它将使用这个networking接口。 如果您想使用公共networking,请使用dmz域地址。

本地主机如何select出接口

这是路由表的用途。 您的路由表将看起来类似于这样的:

 destination netmask gateway metric interface 0.0.0.0 0.0.0.0 157.38.5.1 1 eth0 157.38.5.0 255.255.255.0 0 eth0 192.168.1.0 255.255.255.0 0 eth1 

表的确切格式取决于您的操作系统,操作系统版本和用于显示它的命令。 而且,度量的绝对值可能不同。 其中的关键在于,从所有路由表项中,内核将消除那些不适合目标地址的内容。 如果连接到192.168.1.1,则会从列表中删除第二个条目(157 …)。 默认路由(0.0.0.0)在这一点上仍然是可以理解的。

然后,从所有剩余的可能性中,select具有最佳度量的那个。 通常,度量标准是到达目的地跳数的同义词,所以最低的度量标准是最好的。 Windows使用其他方式,最高指标是最好的。 无论如何,它是在你的本地路由表中可能的路由和度量的组合,决定使用哪个本地接口。

如果您尝试从公司内部的“远离networking”的地方进行连接,那么在您的PC和目标networking之间存在一个或多个路由器的情况下,这一点尤其重要。

进一步改善的可能性

  • 您可能希望为主机提供不同的主机名,而不是不同的networking域。 因此,您可能拥有host001-ext.mycompany.com和host001-adm.mycompany.com主机条目,因此每次连接到特定主机时都不必“拼出”域。 但是,通过混淆不同PC上的域名search顺序,您可以在PC A更喜欢dmz.company.com,PC B更喜欢mgm-net.company.com,并且“自动select”正确的networking请参阅configuration文件中的“host001”。

  • 如果您同步最后的IP字节,您将会减less混淆; 内部157.38.5.6应该匹配192.178.1.6,而不是192.168.1.1。 拥有一致的最后字节允许您创build一个脚本,从外部自动生成内部地址。

  • “危险”服务,例如端口22 / ssh(在unix上)或3389 /远程桌面上,只能绑定在192.168.1.X地址上。 这样,如果你在内部networking上,你仍然可以使用你的机器,但你已经从外部删除了一个攻击媒介。

configuration/编程

OS API的function之一就是隐藏所有这些细节,所以你没有看到“数据来自哪个接口”的任何区别,除非你明确地要求。

从C ++ API中,你可以使用getsockname()getpeername()函数来查找套接字的本地/远程地址。 而当你使用bind()来build立一个监听套接字时,其中一个参数是sockaddr结构,你必须在其中设置端口,并在其中设置IP地址。 通常情况下,您只需将其设置为0.0.0.0,这意味着套接字绑定到任何地址上的端口。

在Java中,你有Socket.getRemoteSocketAddress()Socket.getInetAddress来做同样的事情, ServerSocket()有一个3参数版本让你设置地址来侦听。

应用程序通常具有相同的configuration文件。 例如, /etc/sshd/sshd_configsshdconfiguration有一个ListenAddress参数。 如果你在这里说ListenAddress 192.168.1.1 ,那么sshd会在创build套接字的时候将192.168.1.1传递给bind() ,你的操作系统将不会接受目标为157.38.5.6 ssh数据包。

同样,apache web服务器有一个configuration参数Listen ,允许你设置端口和可选的地址来侦听。

Windows程序通常会在一些configuration中使用clickies。 在IIS中,您可以使用端口和IP地址(其中地址可以是所有地址的“*”)将服务绑定到服务器,这样做的效果相同。

从你的文本我不知道你是否真的在谈论两个真正独立的networking,即:

  1. 每个子网有一个不同的交换机(或一个pipe理交换机,具有多个VLAN);

  2. 每台交换机都连接到服务器上的一个NIC(网卡)。

  3. 所有其他计算机只连接到一个交换机;

  4. 每个子网都有它自己的寻址,例如,一个地址是192.168.0。*,另一个是192.1.68.1。*。

如果确实如此,那么:

  1. 服务器上的Linux应该自动将stream量从一个networking路由到另一个networking(如果没有,Google iptables,两个NICS之间的路由,并告诉我们你正在运行哪个Linux)

  2. 服务器也是configuration防火墙以限制不想通过networking路由的stream量的好地方。

  3. stream量stream向的区分只是基于IP地址(见上面的4)。

  4. 通常情况下,你不能在两个子网上连接PC,你应该使用路由和防火墙(在一个点上,服务器上)来调整跨子网的传输。