草庐IT

IP路由基础之静态路由

sunboy_guo 2023-04-12 原文

1.路由的含义

        交换机隔离冲突域,路由器隔离广播域。同一局域网下的设备通过二层转发即可实现通信,即交换机查询MAC地址表来进行转发。那么不同网段的主机进行通信时,如何进行数据转发?这个时候需要进行三层转发操作,即网络层依靠路由表来实现IP寻址和路径选择。

路由表示的是去往目的IP地址的最近的一个中转站,去往中转站就要明确指出中转站的地址(下一跳地址)以及从本端如何出去(出接口)。因此,一条路由的必要组成分为目的网段、目的网段掩码、出接口、下一跳地址。

2.路由表

        维护路由表最典型的代表设备就是路由器,路由表存放着该设备去往已知网段的最优路由。数据去往目的地可能有多个不同的路径,在路由表中展现出来的,就是那条最优的路径。

destination/mask:目的网段和掩码

proto:路由协议

常见的协议有direct,static,OSPF,ISIS,BGP等 

pre:路由优先级,当目的地址相同时,路由器根据优先级选择最优的路由放入路由表中,以小为优,范围0-255。

直连路由direct:优先级为0,不可以更改。

静态路由static:优先级为60

动态路由OSPF:优先级为10或150(ospf内部和外部)

动态路由ISIS:优先级为15

动态路由BGP:优先级为255

cost:度量值,当优先级相同时,比较度量值选择最优的一条路由放入路由表。

flags:标志位,R代表要递归查询,D代表在fib转发表中,可以直接进行转发。

nexthop:下一跳地址,去往目的地址转发的下一个设备。

interface:出接口,数据去往下一条从哪个接口转发出去,出接口可以是物理接口,也可以是逻辑接口。

3.路由表中路由的来源

        3.1 直连路由

        直连路由是指通过传输介质直接连接在设备接口上的网段,设备根据自己端口上的IP地址和掩码,通过与运算得出网络地址,自动生成直连路由放入路由表中。

        直连路由产生的前提条件是设备端口的物理状态和协议状态都要UP,并且端口要配置IP地址。当端口down以后,该直连路由将在路由表中消失。

        3.2 静态路由

        静态路由是由管理员手工配置上去的,简单方便,但是静态路由不能感知到网络的变更,路由信息无法根据网络的改变而自动更新,需管理员手工更改或者删除,因此,静态路由不适用于大型的网络中,不具有时效性。

        3.3 动态路由

        相比于静态路由而言,动态路由是设备之间通过交互信息互相学习而来的路由条目,可以根据网络中路由的变更,动态的进行更新。但是由于需要设备之间进行报文进行信息交互,因此,动态路由会占用一定的链路带宽资源。

4.静态路由

        静态路由是需要管理员手工配置的,根据路由的必要组成部分,路由组成的必要条件需要目的网段和掩码、出接口和下一跳地址。那么如何配置静态路由呢?以下面拓扑为例:

        

 描述:

        

设备接口IP地址掩码
R1G0/0/010.1.12.124
R2G0/0/010.1.12.224
S1/0/010.1.23.224
R3S1/0/010.1.23.324
loopback03.3.3.332

要求R1能够访问3.3.3.3

        首先在R2上配置去往3.3.3.3的静态路由。

[r2]ip route-static 3.3.3.3 32 s1/0/0----配置静态路由

测试连通性:

 

        在R3上配置回包路由

[r3]ip route-static 10.1.12.0 24 s1/0/0----配置去往R1的静态路由

在R1上配置去往3.3.3.3的静态路由

[r1]ip route-static 3.3.3.3 32 g0/0/0------配置去往3.3.3.3的静态路由

 ping测试连通性:

可以看到R1此时ping不通3.3.3.3,抓包查看:

可以看到R1发出的ARP request没有响应。原因分析:

        1.根据ping通原理,R1ping 3.3.3.3时,需要查看IP路由表,有路由则进行ICMP的封装。

        2.封装ICMP,

ICMP echo-requestSIP:10.1.12.1,DIP3.3.3.3SMAC:R1,DMAC:?

        3.由于不知道3.3.3.3的MAC地址,所以查看ARP缓存表。

        4. ARP缓存表没有3.3.3.3的表象,所以建立一个incomplete条目,发送ARP request。

ARP requestSIP:10.1.12.1,DIP3.3.3.3SMAC:R1,DMAC:全F

        5.R2收到以后 解封装,查看目的IP不是自己,所以丢弃。

解决方法:

        方法1:在R2上开启ARP代理

[r2-GigabitEthernet0/0/0]arp-proxy enable----开启ARP代理

测试连通性:

抓包查看

可以看出,当R2配置了ARP代理功能以后,R2用自己的接口地址回复了R1的ARP request。

ARP代理在本质上就是一种ARP的欺骗。 

        方法2:配置静态路由时写明下一跳地址。

        关闭R2上的ARP代理功能,重新在R1上配置静态路由。

        R2配置

