坑边闲话:讲真,Windows 是我最爱的系统,没有之一。有人问,你作为一个 Geek 竟然不爱 UNIX,这“河狸”吗?其实真的很合理。Windows 是我见过的设计得最精妙的系统,保持强大兼容性的同时,Server 版的稳定性也好得没话讲。所以我想聊聊 Windows 的网络配置。后期也有可能出几期用 Windows Server 2019 当软路由的教程。

1. 前言:请抛弃 DOS·

现在 Windows10 系统依旧内置了一个 DOS 模拟器,而这也就是我们常说的 cmd.exe 程序。通过这个程序可以运行好多简单的网络命令,比如 ping、ipconfig 等。尽管看起来如此方便了,但是我们要明确,cmd.exe 早就老掉牙了~~

有更好、更新的东西等着它呢~~

记得我本科时有位哲学课老师说,“新的就是好的”。我当初很不理解这句话,觉得这也太古怪了吧?!新的东西可能兼容性不好,所以有可能出各种问题。后来我把这句话魔改为“新的稳定版就是好的”,至今我仍旧奉行这句话,所以一直都保持着对新鲜事物的热爱与探索。

废话不多说,直接开始上主题:如何用 Powershell 设置 Windows 的路由表。

2. Powershell 的 NetAdapter 和 NetTCPIP 命令家族·

NetTCPIP 是微软 Powershell 下非常常用的一套命令,里面有三十多个 cmdlet(可以简单认为是某些 Linux 下的命令)。具体可以参考微软的官方文档。今天我们介绍其中比较简单的几个。

在开始之前,应该明白 Windows 路由表的一个表项(Item)应该包含哪些元素。

路由表条目所对应的 Interface. 这个 Interface 可以初步认为是某个物理网卡(实际上不完全是这样),在 Powershell 里,这个 Interface ID 用一个正整数表示,我们用 IfIndex 来指代这个 ID.

路由表条目的 IP 版本,用 AddressFamily 表示 。这个很好理解,它就是用来标识路由表是 IPv4 还是 IPv6 的。

路由表条目的目的地,用 DestinationPrefix 表示。这个也很好理解,数据包在路由器里被转发,路由器就问你,你要去哪里啊?你告诉路由器,我要去某个目的地。这时候路由器根据你的目的地,查询一下路由表,然后告诉你从哪个口出发。如果表里没有你要去的目的地,就把你发往默认的出口。所以路由器要存储并实时维护路由表,我们程序员要做的就是配置这个路由表。你可以在 IfIndex 10 上添加一个可达的目的地址,这个目的地址用 IP/subnet-mask 的形式表示。掩码在这里不一定指代一个真实的子网,其实理解成前缀匹配更合适。

这条路由表条目的优先级,用英文 RouteMetric 表示。Metric 表示一种度量,用来标识优先级再好不过了。RouteMetric 越小,说明优先级越高。这里我们解释一下为什么需要定义路由表条目的优先级。因为一个路由器有能力连接多个网络,比如你的路由器用 LAN 口连接局域网,Eth1 口连接贵公司的存储网络,Eth2 口连接 Internet. 而恰巧你公司的存储网络也可以通过互联网访问。所以这时候你的 Eth1 口应该有一个通向存储网络的路由表项,Eth2 也有一个通向存储网络的路由表项。说人话就是通过 Eth1 和 Eth2,都可以将数据转发到贵公司的存储网络。但是 Eth1 是直连存储网络,速度快一些,Eth2 是经过互联网转发,延迟可能很大,带宽也可能很小。这时候我们把 Eth1 上的路由表条目的 RouteMetric 弄小一点,后者弄大一点,这样就建立了优先级顺序。发往存储网络的数据包在路由器被转发时,会优先走 RouteMetric 小的那个口。

注意,如图 1 所示,网络面板适配器属性里,也可设置 IPv4/IPv6 的跃点数。但是这个跃点数与上面提到的 RouteMetric 是两个值。这里的 Metric 叫做 IfMetric,即网络接口跃点数。一条路由表会同时有这两个 Metric,但是 RouteMetric 的优先级又要高于 IfMetric.这就相当于东京奥运会,我们比较国家的综合排名,看的是金牌数,而不是银牌数。说得直观点,就是说如果出现了两个路由表,它们去往同一个地址,但是走的网口不一样,一个走 WAN1,另一个走 WAN2,这时候就需要用到 Metric 来仲裁了!WAN1 接口的 IfMetric 可能优先级更高,但是在这一条路由上,WAN1 所在的这个路由表条目的 RouteMetric 优先级却更低。根据 RouteMetric(金牌)是考虑的第一要素这个原则,我们断定要走 WAN2. 就是这么简单。后面将会举个例子。

