导航

路由转发配置与故障排除

Posted on 2023-12-04 14:44  蝈蝈俊  阅读(302)  评论(0编辑  收藏  举报

在当今的数字化时代,网络连接的重要性不言而喻。路由转发作为网络通信的核心环节,其配置的正确与否直接影响着网络的稳定性和效率。

本文使用下图这个简化网络来演示:

  • 如何简洁高效地配置路由转发;
  • 在遇到问题时,如何利用常用工具进行分析和定位。:

图说明:

  • 一台具有两个网络接口的机器b(192.168.1.510.2.0.3),作为两个网络之间的路由器/网关。
  • 机器a(192.168.1.28) 和 机器c(10.2.0.8)在各自网络。

配置路由转发

为了确保从机器a(192.168.1.28) 发出的 ping 请求能够到达机器c(10.2.0.8) 并且能收到回应,你需要正确配置网络和路由。

以下是配置步骤:

1、启用 IP 转发

在扮演路由器角色的机器b上启用 IP 转发。

在 Linux 上,你可以这样做:

echo 1 > /proc/sys/net/ipv4/ip_forward

或者永久启用,编辑 /etc/sysctl.conf 文件,添加或取消注释以下行:

net.ipv4.ip_forward = 1

然后运行 sysctl -p 来应用更改。

IP 转发的作用

net.ipv4.ip_forward = 1 这个设置是在 Linux 系统中启用 IP 转发的配置。启用 IP 转发后,该系统可以将接收到的网络包转发到另一个网络接口,这是路由器多宿主主机进行数据包转发的基础功能。

路由器功能:当启用 IP 转发时,该机器可以充当路由器,允许不同网络之间的通信。例如,一个接口连接到 192.168.1.0/24 网络,另一个接口连接到 10.2.0.0/24 网络,该机器可以转发这两个网络之间的数据包。

多宿主主机:在一个多宿主(多个网络接口)的机器上,启用 IP 转发可以使得这台机器在其接口之间转发数据包,从而连接不同的网络。

在有两个或多个网络接口(包括虚拟网卡)的机器上,启用 IP 转发最有意义,因为这允许机器在其不同的网络接口之间转发数据包。

2、路由器上的防火墙规则

确保你的路由器(双网卡机器)上的防火墙设置允许从一个接口到另一个接口的流量。这可能涉及到添加 iptables 规则,允许转发。

我们这里假设前面路由器机器b有两个网卡:

  • gnb_tun 对应 192.168.1.0/24 网络
  • enp1s0 对应 10.2.0.0/24 网络

下面这两个命令配置了一个简单的NAT和数据包转发规则:

  • 允许从特定接口(如gnb_tun)来的数据包经过主机并通过另一个接口(如enp1s0)发送出去,
  • 同时修改这些数据包的源地址,使其看起来像是从主机本身发出的。

我们这里用nftables来演示,nftables 是设计来替代 iptables 的新一代网络流量管理框架,在 Linux 3.13 内核中引入(2014年)。以ubuntu 22.4 为例,默认使用的是 nftables 作为其主要的网络包过滤框架,如果你在 Ubuntu 22.04 上执行 iptables 命令,这些命令实际上是通过 nftables 的后端执行的(通过使用 iptables-nft 包实现的)。

配置防火墙规则:

# 发出去的包动态地改变源地址
sudo nft add table ip nat
sudo nft add chain ip nat postrouting { type nat hook postrouting priority srcnat; }
sudo nft add rule ip nat postrouting oifname "enp1s0" masquerade


# 转发数据包
sudo nft add table ip filter
sudo nft add chain ip filter forward { type filter hook forward priority 0; }
sudo nft add rule ip filter forward iifname "gnb_tun" oifname "enp1s0" accept

参数解释:

创建 NAT 表和规则

nft add table ip nat
  • nft: nftables 命令行工具。
  • add: 添加一个新元素(如表、链、规则)。
  • table: 表示要添加的是一个表。
  • ip: 指定表的家族,这里是 ip,用于 IPv4。对于 IPv6,使用 ip6
  • nat: 表的名称,这里称为 nat
nft add chain ip nat postrouting { type nat hook postrouting priority srcnat; }
  • add chain: 添加一条新链。
  • ip nat: 指定链所在的表和家族。
  • postrouting: 链的名称。
  • { type nat hook postrouting priority srcnat; }: 定义链的类型和钩子。
    • type nat: 指定链的类型为 NAT。
    • hook postrouting: 指定链挂载的钩子位置,这里是在 POSTROUTING,即在路由决策后处理出站数据包。
    • priority srcnat: 设置链的优先级,这里是用于源 NAT。
nft add rule ip nat postrouting oifname "enp1s0" masquerade
  • add rule: 添加一条新规则。
  • ip nat postrouting: 指定规则所属的表、家族和链。
  • oifname "enp1s0": 规则的匹配条件。这里表示匹配出站接口名称为 enp1s0 的数据包。
  • masquerade: 执行的操作,即 MASQUERADE。这会将数据包的源地址改为出站接口的地址。这用于动态地改变数据包的源地址,使得从内部网络(例如私有网络)出去的数据包看起来都是从防火墙或者网关的公共地址发出的。。

创建 Filter 表和规则

nft add table ip filter
  • 同上,这次创建的是名为 filter 的表,用于包过滤。
nft add chain ip filter forward { type filter hook forward priority 0; }
  • add chain: 添加链。
  • ip filter: 指定表和家族。
  • forward: 链的名称。
  • { type filter hook forward priority 0; }: 定义链的类型和钩子。
    • type filter: 表明这是一个过滤链。
    • hook forward: 指定在 FORWARD 钩子上,即处理转发的数据包。
    • priority 0: 设置链的优先级。
nft add rule ip filter forward iifname "gnb_tun" oifname "enp1s0" accept
  • add rule: 添加规则。
  • ip filter forward: 指定规则所属的表、家族和链。
  • iifname "gnb_tun": 匹配入站接口名称为 gnb_tun 的数据包。
  • oifname "enp1s0": 同时匹配出站接口名称为 enp1s0
  • accept: 规则的动作,这里是接受匹配的数据包。

nftables 中,规则是按照定义的顺序进行处理的,所以确保您的规则顺序符合您的网络策略需求。

如何确认已经启用上述规则?

要检查是否已经设置了上述的 nftables 规则,您可以使用 nft 命令来列出当前的规则集。这样可以查看所有的表、链和规则,包括您刚刚添加的那些。以下是如何进行检查的步骤:

列出所有规则集:

sudo nft list ruleset

这个命令会显示当前系统上所有的 nftables 配置。它包括所有的表、链和规则。由于输出可能很长,您可能需要仔细查看或使用文本编辑器进行搜索。

查看指定的表

如果您只想查看特定的表,比如 nat 表或 filter 表,可以使用以下命令:

sudo nft list table ip nat

# 或者
sudo nft list table ip filter

查看特定表中的特定链

如果您想要更加具体,只查看某个特定表中的特定链,例如 nat 表中的 postrouting 链或 filter 表中的 forward 链,可以使用如下命令:

sudo nft list chain ip nat postrouting

# 或
sudo nft list chain ip filter forward

这些命令将仅显示您指定的链及其包含的规则。

保存当前的规则集

在默认情况下,通过 nft 命令直接添加到 nftables 的规则在服务器重启后不会自动保留。这意味着,如果您重启服务器,您之前添加的规则将丢失,除非您采取了措施来持久化这些规则。

导出规则集

sudo nft list ruleset > /etc/nftables.conf

这个命令会将当前的 nftables 规则集导出并保存到 /etc/nftables.conf 文件中。这是大多数 Linux 发行版的标准位置,包括 Ubuntu。

确保在启动时加载规则

设置自动加载:

  • 大多数现代 Linux 系统(使用 systemd)都会在启动时自动加载 /etc/nftables.conf 中的规则,因为 nftables 服务默认会查找这个文件。
  • 如果您的系统没有自动执行此操作,您可能需要启用 nftables 服务:
sudo systemctl enable nftables

检查配置文件

  • 确保 /etc/nftables.conf 文件包含了您想要的规则。

  • 在重启之前,您可以手动运行如下命令,来测试配置文件是否正常工作。

sudo nft -f /etc/nftables.conf

nftables 的主要概念和工作流程

nftables 的主要概念是围绕着“表(Tables)”、“链(Chains)”和“规则(Rules)”。这三个组件构成了 nftables 配置的核心。除此之外,还有一些其他的概念,如“集合(Sets)”和“元素(Elements)”,但表、链和规则是最基础和最重要的。

下面是这些概念之间的关系和它们的作用:

表(Tables)

作用:表是用于存储规则的容器。它们提供了一个组织结构,用于分类规则。

类型:表可以是特定类型的,如 filternat 等,这决定了表中的链和规则可以执行的操作类型。

链(Chains)

作用:链是规则的序列,它们定义了如何处理网络流量。链可以是内建的(如 INPUTFORWARDOUTPUT 等),也可以是用户定义的。

钩子(Hooks):链与特定的网络流量处理点(钩子)相关联,例如 preroutinginputoutputpostrouting。这决定了链在网络堆栈的哪个点上处理数据包。

规则(Rules)

作用:规则定义了对匹配特定条件的数据包执行的操作。每条规则都包含一个或多个匹配条件和一个动作(如接受、丢弃、修改等)。

顺序:规则在链中按定义的顺序执行,直到找到匹配的规则。

集合(Sets)和元素(Elements)

集合:集合是一组预定义的值,可以在规则中使用。例如,您可以创建一个包含特定 IP 地址的集合,并在规则中引用这个集合来匹配这些地址。

元素:元素是集合中的具体值,如特定的 IP 地址、端口号等。

它们之间的关系

层级关系:表位于最顶层,存储着一系列的链。链则定义了特定条件下应当如何处理数据包,通过一系列的规则来实现。

工作流程:当网络流量到达时,它会根据其类型(如 IPv4 或 IPv6)和目的(如过滤或 NAT)进入相应的表。然后,根据流量的具体特性(如来源、目的地等),在表中的适当链上进行处理。最终,链中的规则会根据匹配条件决定对数据包的操作。

3、配置路由

我们演示的要能ping通,所以需要配置两条路由,一条去的路由(红线),一条回来的路由(蓝线)。

去的路由

在 192.168.1.28 上,你需要确保有一条路由告诉它如何到达 10.2.0.0/24 网络。这可以通过以下命令完成:

ip route add 10.2.0.0/24 via 192.168.1.5

这告诉 192.168.1.28,要到 10.2.0.0/24 网络,需要通过 192.168.1.5。

回来的路由

在 10.2.0.8 上,确保它知道如何将数据包发送回 192.168.1.0/24 网络。这可能已经由默认路由覆盖,但如果没有,你需要添加一个类似的路由:

ip route add 192.168.1.0/24 via 10.2.0.3

这告诉 10.2.0.8 通过 10.2.0.3(你的路由器的另一个接口)来达到 192.168.1.0/24 网络。

ip route add 参数说明

ip route add 命令的一般形式及其参数的含义:

ip route add [destination] via [gateway] dev [device] [additional-options]
  • [destination]: 这是目的网络的地址。它可以是一个特定的 IP 地址,也可以是一个 IP 地址范围,通常以子网掩码(如 /24)表示。例如,192.168.1.0/2410.0.0.0/8

  • via [gateway]: (可选)这个参数指定了到达目的地的网关或下一跳地址。网关应该是本地连接的网络上的一个地址,通常是路由器的接口地址。

  • dev [device]: (可选)这个参数指定了用于发送到该目的地的数据包的网络接口(如 eth0eth1wlan0 等)。在多网卡系统中,这可以用来指定特定的网络接口。

  • [additional-options]: 这里可以包括额外的选项,如 src [address](指定发送数据包时使用的源 IP 地址),metric [value](为路由指定一个度量值,用于在有多条路由可用时选择路由),和其他高级路由选项。

一个典型的命令可能如下所示:

ip route add 192.168.2.0/24 via 192.168.1.1 dev eth0

这个命令的含义是:添加一条路由,指示系统发送到 192.168.2.0/24 网络的所有数据包都应该通过 192.168.1.1 这个网关,且使用 eth0 网络接口。

常用分析工具

  • 使用 ping 命令测试网络连通性。
  • 使用 traceroute(在 Windows 上是 tracert)命令追踪数据包的路径。

ping命令

ping 命令是一个常用的网络工具,用于测试到另一台计算机的网络连接。

以下是一些跨平台常见的参数:

  • -4:强制使用 IPv4。

  • -6:强制使用 IPv6。

  • -t (仅限 Windows):持续 ping 目标主机,直到手动停止(使用 Ctrl+C)。

  • -c [次数] (通常用于 Linux/Mac):发送指定数量的 echo 请求包。例如,ping -c 4 [目标地址]。

  • -w [秒] (Windows) / -W [秒] (Linux/Mac):设置超时时间,单位为秒。如果响应时间超过此值,ping 请求将失败。

  • -i [秒]:设置 ping 请求之间的时间间隔(以秒为单位)。

  • -s [大小]:指定要发送的数据包的大小(以字节为单位)。

  • -l [大小] (仅限 Windows):设置发送缓冲区大小。

  • -a:将地址解析为主机名。

  • -n [次数]:发送指定数量的 echo 请求包。

  • -r [次数] (仅限 Windows):记录传递数据包的路由。

  • -v (Linux/Mac):详细模式,显示每个回应数据包的详细信息。

不同的操作系统和不同版本的 ping 命令可能支持不同的参数集合。因此,最好查看您的特定系统上的 ping 命令的帮助文档或手册页(通常可以通过在命令行中输入 ping -hman ping 来访问)

traceroute/tracert

traceroute(在Windows中通常称为tracert)是一个网络诊断工具,用于显示数据包在到达指定目的地时所经过的路径。这个命令的常用参数因操作系统的不同而略有差异,但以下是一些常见的参数:

对于 Unix/Linux 系统 (traceroute):

  • -n: 不解析地址到主机名。这会显示IP地址而不是机器名。
  • -m [max_ttl]: 设置最大生存时间(TTL)值,即最大跳数。
  • -q [nqueries]: 设置每跳发送的查询数。
  • -w [waittime]: 设置每次查询的等待时间。
  • -I: 使用ICMP回声请求代替UDP数据包。
  • -T: 使用TCP SYN数据包而不是UDP或ICMP。
  • -A: 进行AS号(自治系统号)查询。
  • -f [first_ttl]: 指定起始的TTL值。
对于 Windows 系统 (tracert):
  • -d: 不解析地址到主机名。
  • -h [max_hops]: 定义最大跳数。
  • -w [timeout]: 等待每个回应的毫秒数。
  • -j [host-list]: 使用源站选路(源路由)的主机列表。
  • -R: 使用ICMP回声请求跟踪回路。
  • -S [srcaddr]: 使用指定的源地址。
  • -4: 强制使用IPv4。
  • -6: 强制使用IPv6。

PathPing/MTR

结合了 pingtracert/traceroute 的工具有PathPing(Windows) 和 MTR(My Traceroute,在Unix/Linux上)

PathPing(Windows)

PathPing:这个工具结合了 ping 和 tracert 的功能,它会发送多个数据包到每个跳点,并统计丢包率和延迟。这对于识别链路中的问题节点非常有用。

如何使用 PathPing

打开命令提示符

在Windows中,点击“开始”菜单,然后在搜索框中输入“cmd”或“命令提示符”,然后选择“命令提示符”程序。

运行 PathPing

在命令提示符中,输入以下命令:

pathping [目的地地址]

其中 [目的地地址] 可以是一个IP地址或一个域名。例如:

pathping www.google.com

pathping 192.168.1.1

等待结果

PathPing 首先会列出到达目的地的路径,这部分类似于 tracert 的输出。
然后,它会进行一系列测试,通常持续几分钟,以收集和计算每个节点的丢包率和响应时间。这一部分是 PathPing 独有的。

分析输出

输出结果会显示经过的每个节点(跳点)及其相应的统计数据。
查看每个节点的丢包率和延迟时间,可以帮助你识别网络中可能出现问题的节点。

注意事项
  • PathPing 的完整测试可能需要几分钟到十几分钟不等,具体取决于路由的复杂性和网络状况。

  • 输出结果的最后部分,即统计数据,尤其重要。它提供了关于网络性能和可靠性的详细信息。

  • 在分析结果时,高丢包率或异常高的延迟可能表明该节点存在问题。

通过使用 PathPing,你可以更全面地了解网络性能问题,并识别出问题发生的具体位置。

MTR(My Traceroute,在Unix/Linux上)

MTR:类似于PathPing,MTR结合了 tracerouteping 的功能,能持续监测网络链路状况,可以显示到达目标主机的路径以及每一跳的延迟。

要使用 mtr,您首先需要确保它已经安装在您的系统上。在大多数基于 Debian 的系统(如 Ubuntu)中,您可以使用以下命令安装它:

sudo apt-get update
sudo apt-get install mtr

安装完成后,您可以通过以下命令使用 mtr

mtr [目标主机名或IP地址]

例如:

mtr google.com

这将显示从您的计算机到 google.com 的路由,包括每一跳的统计信息。

mtr 提供了丰富的输出,显示每个中继站点的地址、数据包丢失率、响应时间等信息。这对于诊断网络问题非常有用。

还有一些选项可以用来定制 mtr 的输出,例如:

  • -n:不进行 DNS 反向解析,直接显示 IP 地址。
  • -r:生成报告模式。
  • -c:设置发送的 ping 包数量。

例如,要发送 10 个 ping 包并生成报告,您可以使用:

mtr -r -c 10 google.com

mtr 是一个非常强大的网络诊断工具,适用于排查复杂的网络问题。

tcpdump

要捕获特定接口的数据包,可以使用:

sudo tcpdump -i [网卡名]

查看指定网卡上来自特定来源 IP 的数据包

sudo tcpdump -i [网卡名] src [来源IP]

# 例如,如果你想要监听 eth0 网卡上来自 IP 地址 192.168.1.100 的数据包,你可以使用以下命令:

sudo tcpdump -i eth0 src 192.168.1.100

#如果你只对特定类型的协议(如 TCP 或 UDP)感兴趣,可以进一步指定。例如,只捕获 TCP 数据包的命令是:

sudo tcpdump -i eth0 src 192.168.1.100 and tcp


# 只查看目标端口为 80 的数据包:

sudo tcpdump -i eth0 src 192.168.1.100 and port 80

# 保存到文件: 使用 -w 选项,你可以将捕获的数据包保存到一个文件中,稍后进行分析:

sudo tcpdump -i eth0 src 192.168.1.100 -w capture_file.pcap

总结

通过本文的介绍,您现在应该对路由转发的配置流程有了清晰的认识,并掌握了一系列分析和定位网络问题的工具。无论是基础的 ping 命令,还是更高级的 tcpdump 分析,这些工具都是每位网络管理员必备的武器。记住,网络管理是一个持续学习和适应的过程。随着您技能的提升和经验的积累,您将更加自信地面对各种网络挑战。祝您在网络管理的道路上一帆风顺!