[r2-GigabitEthernet0/0/0]undo arp-proxy enable ----关闭ARP代理功能

        R1配置

[r1]ip route-static 3.3.3.3 32 10.1.12.2-----配置静态路由指明下一跳地址

测试连通性

抓包查看

 

R1发送的ARP请求的是下一跳的MAC地址,由此可见,下一跳地址的作用就是为了ARP能够请求到MAC地址,完成二层的封装。

  问题1:为什么只写下一跳不写出接口也可以?

        查看路由表

由此可见,不写出接口的情况下,路由中的flags变成了RD,也就是需要递归查询。去往3.3.3.3的下一跳是10.1.12.2,再递归查询去往10.1.12.2的路由,发现是直连路由,出接口是G0/0/0接口。因此,只写下一跳地址可行。

        问题2:下一跳和出接口都写是否可行?

        可行,但是不建议都写。因为写明了出接口,数据就只会通过此接口发送出去,如果是冗余链路,此接口down了以后,数据将无法继续进行通信,适合单一出口的情况下这样写,不用做递归查询,转发更高效。

        问题 3:为什么R2和R3之间只写出接口就可以?

        因为R2和R3之间是P2P链路,通信不需要封装MAC,封装的是PPP帧头,所以不需要写下一跳地址。 

         总结静态路由书写方式:

 MA链路:

       ip route-static 3.3.3.3 32 g0/0/0----不可以
       ip route-static 3.3.3.3 32 10.1.12.2----可以,推荐

       ip route-static 3.3.3.3 32 g0/0/0 10.1.12.2----可以,不推荐 

P2P链路:

         ip route-static 3.3.3.3 32 s1/0/0----可以,简单高效

         ip route-static 3.3.3.3 32 10.1.12.2----可以,多宿主冗余

         ip route-static 3.3.3.3 32 s1/0/0 10.1.12.2----多余,没必要

5.最长掩码匹配 

         路由器在进行路由转发的时候,查看目的IP地址和掩码,按照最长掩码匹配的原则进行路由转发。

                在R2上另写一条3.3.3.0/24的静态路由,当R2收到目的地址是3.3.3.3的时候,这时匹配到两条路由,3.3.3.0/24和下面的3.3.3.3/32,此时R2会根据最长掩码匹配的原则,选择3.3.3.3/32这条路由进行转发。

6.特殊路由

         6.1 缺省路由

        配置:

[r1]ip route-static 0.0.0.0 0 10.1.12.2----配置缺省路由

        缺省路由也叫默认路由,当去往的目的网段匹配不到路由表中的其他路由时,就会通过缺省鲈鱼转发出去,适用于访问互联网或者单一出口的情况下。

        6.2 黑洞路由

        配置:

[r1]ip route-static 20.0.0.1 8 NULL 0-----配置黑洞路由

 当设备的目的网段匹配到黑洞路由时,就会发往逻辑接口null0,相当于是直接丢弃掉,不进行转发,可以用来聚合路由防环。

7.高级特性 

        7.1 负载分担 

         当设备有多个出口可以去往目的网段时,可以配置多条静态路由,以达到路由冗余负载的效果,当一跳链路断开,还有另外的路由可以转发。

        配置:

[r1]ip route-static 3.3.3.3 32 100.1.12.2-----在R1上再加一条去往3.3.3.3的静态路由

       查看路由表:

         可以看到去往3.3.3.3的路由是等价负载的,一个down掉,还有另外一个。

        7.2 非等价负载

         当两条链路的带宽不一致,10网段是3G带宽,100网段是1G带宽时,可以实现3个包走10网段,1个包走100网段。

        配置:

[r1]ip route-static 2.2.2.2 255.255.255.255 100.1.12.2
[r1]ip route-static 3.3.3.3 255.255.255.255 7.7.7.7
[r1]ip route-static 3.3.3.3 255.255.255.255 8.8.8.8
[r1]ip route-static 3.3.3.3 255.255.255.255 9.9.9.9
[r1]ip route-static 3.3.3.3 255.255.255.255 2.2.2.2
[r1]ip route-static 7.7.7.7 255.255.255.255 10.1.12.2
[r1]ip route-static 8.8.8.8 255.255.255.255 10.1.12.2
[r1]ip route-static 9.9.9.9 255.255.255.255 10.1.12.2

查看路由表

        

        7.3  浮动路由 

         当路由表中只需要一条路由,不需要负载的时候,但是需要一条路由作为备份,可以通过设置优先级的方式来实现。

        配置

[r1]ip route-static 3.3.3.3 32 10.1.12.2 -----默认优先级60
[r1]ip route-static 3.3.3.3 32 100.1.12.2 preference 65-----增大优先级为65

        查看路由表:

 

 当10网段的链路断开时查看路由表

 

 

 

 

          

        

有关IP路由基础之静态路由的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  3. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  4. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  5. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  6. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  7. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  8. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  9. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  10. ruby - 在 TCPServer (Ruby) 中,我如何从客户端获取 IP/MAC? - 2

    我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!

随机推荐