下一跳,NextHop. 这个指的是数据包具体被转发给你 WAN 口那边的网络里的谁。比如你的 WAN 口插在一个交换机上,交换机上又接入了两个更高一层的路由器 RA 和 RB,这时候你的 WAN 有能力把数据选择性地转发给 RA 或 RB,因此要用 NextHop 来指定到底转发给哪个路由器。在实际生活中,我们经常面对的是中国移动或者中国联通,所以这个 NextHop 也就是你光猫后面那个服务商的路由器的 LAN 口 IP 地址。一般你的电脑插上网线就会自动获得一个路由表,通过该路由表就能看到 NextHop. 在你的 Windows 上,这个 NextHop 一般就是你的路由器的内网地址。

图 1. 这里的跃点数 Metric 指的是 IfMetric,而不是 RouteMetric. 后者只能通过命令行查看。

3. 实战演练·

图 2. Get-NetRoute 命令。

首先看一下图 2,命令为 Get-NetRoute. 如果你不加参数地执行,那么会输出很长的一串。加了一些选择参数,就能看到简洁的输出。在这里我们仅选择下一跳 NextHop 不为 0.0.0.0 的路由表。而图 2 里的 DestinationPrefix0.0.0.0/0 指的是这是一个默认路由。如果你的电脑插了多条网线,那么可以自定义路由。比如自定义一条到 10.0.0.88 (我的 NAS 的局域网地址)的路由表。

类似的命令还有 Set-NetRouteRemove-NetRoute. 一般人掌握到创建、删除、修改路由表就够了。详情参见微软的官方手册,英文过关的话,看起来毫无障碍!

图 3. 微软官方 Powershell 手册的截图。

另外提一下 Get-NetAdapter 命令,这个命令可以输出当前电脑的网卡,以及查看相应的状态。通过这个命令可以查看网卡对应的 IfIndex,然后再根据 IfIndex 设置路由表。

图 4. Get-NetAdapter 命令,打印出当前的网络接口。

4. 创建路由表实例·

在之前的实例中,我介绍了一个如图 5 所示的单 PC 虚拟化的结构。

图 5. 单机虚拟化,这与“旁路由”透明代理的区别在于,我这个网络的主路由也可以借助第二块网卡实现访问“旁路由”。

不过今天并不是介绍这个网络结构,而是想说一下在 Windows Host 这一边,由于有 Ethernet_UCAS(国科大校园网)和 vEthernet_LAN(旁路由的接入点)两张网卡,而且校园网还要过深澜沧科技的认证。所以尽管宿主机能直接通过自己的 Ethernet_UCAS 完成认证,但这也是不满足需求的,因为我们想让 OpenWrt 完成认证,而不是宿主机!

这可如何是好?

其实我们的诉求很简单,那就是让访问校园网认证服务器的数据包强制走 OpenWrt 中转,而不是直接发出去。所以添加一条路由表就好了。

执行如下命令:

1
New-NetRoute -ifIndex 53 -DestinationPrefix 124.16.81.61/32 -NextHop 10.10.10.1 -RouteMetric 1
  • New-NetRoute,顾名思义就是创建一个新的路由表项
  • IfIndex 53,即在 53 号接口上创建,因为这个接口连接了 OpenWrt
  • DestinationPrefix 124.16.81.61/32,这就是目的地址,也就是校园网认证服务器的地址
  • NextHop 10.10.10.1,即下一跳的地址,在这里就是 OpenWrt 虚拟机的 LAN 口地址
  • RouteMetric 1,即路由的跃点数,设置为 1,优先级非常高!以此强制要求通往验证服务器的数据包走 53 号接口

完成了这一步,在访问并登录验证服务器,就发现 OpenWrt 的 WAN 口地址被注册进去了!美滋滋。

看了下面这个视频还不会配置路由表的同学,一定要好好学习这篇文章,然后看懂微软的手册。

OK,本期的 L.L 教程先到这里,对 Powershell 感兴趣或者有问题的伙伴,可以在评论区留言讨论,进一步的交流,可私信查看自动回复,进群直接问老湿基。