网关为0.0.0.0 或者* 表示表示此条路由不需要通过网关转发,目标地址和自己属于同一个二层网络,通过ARP协议获取目标的MAC地址后通信,比如一些虚拟网卡,不需要路由。

在Linux上配置其他网段路由的时候一定要指明网关,而不是只指明这个网段的出接口,否则会默认本目标网段与接口是直连的。

route add default dev eth0 等效为:route add -net 0.0.0.0 netmask 0.0.0.0 dev eth0。下一跳是eth0设备,使用此路由的数据直接发往目标IP

route add default gw * dev eth0 等效为:route add -net 0.0.0.0 netmask 0.0.0.0 gw * dev eth0。下一跳是gw IP地址,数据通过网关转发

路由下一跳是接口还是IP设备的最大区别就是ARP表的区别:下一跳是IP设备的话,数据包毫无疑问交给了IP网关,但是如果下一跳只是接口的话是需要单独对目标ip做arp解析的,如果IP网关上没有开启接口的proxy arp feature的话是不会响应这个arp请求,数据包无法完成二层封装,无法发送出去

实验

说明

image-20220423164559089

PC为内网主机。PC_ROUTE为路由器,有内网网卡和公网网卡(需要开启ip_forward转发)。Inter_Server作为其他网段的服务器,有外网接口STR和内网服务地址S_eth0

PC默认路由发往PC_ROUTE,PC_ROUTE默认路由发往RTS。Inter_Server做三种配置:1.不配置默认路由 2. 配置到PC网段的目标路由,不设置网关。route add -net 192.168.0.0/24 dev STR。3. 配置到PC网段的目标路由,设置网关。route add -net 192.168.0.0/24 gw 10.10.0.20 dev STR

配置

  1. 创建三个namespace

    1
    2
    3
    4
    5
    6
    7
    8
    # 本地主机
    $ ip netns add PC

    # 路由
    $ ip netns add PC_ROUTE

    # 远程服务主机
    $ ip netns add Inter_Server
  2. 创建2对veth

    1
    2
    3
    $ ip link add PTR type veth peer name RTP

    $ ip link add RTS type veth peer name STR
  3. 将veth分别加入到创建的namespace中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # PTR加入到本地PC
    $ ip link set PTR netns PC

    # RTP RTS加入到中间路由
    $ ip link set RTP netns PC_ROUTE
    $ ip link set RTS netns PC_ROUTE

    # STR加入到远程服务主机
    $ ip link set STR netns Inter_Server
  4. 设置IP地址并启动网卡

    1
    2
    3
    4
    # 进入到PC的namespace bash中
    $ ip netns exec PC bash
    $ ip address add 192.168.0.2/24 dev PTR
    $ ip link set PTR up

    image-20220422151709864

    同理设置其他的IP

    1
    2
    3
    4
    # 进入到路由的namespace bash中
    $ ip netns exec PC_ROUTE bash
    $ ip address add 192.168.0.1/24 dev RTP
    $ ip address add 10.10.0.20/24 dev RTS
    1
    2
    3
    4
    5
    6
    7
    # 进入到远程服务的namespace bash中
    $ ip netns exec Inter_Server bash
    $ ip address add 10.10.0.10/24 dev STR
    #远程服务添加第二块网卡S_eth0
    $ ip link add S_eth0 type dummy
    $ ip address add 2.2.2.2/32 dev S_eth0
    $ ip link set S_eth0 up
  5. 设置PC、PC_ROUTE默认路由

    1
    2
    3
    4
    # PC默认路由
    route add default gw 192.168.0.1 dev PTR
    # PC_ROUTE默认路由,不设置默认网关
    route add default dev RTS

测试

此时PC与PC_ROUTE可以互通,PC_ROUTE与Inter_Server互通,PC与Inter_Server不通

  1. 在Inter_Server加入不设置网关的默认路由

    1
    route add -net 192.168.0.0/24 dev STR

    此时PC仍ping不同Inter_Server

    image-20220424101941787

    抓包发现此时Inter_Server要向192.168.0.2发送数据包需要先ARP协议询问地址。

  2. 在Inter_Server加入设置网关的默认路由

    1
    route add -net 192.168.0.0/24 gw 10.10.0.20 dev STR

    image-20220424103514568

    可以发现此时Inter_Server不需要arp查询192.168.0.2mac地址了,而是直接将数据包发往网关mac地址交由网关转发。


同网段和不同网段的ARP协议

0.0.0.0 网关的含义

Task-centered iproute2 user guide