到目前为止,我们已经深入了解了 Linux 网络管理,涵盖了从规划、设置文件服务器、网络服务等方方面面。 现在,当我们接近本书的结尾时,最后几章将以关于高级网络、安全性甚至故障排除的信息来完善这些知识。 在这一章中,我们将了解一些更高级的概念,如子网、路由等!
在本章中,我们将介绍:
- 将网络划分为多个子网
- 理解 CIDR 符号
- 服务质量(QoS)
- 网络地址转换(NAT)
- TCP / IP 路由流量
- 创建冗余 DHCP 服务器和 DNS 服务器
- 配置网络网关
除非你正在运行一个非常小的家庭或办公室网络,否则通常是一个好主意。 子网允许您将网络分割成更小的部分,每个部分都有自己的 IP 地址和资源。 例如,可以将无线通信、服务器、工作站和公司发布的移动设备放在它们自己的子网中。 此外,如果在您的网络中有任何特定的服务接收最多的流量,您也可以将该服务放在它自己的子网中。 有无限的可能性,每个管理员都有他或她自己的想法,最好的方式分裂网络。
在第六章、配置网络服务中,我们建立了一个 DHCP 服务器。 在其中,我包含了一个使用特定子网来动态租用 IP 地址的示例。 在该方案中,我们使用的网络是10.10.96.0/22
。 这意味着我们有几个可用的网络,包括10.10.96.0
、10.10.97.0
、10.10.98.0
和10.10.99.0
。 有了这个网络,我们基本上可以把几个业务分成各自的网络。 在我们的配置中,10.10.99.0
用于 DHCP。 但是当然,如果您决定这样做的话,没有什么可以阻止您使用 IP 地址10.10.96.1
到10.10.99.254
。 这实际上取决于您如何配置网络。 在那一章中,我们设定了一些本章将要用到的基础工作。 但是我们并没有讨论我们是如何得到这些数字的,或者如何手动分割网络。
子网划分的神奇之处在于子网掩码,尽管大多数人只忽略了这个数字。 对于相当多的网络,子网掩码保持默认值(255.255.255.0
),没有人真正质疑它。 如果你从商店购买了一台路由器,并在没有配置它的情况下投入生产(坏主意),你就只剩下一个 24 位网络和一个255.255.255.0
子网掩码。 但这到底意味着什么呢?
有两种不同类型的子网,有类的和无类的。 在生产网络中,很少有人会提到实际的类,因为无类就是现在子网的方式(稍后会详细介绍)。 但在我们进入无课网络之前,重要的是了解之前的情况。 在关于子网划分的讨论中,我们多次使用了255.255.255.0
的子网掩码示例,该示例属于 C 类网络。 总共有 5 个类,从类 A 到类 E。类 D 和 E 并不常用,所以为了讨论有类 IP 地址,我们将继续使用类 A 到类 C。
A 类到 C 类的子网掩码如下:
|类
|
子网掩码
|
| --- | --- |
| 一个 | 255.0.0.0
|
| B | 255.255.0.0
|
| C | 255.255.255.0
|
每个子网掩码对应于为网络指定的 IP 地址的哪一部分,以及为每个单独的节点指定的哪一部分。 例如,假设我们有一个配置了网络地址192.168.50.0
作为 C 类网络的网络。 这意味着我们的网络的子网掩码为255.255.255.0
。 与所有 IPv4 IP 地址一样,我们的网络地址有四个八位:192
、168
、50
和0
。 为了说明子网掩码如何影响 IP 地址,我将在一个表中排列每个八位元:
子网掩码的目的是掩码出,即 IPv4 地址的八位元对应于整个网络,而这些八位元对应于各个节点。 每个八字节中可能的最大值是255
。 如果一个子网掩码内的一个八位元被设置为255
,占用了整个八位元,从而抵消了它。 在这种情况下,每个节点的 IP 地址将以192.168.50
开始,因为前三个八位元被抵消了。 注意,最后一个八位元在网络地址和子网掩码中都是零。 在 IPv4 网络中,0
意味着任何东西。 因此,子网掩码的最后一个 8 位元是0
,这说明它不关心这个 8 位元,而网络地址是0
,这意味着它也不关心这个 8 位元。 因此,在最后一名的任何数字都是公平的。
在本例中,从192.168.50.0
到192.168.50.255
的 IP 地址属于这个网络(子网)。 嗯,差不多。 如果我们的子网掩码是255.255.255.0
,我们就永远无法开始分配192.168.50.0
IP 地址范围。 这是因为子网的第一个 IP 地址不能分配给节点。 第一个 IP 地址被指定为作为网络标识符,并被保留。 当然可以有一个以0
结尾的 IP 地址,只要它不是块中的第一个 IP 地址。 但是在类 C 网络中,192.168.50.0
的 IP 地址是无效的,因为它实际上是该子网中的第一个地址。
另一个不能分配给任何节点的 IP 地址是子网的最后一个 IP。 在我们的 C 类示例中,应该是192.168.255.255
。 这个 IP 地址被称为广播地址,也被保留。 如果广播消息需要发送到整个网络,则广播地址用于此目的。 考虑到这一点,我们的 DHCP 范围在类 C 网络(如我们示例中使用的网络)中的最大范围是192.168.50.1
到192.168.50.254
。
你可能想知道广播地址的目的。 如上所述,它允许将数据包发送到整个网络。 实际上,网络服务(如 DHCP)是利用广播的。 当你第一次将一台计算机插入以太网线(一台没有静态 IP 编程的计算机)时,它将发送一个广播消息请求一个 IP 地址。 在连接之前,它不知道 DHCP 服务器的 IP 地址是什么。 它可以是192.168.1.1
,甚至是192.168.1.100
。 它什么都不知道。 通过发送广播消息,任何负责 DHCP 的服务器都应该能够听到请求并响应它。
那么,为什么在前面的示例中选择 IP 地址192.168.50.0
呢? 这个数字是随机选择的,为的是说明子网掩码如何影响可用的 IP 地址。 我们可以使用172.16.254.0
作为我们的网络地址,并使用255.255.255.0
的 C 类子网掩码,这仍然会给我们相同数量的可用 IP 地址(254)。 在第二个例子中,我们仍然声明一个 C 类网络,只是使用了不同的 IP 方案。 由于您正在管理一个内部网络,您可以选择您想要的任何编号系统。 只要你的 IP 地址不是公开可路由的,只要你在任何八位元组中不使用超过 255 的数字,或者在网络中的第一个或最后一个 IP 地址,这都是公平的游戏。 还有一些其他的 IP 地址我们不能使用,我们稍后会讲到。
为了更好地理解这是如何工作的,我们需要重新讨论子网掩码。 如前所述,子网掩码有助于确定 IP 地址方案的哪些部分属于各个节点,哪些部分属于网络本身。 这样想。 255 是子网掩码或 IP 地址的任意八位字节中的最大数目。 子网掩码中的每个 255 代表一个不能更改的数字。 因此,如果你有一个 IP 地址10.19.100.24
和一个子网掩码255.255.255.0
,你可以马上知道这个网络的前三个八位元不会改变。 这意味着每个属于这个子网的主机都有一个以10.19.100
开头的 IP 地址。 如果子网掩码是255.255.0.0
,就会有更多可用的 IP 地址,因为最后两个八位元可以被占用。 这实际上会给我们 65534 个 IP 地址。 前者只允许我们使用 254 个 IP 地址,因为最后一个八位元是唯一可以改变的,它的最大值是 255(减去一个广播地址)。
但是您可能已经注意到,我使用了 a 类 IP 地址(10.19.100.24
)的示例,但我使用了 C 类子网掩码(255.255.255.0
)。 这是有效的吗? 当然! 不管一般公认的类结构是什么,子网掩码的唯一目的是帮助您了解哪一部分是主机,哪一部分是节点。 因此,255.255.0.0
和255.255.255.0
的子网掩码都对该网络有效。
然而,有些 IP 地址对于单独的类来说是无效的。 虽然带有253.221.96.0
子网掩码255.255.255.0
的内部 IP 网络符合所有这些规则,但它并不适用于 C 类网络。 如果您只管理您的网络中的 IP 地址,它可能工作,也可能不工作。 因此,对于类风格的每个类,都有一个推荐的方案。 我将在下表中说明这一点:
类
|
IP 开始
|
结束的 IP
|
| --- | --- | --- |
| 一个 | 0.0.0.0
| 127.255.255.255
|
| B | 128.0.0.0
| 191.255.255.255
|
| C | 192.0.0.0
| 223.255.255.255
|
对于所有联网的东西,这里也有一个例外需要记住,您不能将127.0.0.0
或127.0.0.1
分配给任何东西,因为它指的是本地回环适配器。
事实上,在 A 类方案中,内部网络以10
开始一个 IP 地址范围是非常常见的。 这是我们在前面设置 DHCP 服务器时所做的。 在该示例中,我们使用了10.10.96.0
网络。 但如果你还记得,我们没有使用的 C 类子网掩码255.255.255.0
; 我们使用255.255.252.0
。 这种区别将引导我们进入下一个主题,CIDR。
正如我前面提到的,有类子网的概念不再经常使用。 有类子网的主要用途是网络设备(如路由器)的默认配置,以及大多数 DHCP 服务器的默认设置。 在家庭路由器的情况下,DHCP 服务器通常是内置的,默认方案通常是 C 类网络(通常是192.168.1.0
,中间有几个变体)。 但对于大多数设备,无论是家庭设备还是企业设备,如果不将其更改为其他内容,您可能会得到一个 C 类 IP 方案。 在小型网络中使用这些默认设置并没有什么错,但是现在几乎没有人在配置网络时使用类样式。 原因是有等级的网络太局限了; 在复杂的网络部署中,试图强迫您的网络计划适应这些预先确定的方案之一可能是一件痛苦的事情。
解决有类方案缺乏灵活性的方法是无类域间路由(CIDR)。 有了 CIDR,我们基本上把 A 类、B 类和 C 类子网掩码的限制抛到了九霄外。 相反,我们使用二进制系统来决定如何划分我们的网络。 因此,我们可以借用位,改变子网掩码,以更灵活的方式划分网络,而不是坚持使用三个不同的子网掩码。
要理解这个概念,首先要理解比特的概念。 子网掩码中的每个八位元包含 8 位。 每个位要么是一个1
要么是一个0
(二进制)。 而且,每八个比特都有价值。 为了说明这一点,以数字255
为例。 这是任何八位元可以达到的最大值。 如果写成二进制,255
就是11111111
。 因此,将255.255.255.0
的 C 类子网掩码写成二进制则为11111111.11111111.11111111.00000000
。
为了更容易理解,请参阅下表,其中我列出了四个输出之一(255
),并以二进制形式显示它。 在这个表中,第一行给出了每个位的点值。 您可以看到,最右边的位值仅为1
,而最左边的位值为128
。 任何在底部的1
位都被累加起来。 在本例中,每一位都是1
(因为255
是最大值),所以我们将第一行的每个数字加起来,得到255
。
另一个例子见下表:
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |要将这个数字转换为小数,请从右边开始,然后向左移动。 第一个位是 0。 它符合 1 的点值吗? 不。 跳过它。 其次,它也不符合 2、4 或 8。 所以跳过这些。 但它确实晋级了最后四名,16、32、64 和 128 名。 把这些加起来。 答案吗? 224. 您只是将二进制数1111000
转换为十进制数。
我们可以使用1101000
作为子网掩码中的值吗? 不可能。 原因是子网掩码中为 1 的位必须是顺序的。 以下是子网掩码中所有有效的二进制数:
00000000
10000000
11000000
11100000
11110000
11111000
11111100
11111110
11111111
事实上,就是这样。 因为任何 1 都必须是连续的(从左到右),所以它们是唯一对子网掩码内的任何八位元有效的数字。 因此,对于子网掩码的任何八位元,唯一有效的十进制值是 0、128、192、224、240、248、252、254 和 255。
如果将一个 IP 地址转换为二进制,您将遵循前面表中相同的点值,尽管顺序 1 的规则并不适用。 从 0 到 255 的任何数字在 IP 地址的任意八位中都是有效的,在每个八位中都是 1 和 0 的组合。
对于一个网络的子网,我们只需改变顺序 1 的数目。 例如,255.255.255.0
的二进制表示为11111111.11111111.11111111.00000000
。 我们可以在这个掩码上添加一个额外的 1,得到11111111.11111111.11111111.10000000
,从而得到一个255.255.255.128
的子网掩码。 使用这个子网掩码,我们可以将我们的网络分成两部分。 让我们来分析一下。
正如我多次提到的,子网掩码的目的是掩码出哪个 IP 地址部分用于网络,哪个 IP 地址部分用于单个节点。 正如我们已经知道的,子网掩码为255.255.255.0
意味着前三个八位元不能被使用,但我们可以使用它,因为最后一个是 0。 如果我们将这个子网掩码应用于10.10.10.0
网络,我们可以知道每台主机将有一个10.10.10.x
的 IP 地址。 最后一个八位是 0,它告诉我们 IP 地址10.10.10.1
到10.10.10.254
是可争取的。 同样,我们不能使用子网的第一个 IP(本例中为10.10.10.0
)或最后一个 IP(10.10.10.255
),因为它们分别对应于网络标识符和广播地址。
但是,对于一个以而不是结尾为 0 的子网掩码,我们该怎么做呢? 如果子网掩码为255.255.255.128
,最后一个八位元将被使用,但不会耗尽,因为它不是 255 的最大值。 我们还剩下一些。 这是因为当子网掩码中的 8 位元为而不是255 时,它并不能完全屏蔽该 8 位元。 相反,它创造了一条分界线。 如果我们将该子网掩码应用于我们的10.10.10.0
网络,那么10.10.10.128
的 IP 地址就不能使用了。 我们所做的就是把最后一个八位元分成两半。 记住,值 0 到 255 在一个八位字节中是有效的; 因此,256 个可用的数字减半等于 128。 考虑到这一点,我们创建了一个有两个网络的方案。 一个网络包含10.10.10.1
~10.10.10.126
IP 地址。 另一个允许我们 IP 地址10.10.10.129
到10.10.10.254
。 原因是10.10.10.128
是我们子网的分界线,无法使用。 我还提到,一个块中的第一个和最后一个 IP 地址也不能使用,因为10.10.10.0
和10.10.10.128
是每个网络的标识符。 每个块中的最后一个 IP 地址分别是10.10.10.127
和10.10.10.255
,并且是禁止的,因为这些地址现在是这两个网络的广播地址。 如果我们用 CIDR 格式写出这些网络,我们得到以下结果:
10.10.10.0/25
10.10.10.128/25
记住,我们计算子网掩码中顺序的数目,以达到最后的斜杠数字。 我们可以写成下面这样,但我相信你会同意 CIDR 更容易输入:
10.10.10.0/255.255.255.128
10.10.10.128/255.255.255.128
在二进制中,该子网掩码为11111111.11111111.11111111.1 0000000
。 因为有 25 个 1,所以这个子网掩码的 CIDR 表示法是 25。 希望这个概念现在讲得通了。
至于我们的无类样式,没有什么可以阻止你使用子网掩码,比如255.255.255.0
。 并不是每个人都需要大量的主机。 但在 CIDR 风格中,我们不将其称为 C 类子网掩码,而是将其称为/24
网络。 在表中,我列出了讨论有类网络时使用的子网掩码,以及它们的 CIDR 等效。
类
|
子网掩码
|
CIDR 标记
| | --- | --- | --- | | 一个 | 255.0.0.0 | / 8 | | B | 255.255.0.0 | / 16 | | C | 255.255.255.0 | / 24 |
既然我们了解了子网是如何工作的,那么我们如何在我们的网络中使用它呢? 幸运的是,这部分很简单。 部署子网的神奇之处在于 DHCP 服务器。 如果你还记得,在第 6 章,配置网络服务中,我们在 DHCP 服务器的/etc/dhcp/dhcpd.conf
文件中使用了以下配置:
default-lease-time 86400;
max-lease-time 86400;
option subnet-mask 255.255.252.0;
option broadcast-address 10.10.99.255;
option domain-name "local.lan";
authoritative;
subnet 10.10.96.0 netmask 255.255.252.0 {
range 10.10.99.100 10.10.99.254;
option routers 10.10.96.1;
option domain-name-servers 10.10.96.1;
}
在第一行粗体中,我为从该服务器接收 IP 地址的每个节点提供了一个子网掩码255.255.252.0
。 在最后的代码块中,我决定从10.10.99.100
到10.10.99.254
发出 IP 地址。 因此,每个节点将收到一个10.10.99.x
IP 地址和一个255.255.252.0
子网掩码。
在推出子网方案时,惟一需要做的就是确保每个拥有静态 IP 地址的服务器或设备也都被更改。 除非您使用了静态租约(也称为预订),否则您将不得不找到这些主机并手动更改它们。 出于这个原因,我总是更喜欢静态租期而不是静态 ip。 对于静态租期,您需要做的就是编辑 DHCP 配置并更改分发给主机的 ip。 如何设置预约,请参考第 6 章、配置网络服务。
不是所有的网络流量都是平等的,也不是所有的服务都是同等重要的。 有时候,一个网络需要比其他服务更紧急地处理某些服务。 也许在服务器环境中,您的 web 服务器接收来自游客的高水平的交通,必须优化 MySQL,或者你的办公室使用 VoIP(语音 IP)和需要重点放在电话系统。 您的网络可能需要比其他网络更紧急地处理某个服务,原因有很多。 Quality of Service(QoS)帮助我们实现了这一点。
虽然有多种方法可以调整网络适配器以实现 QoS,但最典型的方法是,称为排队规则(或者更简单地说,qdisc)。 排队规则是管理员可以应用于网络适配器以使用多个调度器中的一个,每个调度器对流量的处理有不同的影响。 要查看您的网络适配器当前使用的调度程序,运行以下命令:
ip link list
寻找你的默认网卡,可能是eth0
(在 Debian 中)或eno1
(在 CentOS 中)或类似的。
查看 Debian 中 IP link list 的输出信息
最有可能的情况是,您将在输出中看到qdisc pfifo_fast
,它告诉我们当前使用的排队规则是pfifo_fast
。 这基本上是一个先到先服务的调度程序(先到先出)。 但它并不是只包含一个频带,而是包含三个频带pfifo_fast
——每个频带将流量分成三个优先级。 第一个频带(频带 0)包含最高优先级的流量。 每个波段只有在前一个波段被服务之后才被处理。 除非您的发行版更改了默认调度器pfifo_fast
,否则该调度器最有可能是当前系统上使用的开箱即用的调度器。
调度器被称为无类调度器。 换句话说,您看到的就是您得到的——当涉及到无类调度程序如何过滤流量时,不需要进行配置。 其他阶级学科包括随机公平【5】【T6 排队】(【显示】SFQ),扩展随机公平排队(【病人】ESFQ),和令牌桶过滤器(转发【t16.1】延长)。
正如我们之前提到的,SFQqdisc 使用了 FIFO 的概念,但是将网络流量分割成多个 FIFO,以循环方式处理。 这个 qdisc 尽量做到公平,使用流来调度数据包传输。 这给了每一个流一个转折来传输,防止其中任何一个变得饱和。 ESFQ 非常类似,但它为管理员提供了更多的配置选项。 与 SFQ 不同,TBF 实际上不操作数据包,也不进行任何调度。 TBF 的主要目的是设置传输发生的速率,允许您设置参数,如速率、突发、峰值速率等。 有关这些 qdisc 的更深入的信息,请参阅sfq
和tbf
的主页。 在网络适配器上设置首选 qdisc 是通过tc
命令完成的。 在以太网适配器eno1
上设置sfq
的示例如下:
# tc qdisc add dev eno1 root sfq perturb 60
这里,我们用qdisc
调用tc
命令,并阐明我们想要add
(我们也可以del
)一个 qdisc。 我们将针对接口eno1
执行此操作,并且我们将此更改请求到出口(root
),同时针对接口的sfq
qdisc。 最后,我们设置 qdisc 特定的参数(在本例中为pertub
)。 perturb 参数允许我们设置这个 qdisc 的哈希算法将被重置的秒数。 我们还可以修改其他特定于 sfq 的值,例如所使用的流的数量、量程、redflowlimit 等等。 有关可与 sfq 或 tbf 一起使用的参数的完整描述,请参阅man sfq
。
无分类 qdisc 的不足之处在于,它们不允许您像人们所希望的那样对流量进行粒度分类。 虽然改变数据包的调度方式当然很有用,但这个概念不允许您选择在任何给定时间接收优先级的流量类型。 有类 qdiscs 解决了这个问题,并为管理员提供了更大的灵活性。 有了这些,你就可以为父母和孩子设定不同的规则。 事实上,这就是有类 qdisc 和无类 qdisc 的主要区别。 这并不是说无类 qdisc 是不可配置的; 他们只是没有支持高级用例灵活性的选项。 接下来,我们将探索有类的 qdisc,以及它们如何允许我们增加这种灵活性。
通过利用有类 qdisc 的功能,您几乎可以完全控制如何在网络上处理包。 我说几乎是,因为重要的是要记住,排队规则的思想只影响出站流量(出口),而管理进入的流量几乎是不可能的。 然而,在生产网络上,保证特定的服务有一定数量的带宽是非常有益的。 正如我们在前一节中所讨论的,无类 qdisc 允许我们管理处理包的一般方式,但有类 qdisc 允许我们通过设置类和过滤器来进行更多的控制。
你可能会遇到的一个可能的场景是 VoIP 通信变得不稳定,导致通话声音模糊或完全下降。 在这种情况下,您可能想要保证您的 VoIP 服务器有更多的带宽,即使这意味着牺牲来自其他来源的流量。 此外,SSH 在 Linux 网络上也很重要。 如果您的服务器被数据包淹没,甚至无法响应通过 SSH 连接到它的请求,这可能是一个非常糟糕的问题,因为您将无法登录并纠正可能出现的任何问题。 这些都是很多人在没有优先排序的情况下面临的真实情况。 如果你的网络或公司依赖某项服务,优先考虑它是一个很好的方法。
实现这一点的最流行的 qdisc 是分级令牌桶(HTB),这是一个有类 qdisc。 HTB 允许你控制设备上使用的出口带宽,它基于我们之前讨论过的 TBF 风格。 HBT 有许多类可以用来控制流量,例如设置parent
、priority
、rate
、ceil
以及突发字节数。 参见man htb
查看完整列表。
就像我们配置无类 qdisc 一样,设置像 HTB 这样的有类 qdisc 也是通过tc
命令完成的。 在大多数系统上,这个命令存储在/sbin
中,并且可能不在普通用户的路径中。 键入which tc
来定位这个二进制文件在您的发行版中的位置。 在大多数情况下,如果以 root 登录运行,系统应该能够识别此命令。 下面是将 HTB 设置为名为eth0
的网络设备的 qdisc 的过程示例。
# tc qdisc add dev eth0 root handle 1: htb default 10
# tc class add dev eth0 parent 1: classid 1:1 htb rate 2mbit
# tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1mbit ceil 1.5mbit
# tc class add dev eth0 parent 1:1 classid 1:20 htb rate 100kbps ceil 100kbps
在第一个命令中,我们将 qdisc 从默认的pfifo_fast
更改为htb
。 在这个命令中,root
与我们针对出口流量设置此值有关。 1:
的句柄是这个特定实例htb
的名称。 设置默认值10
意味着任何没有在其他地方特别分类的流量将被赋予一个类 ID1:10
。 使用第二个命令,我们创建类 ID1:1
并调整它以使用2mbit
的速率。 在第三个例子中,我们也在做同样的事情,只是我们创建了带有上限的 ID1:10
,这将把这个类限制为1.5mbit
。 因为我们将默认值设置为10
,所以如果我们不专门针对流量来使用其他东西,就会使用这个类。 最后,我还加了第三个班1:20
,这个班的上限要低得多100kbps
。 如果将rate
和ceil
值设置为相同的值,我们可以合理地期望该类下的流量消耗100kbps
,但也将限制为100kbps
。 您可以继续使用此方法向1:
父类添加额外的类,只要您需要,就可以相应地划分带宽。
既然已经确定了类,就应该使用它们。 在前面的示例中,您可能会注意到现在的带宽比以前要少(假设带宽高于我们设置的默认1.5mbit
)。 但是我们另外两个类是未使用的,所以我们可以根据需要提高对其他服务的带宽限制。 因此,让我们为 SSH 添加一个过滤器。 由于 SSH 不需要大量的带宽,我们可以将我们的1:20
类分配给它。 为此,我们将再次使用tc
命令:
# tc filter add dev eth0 parent 1: protocol ip prio 7 u32 match ip sport 22 0xfff classid 1:20
可以更改服务器侦听 SSH 连接的端口,我们将在第 9 章、保护您的网络中讨论。 如果您更改了 SSH 端口,请相应地调整tc
命令。
这样就剩下两个类,1:1
和1:10
。 我们也可以为它们分配过滤器,这取决于我们想要为流量分类的端口:
# tc filter add dev eth0 parent 1: u32 match ip sport 80 0xfff classid 1:1
# tc filter add dev eth0 parent 1: u32 match ip sport 5060 0xfff classid 1:10
这里,我使用端口80
和5060
分别用于 HTTP 和 VoIP 流量。 您的端口可能有所不同,因此您可以根据网络的需要相应地调整该命令。 但是在这个假设的示例中,端口80
上的流量将被分类为1:1
并被授予最大速率2mbit
(对于 web 服务器来说非常好),端口5060
上的流量将被授予1.5mbit
。
总之,无类 qdisc 允许您控制如何在系统上管理数据包的一般共识。 根据您的环境,您可能会发现更改为无类 qdisc 可以提高性能。 但是真正的好处是有类的 qdisc,它允许您更细粒度地控制如何处理数据包,以及服务器资源的提供速率。 调优网络性能是一项耗时的任务,需要反复试验以确定哪些值、类和过滤器将提高网络的性能。
网络的全部目的是使流量从 A 点到 b 点。当一台计算机从另一台计算机请求信息时,信息包被路由到目的地,然后再返回。 有时,计算机需要一点关于如何将包送到目的地的指导。 这被称为routing。 为了帮助实现这一点,节点利用路由表的概念来帮助决定在给定的特定目的地将报文发送到哪里。 如果存在的每个网络都使用相同的 IP 方案,这将是非常容易的,但事实上,每个网络是完全不同的。 要与不同的网络通信,您的计算机必须知道如何到达该网络。 可以将路由表看作外部目的地和到达这些目的地的网关的映射。
为了更好地理解这一点,让我们来讨论一下默认网关的概念。 通常,默认网关是一个知道如何与其他网络通信的路由器。 当您通过网络发送一个信息请求时,包会穿越到本地默认网关,然后从那里进入其他网络。 在小型办公室或家庭网络的情况下,默认网关可能是位于您的网络和世界其他地方之间的路由器。 此外,它还位于本地设备和网络中所有其他设备之间。 如果没有默认网关,就根本不可能在网络上进行通信。
要查看默认网关,发出ip route
命令并查找读取default via
的行。
ip route 命令的输出信息
如果没有默认网关(或者没有正确配置的默认网关),您可能会发现无法与网络上的其他节点进行通信。 在大多数情况下,一旦你通过 DHCP 收到一个地址,默认网关就会被添加到你的路由表中。 如果您使用静态 IP 配置,您可以通过/etc/network/interfaces
手动设置 Debian 中的默认网关,或者在 CentOS 中为您的网卡设置初始化脚本(例如/etc/sysconfig/network-scripts/ifcfg-eno1
)。 下面是这些配置文件的示例,并突出显示了相关的行:
/etc/network/interfaces
文件(Debian):
iface lo inet loopback
allow-hotplug eth0
iface eth0 inet dhcp
# The primary network interface
allow-hotplug eth1
iface eth1 inet static
address 10.10.96.1
netmask 255.255.252.0
gateway 10.10.96.1
broadcast 10.10.96.255
dns-search local.lan
dns-nameservers 10.10.96.1
/etc/sysconfig/network-scripts/ifcfg-eno1
文件(CentOS):
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
NAME=eno1
UUID=8e6587dd-74ec-488f-8597-a04c4a4c5091
DEVICE=eno1
ONBOOT=yes
IPADDR="10.10.96.4"
NETMASK="255.255.252.0"
GATEWAY="10.10.96.1"
如果你想要更手动地设置默认网关,你也可以通过 shell 命令在终端中这样做,如下所示:
# route add default gw 10.10.10.1 eth0
如果您的系统无法识别 route 命令,则需要安装net-tools
包。
很简单。 我们使用 route 命令添加一个新路由; 在本例中,我们添加了默认网关(default gw
)。 在本例中,我们将网关设置为10.10.10.1
并将其绑定到接口eth0
。 这可能是不言自知的,但是一旦重新启动机器或重新启动网络,这个设置很可能会丢失,除非您通过更新接口卡的init
脚本使其永久保存,就像我们前面讨论的那样。
要查看路由表,只需不带任何参数地执行route -n
命令。 如果没有找到该命令,您可能需要调用该路径(例如/sbin/route
)或将其作为根运行。 当您执行此命令时,您将看到路由表。 这也将显示您的默认网关。
route -n 命令的输出信息
关于这个表首先要讨论的是0.0.0.0
的 IP 地址。 在网络方面,这指的是一切。 正如您在前面示例中所示的表中所看到的,该网络上目的地0.0.0.0
的网关是192.168.1.1
。 因此,任何通信都被发送到这个 IP(毕竟,它是默认网关)。 这张表中还显示了其他网络。 在我的例子中,它们指的是运行在这个测试机器上的 Docker 实例和 KVM 虚拟化,每个实例都有自己独立的虚拟网络。 因为它们都在同一台机器上运行,所以它们的网关是本地的0.0.0.0
。
一台 Linux 机器本身就可以很容易地充当路由器,而不需要像思科这样的公司提供的昂贵的网络设备。 这种灵活性使得 Linux 成为网络的一个非常突出的选择,基于 Linux 的硬件路由器也变得非常普遍。 至少在某种程度上,这是由于将 Linux 系统配置为路由器非常容易。 简而言之,将 Linux 节点转换为路由器所需要的全部工作就是多个网络接口卡。 每个接口卡都可以有自己的默认网关,因此您可以按照本节前面为eth0
添加默认网关的方式来配置路由。 您只需对eth1
、eth2
或系统上可能存在的任何其他接口执行相同的操作。
然而,有一个警告。 在大多数 Linux 发行版中,缺省情况下网络接口之间的路由通常是禁用的。 这给您的作者带来了很多痛苦和挫折,直到我在职业生涯的早期就知道了这一点,所以我将为您省去这些麻烦,并向您展示如何在 Linux 系统上启用接口之间的路由。
首先,看看这是否已经为您完成了。 虽然我发现许多发行版在默认情况下没有启用转发功能,但有些发行版启用了。 检查这个很容易:
cat /proc/sys/net/ipv4/ip_forward
这个命令的输出是什么? 是1
吗? 如果是这样,那么一切都准备好了。 如果没有,我们需要改变这一点。 为此,只需将该值替换为 1(作为根):
echo 1 > /proc/sys/net/ipv4/ip_forward
就这样,你完蛋了。 您刚刚启用了接口之间的路由(转发)。 这并不难。 但是,我想你更希望这是一个永久的改变。 一旦重新启动系统,这个设置很可能就会恢复到默认设置。 要使此更改永久生效,使用您喜欢的文本编辑器(以根用户身份)编辑/etc/sysctl.conf
,并在文件末尾添加以下一行:
net.ipv4.ip_forward = 1
现在,无论何时重新启动系统,都将保持此设置。 到目前为止,在我让你做的所有网络调整中,这绝对是最简单的。
最后,让我们花一点时间讨论一下网络地址转换(NAT)。 NAT 的概念是改变发送到一个主机的数据包,并改变它们,使它们的目的地变成其他东西。 这种更改实际上是通过更改数据包本身来完成的,它对于管理网络路由非常有用。 NAT 最常见的用途是保存 IP 地址,这在目前 IPv4 地址短缺的情况下尤其重要。 如果你家里有一个路由器,你可能已经熟悉这个概念了。 你的互联网服务提供商(ISP)给你一个 IP,而这个 IP 就是世界上其他人眼中的你。 但是在你的本地网络中,你可能有十几台设备连接在一起,并且使用相同的互联网连接。 您的每个内部设备都有一个本地 DHCP 服务器给它们的 IP 地址,但该地址只是本地的,不能路由到外部世界。 在这种情况下,你的路由器跟踪进出你的每个设备的数据包,它改变数据包,使它们不会混淆,并结束在正确的地方。
例如,假设您有一台膝上型电脑和一台台式机(在同一网络上),并且您在膝上型电脑上访问https://www.packtpub.com/。 你的路由器将请求发送到互联网上,并发送结果。 基本上,你的路由器代表你的笔记本电脑发出请求。 当从https://www.packtpub.com/返回数据包到达时,数据包的目的地址从您的公共 IP 地址更改为请求信息的机器的 IP 地址。 这样,您就可以合理地确定您的笔记本电脑将得到回复,因为它是第一个要求它的地方。
NAT 的概念很聪明,这甚至不是唯一的用例。 您甚至可以自己手动更改目的地地址,这可以帮助您将数据包发送到其他网络,否则您的内部计算机将不知道如何路由到这些网络。 要手动修改 NAT,我们使用ip rule
命令。 使用这个命令只需要根据流量的来源改变目的地即可。 考虑以下例子:
# ip rule add nat 10.10.10.1 from 192.168.1.134
这再简单不过了。 这里,我们告诉系统查找来自192.168.1.134
的任何包,并将它们重写为流到10.10.10.1
。 对你需要执行的其他NATing重复此步骤。
在第六章、网络服务配置中,我们建立了 DHCP 和 DNS 服务器。 这很好,但不幸的是有一个主要问题。 一个是单一的故障点。 如果 DHCP 服务器宕机,新设备将无法接收 IP 地址,当前连接的客户端将在当前 IP 租期到期时退出网络。 如果 DNS 服务器宕机,客户端将无法通过主机名到达目的地。 根据您的网络范围,这种停机可能很难处理,因此为这些服务提供冗余可能是一个好主意。
当一个 DHCP 服务器与另一个服务器配置冗余时,它将同步其发出的 IP 地址列表,并且每个服务器都将检测其他服务器是否停止响应。 在这种情况下,辅助服务器将接管发布新 IP 地址的任务。 使用 DNS,只是在网络上添加另一个 DNS 服务器的问题,但我稍后会详细讨论这个问题。
让我们从向 DHCP 服务器添加冗余开始。 为了简单起见,可以将前面创建的初始服务器视为主服务器。 接下来要做的是创建另一个服务器作为辅助服务器。 这可以是另一个物理服务器,甚至是一个虚拟机,你自己选择。 按照第六章、和中讨论的方式安装isc-dhcp-server
、配置网络服务。 一旦你让第二个服务器站起来,我们就可以开始了。
在两台 DHCP 服务器投入生产之前,确保它们的时钟是同步的,这是绝对必要的*。 在继续之前,最好再次检查 NTP 是否配置并在两者上运行。 在第 6 章、配置网络服务中,包含了关于设置 NTP 的信息。*
*从主节点开始,我们应该向/etc/dhcp/dhcpd.conf
文件中添加一些额外的代码。 为了增加冗余,我将新建的配置行加粗:
default-lease-time 86400;
max-lease-time 86400;
option subnet-mask 255.255.252.0;
option broadcast-address 10.10.99.255;
option domain-name "local.lan";
authoritative;
failover peer "dhcp-failover" {
primary;
address 10.10.96.2;
port 647;
peer address 10.10.96.1;
peer port 647;
max-response-delay 60;
max-unacked-updates 10;
load balance max seconds 3;
mclt 3600;
split 128;
}
subnet 10.10.96.0 netmask 255.255.252.0 {
option routers 10.10.96.1;
option domain-name-servers 10.10.96.1;
pool {
failover peer "dhcp-failover";
range 10.10.99.100 10.10.99.254;
}
}
注意,下面一行被删除了:
range 10.10.99.100 10.10.99.254;
它被同一部分中的池{}
块所取代。
对于的大多数部分,我们在主服务器上所做的相同配置可以复制到次要服务器上。 您可以使用这里的/etc/dhcp/dhcpd.conf
文件作为在第二台服务器上启动配置的基础。 我将再次强调两者之间的不同之处。 代码如下:
default-lease-time 86400;
max-lease-time 86400;
option subnet-mask 255.255.252.0;
option broadcast-address 10.10.99.255;
option domain-name "local.lan";
authoritative;
failover peer "dhcp-failover" {
secondary;
address 10.10.96.1;
port 647;
peer address 10.10.96.2;
peer port 647;
max-response-delay 60;
max-unacked-updates 10;
load balance max seconds 3;
}
subnet 10.10.96.0 netmask 255.255.252.0 {
option routers 10.10.96.1;
option domain-name-servers 10.10.96.1;
pool {
failover peer "dhcp-failover";
range 10.10.99.100 10.10.99.254;
}
}
从辅助服务器的配置中删除了以下几行:
mclt 3600;
split 128;
你应该注意到主句和次句的地址是相反的。 在第一个配置文件中,主服务器是10.10.96.1
,次要服务器被设置为10.10.96.2
。 在第二个实验中,这个数字分别变为10.10.96.2
和10.10.96.1
。 此外,还要仔细注意 IP 地址、子网掩码和其他可能在不同网络中有所不同的值。 如果您在两台服务器上都启动 DHCP 服务(在 Debian 上是isc-dhcp-server
,在 CentOS 上是dhcpd
),您应该会看到它们通过日志进行通信。 要检查的特定日志在基于 debian 的系统中是/var/log/syslog
,在 CentOS 系统中是/var/log/messages
。 通过在其中一台服务器上禁用 DHCP 服务,您可以很容易地测试这一方法是否有效,并且您应该会看到其他发出的 IP 地址。
现在我们已经为 DHCP 配置了冗余,让我们对 DNS 进行同样的配置。 事实上,这要简单得多。 您所要做的就是指定另一个服务器作为辅助 DNS 服务器(您可以创建一个新机器,或者只是将其添加到辅助 DHCP 服务器),然后将配置文件和区域文件复制到新服务器。 同样,第 6 章、配置网络服务中包含了这些文件的所有相关细节。 如果您想节省一点时间,甚至可以将原来的 DNS 服务器克隆到新机器中,如果您正在使用虚拟化或了解如何使用dd
命令,这很容易做到。 在创建辅助服务器并复制区域文件的任何方法之后,测试 DNS 在新服务器上是否正常工作。 完成之后,我们返回到 DHCP 配置,将这个辅助服务器部署到所有节点。
在/etc/dhcp/dhcpd.conf
文件中,查找以下一行:
option domain-name-servers 10.10.96.1;
修改为:
option domain-name-servers 10.10.96.1, 10.10.96.2;
你就完成了。 现在,每次您的客户的租约到期或他们请求一个新的 IP 地址,他们将自动提供次要 DNS 地址。
此时,剩下要做的唯一一件事就是配置使用静态 IP 地址设置的任何节点,以使用辅助 DNS 服务器。 正如我已经提到过上千次的那样,由于这个原因,我更喜欢静态租期(为 DHCP 服务器上的各个节点保留 IP 地址),而不是手动静态 IP 分配。 只需在 DHCP 服务器上配置即可。 但是,如果您确实有手动配置网络的任何节点(每个节点都是自己的),只需更新它们的init
脚本。 同样,您会在/etc/network/interfaces
(Debian)或/etc/sysconfig/network-scripts/<if-name>.cfg
(CentOS)中找到这个配置。
在我们的旅程中,您的网络应该处于更好的状态。 在这一章中,我们完成了相当多的工作。 我们已经讨论了路由、NAT、子网、服务质量等高级主题,甚至还为 DHCP 和 DNS 服务器设置了冗余。 如果我们出色的网络发生什么事,那将是一个遗憾。 这就是为什么在下一章中,我将介绍如何加强我们网络的安全性。 看到你在那里!*