回车键,日常电脑使用中,扮演“确认”或“执行”事件的功效。


在网络工程师的平日运维工作中,无论是计划性的网络配置修改,还是临时性的故障处理,大家是否都存在同样的感受:特别小心敲击回车键,再三确认以后才执行


相信以下场景是很多做网络的朋友曾经都遇到过的,在远程配置 Cisco 或者其他厂商路由器或交换机时,一顿复制粘贴然后敲下回车结果就是这样:

1. 配错接口 IP 地址——Game Over!

2. 修改静态路由条目或者动态路由协议,导致路由丢失----Game Over!

3. 配置错 VLAN ID 或者二层接口 ACCESS/TRUNK 配置错误----Game Over!


这个时候大部分人都是一脸惊慌,脑子琢磨怎么解决:给远端人员打电话把路由器交换机重启。反正配置没保存呢,重启就回来了。


但是如果远端就是客户的话,后面几天日子恐怕就不太好过了。要是这是公司另外一个厂房的核心交换,这事儿就大了。重启是不可能了,再去现场花费的时间成本无可估量。


总的来说,在做日常网络配置中,回车恐惧症来源于如下几个方面:

● 对自己准备的配置没信心,担心配置中有低级错误

● 害怕配置设备过程中遇到意料之外的问题

● 和对端联调的时候,不信任对端,害怕远端工程师犯错导致联调不成功


以上的问题也曾让我在日常运维中头疼不已。直到后来我入职某运营商后,无论从客户的 CPE,到核心 PE,BNG 或者 P 路由器,绝大部分设备都是 Juniper。在慢慢从 Cisco 习惯过渡到 Juniper 的过程中,我发现这些担忧和问题极大地减少了。而且准确来说你有很大的机会在敲回车执行之间,就已经发现错误并予以纠正。


那到底在 Juniper 环境下,有什么行之有效而且简单易用的工具能够解决工程师的烦恼呢?


为了回答上面的问题,我将用一个日常割接流程来给大家揭晓答案。


说到割接流程,无非就三点: 

● 割接前期配置准备

● 进行割接

● 割接后复查


在介绍这些技巧之前,先给较少接触过 Juniper 设备的朋友们做个知识铺垫:和 Cisco 的 IOS 系统配置模式不同,JUNOS 系统配置模式里面,配置修改并不是立即生效。你可以随意增添甚至删除整个设备配置,只有你在通过 commit 提交配置后,才会生效。


(PS:请勿在现网设备随意模仿,可以在Juniper实验室或者模拟器上测试。)



割接前期配置准备


在前期配置准备过程中,我们怎么保证预配置没有低级错误,如打错字符,写错 IP 等?难道要每次都把预配置加载到实验室设备或者模拟器上跑一遍看看?


另外,由于配置脚本行数多,配置量大。在割接期间逐个复制粘贴很耗费时间;同时,在复制粘贴过程中,如果人眼跟踪不及时,容易忽略设备提示的错误。


那么,下面让我们用一个简单的例子来说明 JUNOS 都有哪些工具能够解决以上问题。

 

案例:

某部门计划隔天割接几台关键服务器到另外一台 Juniper 设备上,工程师计划配置一个新的 vlan 及 vlan interface。并划分两个物理接口到这个新 vlan 内。以下为该工程师做的预配置: 

set interfaces ge-0/0/6 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/6 unit 0 family ethernet-switching vlan members internal
set interfaces ge-0/0/7 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/7 unit 0 family ethernet-switching vlan members internal
 
set interfaces irb unit 5 family inet address 192.168.1.1/24
 
set vlans internal vlan-id 5
set vlans internal l3-interface irb.5


问题 1:一般情况,工程师会等到割接时才把所有准备的配置加载到设备上,那我们可否在准备配置前期提前加载到设备上?等到割接的时候,只需要执行几条关键的命令,就完成整个割接?这样既节省时间,也减少了出错率。

 

答案是可以的,上工具!


工具 1: load set terminal (加载set命令的配置,如果有语法错误会立即提醒)

load set terminal 是一个批量添加配置的工具,相比逐个命令复制粘贴,批量添加的好处是配置清晰明了。可以一目了然地发现错误的参数,尤其是在配置行数特别多的情况下,非常方便工程师查错。


它还有其他孪生兄弟,例如:load merge terminal,load patch terminal等。具体大家可以查阅Juniper文档。


让我们使用 load set terminal 把工程师准备的割接配置加载到设备上,方法如下: 

admin@Juniper>configure 
Entering configuration mode
 
admin@Juniper# load set terminal 
[Type ^D at a new line to end input]
set interfaces ge-0/0/6 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/6 unit 0 family ethernet-switching vlan members internal
set interfaces ge-0/0/7 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/7 unit 0 family ethernet-switching vlan members internal
 
set interfaces irbunit 5 family inet address 192.168.1.1/24
 
set vlans internal vlan-id 5
set vlans internal l3-interface irb.5
load complete
 
[edit]
admin@Juniper#

当所有命令加载完毕以后,键入 Ctrl+D 后就可以结束 load setterminal 的界面并回到了配置模式下。


工具 2: deactivate(告知 JUNOS 忽略某配置)

通过 deactivate 这一配置技巧,我们可以人为地忽略某配置。从而让 JUNOS 在读取配置的时候,不读取对应的配置参数。但是在通过 show configuration 的时候,仍然可见。


回到案例中,为了避免割接前配置的 vlan 接口 irb.5 的 IP 地址被其他路由协议发布到网络中,我们先把它 deactivate 掉。方法如下: 

[edit]
admin@Juniper# deactivate interfaces irb unit 5 family inet address 192.168.1.1/24


工具 3: disable (admin shut down某接口)

disable 就等同于 Cisco 的接口 shutdown。与 Cisco 相似,它也只能应用于接口级别。


为了让接口在割接前不开启,我们可以 shutdown ge-0/0/6 以及 ge-0/0/7 接口。方法如下:

admin@Juniper# set interfacesge-0/0/6 disable 
 
[edit]
admin@Juniper# setinterfaces ge-0/0/7 disable


最后,让我们来看看通过以上工具配置后的最终结果:

admin@Juniper# show interfaces | display set 
setinterfaces ge-0/0/6 disable
set interfacesge-0/0/6 unit 0 family ethernet-switching interface-mode access
set interfacesge-0/0/6 unit 0 family ethernet-switching vlan members internal
setinterfaces ge-0/0/7 disable
set interfacesge-0/0/7 unit 0 family ethernet-switching interface-mode access
set interfacesge-0/0/7 unit 0 family ethernet-switching vlan members internal
set interfaces irb unit 5 family inet address 192.168.1.1/24
deactivate interfaces irb unit 5 family inet address 192.168.1.1/24
 
admin@Juniper# show vlans | display set 
set vlans internal vlan-id 5
set vlans internal l3-interface irb.5

这里你可能会注意到在每个配置里面,都有一个对应的 deactivate 或者 disable 配置。


Tips:deactivate 和 disable 有什么区别?

disable 等同于 Cisco 的 shutdown,但是 JUNOS 系统会继续读取 ge-0/0/6 或者 ge-0/0/7 的接口配置,只是把它admin down了而已。

而 deactivate 直接让 JUNOS 忽略此配置,虽然你通过 show config 仍然能看见 irb unit 5 的 IP 地址,但是对于设备本身来说,它会完全忽略此IP。


问题 2:预配置完成以后,如何通过JUNOS核查配置错误,如何知道当前的配置与现有配置是否冲突呢?


工具 4: show | compare (对比原配置和加载的新配置之间的区别)

show | compare能够对比配置前后的差别,从而看出配置是否有误。


在本案例中,使用 show | compare 可以对比配置加载前后的区别,方法如下:

admin@Juniper# show |compare 
[edit interfaces]
+   ge-0/0/6 {
+       disable;
+       unit 0 {
+           family ethernet-switching {
+               interface-mode access;
+               vlan {
+                   members internal;
+               }
+           }
+       }
+   }
+   ge-0/0/7 {
+       disable;
+       unit 0 {
+           family ethernet-switching {
+               interface-mode access;
+               vlan {
+                   members internal;
+               }
+           }
+       }
+   }
[edit interfaces irb]
+    unit 5 {
+        family inet {
+            inactive: address 192.168.1.1/24;
+        }
+    }
[edit vlans]
+   internal {
+       vlan-id 5;
+       l3-interface irb.5;
+   }
 
[edit]
admin@Juniper#

你可以看到,左边为加号(+),证明此配置是新增配置。如果是减号(-),那么代表删除配置。


为了加强对这个工具的理解,下面再加一个示例:


### 额外示例 ###

某个工程师准备把接口 ge-0/0/5 从 access 模式变为 trunk 模式,并新增一个 Internet 的 vlan 在此接口下。完成配置并 show | compare 后,通过加减号就可以知道哪个配置删除了,哪个配置是新增的。示例如下:

admin@Juniper# show |compare 
[edit interfaces ge-0/0/5 unit 0 family ethernet-switching]
-      interface-mode access;
+      interface-mode trunk;
[edit interfaces ge-0/0/5 unit 0 family ethernet-switching vlan]
-       members MGMT;
+       members [ MGMT Internet ];

注意,show | compare 在日常 Juniper 运维中,占据了非常重要的角色,通过 show| compare 你可以清楚知道自己的配置是否符合预期。


工具5: commit check (设备配置自动核查)

通过 commit check,能够在提交配置之前,做最后一步的系统配置自检。


回到我们开头的案例。完成 show | compare 的检查以后,我们继续让 JUNOS 自行检查配置: 

[edit]
admin@Juniper# commit check 

configuration check succeeds
 
[edit]
admin@Juniper#

commit check 会告知你配置是否有误,是否与其他配置有冲突等。上面输出可以看出我们的配置没有问题。接下来就可以放心去提交配置了。

 

问题 3:在配置中如果需要修正错误配置或需要新增其他配置时,如何简洁高效地完成任务?


有些时候,大家载入配置过程中,发现脚本里面接口配置错误,或者IP地址配置错误。按照一般思路来的话,肯定是删除掉此命令,然后再重配置一遍。其实还有比这个更简单的方法,我们来看看对比:


上面的案例里,我们配置了 ge-0/0/6 和 ge-0/0/7 两个接口。假设服务器部门告诉你,正确接口应该是 ge-0/0/5,你需要把 ge-0/0/7 的配置挪到 ge-0/0/5 上。


传统方法:

delete interfaces ge-0/0/7 
 
set interfaces ge-0/0/5 disable
set interfaces ge-0/0/5 unit 0 family ethernet-switching interface-mode access
set interfaces ge-0/0/5 unit 0 family ethernet-switching vlan members internal


而更简单的方法可以用到以下工具:

 

工具 6: rename (重命名某一个变量)

顾名思义,rename 可以把你在 JUNOS 内配置的任何参数变量重命名。在这里我们把接口 ge-0/0/7 重命名为 ge-0/0/5,所有 ge-0/0/7 相关的配置被挪到 ge-0/0/5 层级之下。

admin@Juniper# rename interfaces ge-0/0/7 to ge-0/0/5 
 
[edit]
admin@Juniper# show |compare 
[edit interfaces]
+   ge-0/0/5 {
+       unit 0 {
+           family ethernet-switching {
+               interface-mode access;
+               vlan {
+                   members internal;
+               }
+           }
+       }
+   }
-   ge-0/0/7 {
-       unit 0 {
-           family ethernet-switching {
-               interface-mode access;
-               vlan {
-                   members internal;
-               }
-           }
-       }
-   }
 
[edit]
admin@Juniper#

 

工具 7: replace pattern(替换字符串)

相比 renamereplace pattern 的功能更为强大,他可以替换整个 JUNOS 配置里面的参数。假设 ge-0/0/7 被某一个 routing-instance VRF)调用,在执行 replace pattern ge-0/0/7 with ge-0/0/5 以后,接口配置和 routing-instance 配置都会同时改变。这在大批量修改某一个参数的时候尤其方便。


在此案例中,ge-0/0/7 仅有接口配置,并未被其他协议等调用。所以 show | compare 仅仅替换接口相关参数。

admin@Juniper# replace pattern ge-0/0/7 with ge-0/0/5


替换完成后,使用前面讲到的 show | compare 查看结果,方法如下:

admin@Juniper# show |compare 
[edit interfaces]
+   ge-0/0/5 {
+       unit 0 {
+           family ethernet-switching {
+               interface-mode access;
+               vlan {
+                   members internal;
+               }
+           }
+       }
+   }
-   ge-0/0/7 {
-       unit 0 {
-           family ethernet-switching {
-               interface-mode access;
-               vlan {
-                   members internal;
-               }
-           }
-       }
-   }
 
[edit]


可以看出,运用此工具后,所有的 ge-0/07 都被替换成了 ge-0/0/5。

 

工具 8: copy (复制某一个变量到其他变量)

如果这个时候,服务器部门又发邮件告知你,索性把ge-0/0/5和ge-0/0/7都配置了吧,很简单,我们把ge-0/0/7的配置复制到ge-0/0/5就行了。


下面我们以ge-0/0/7为模板复制配置到ge-0/0/5。

admin@Juniper# copy interfaces ge-0/0/7 to ge-0/0/5 
 
[edit]
admin@Juniper# show |compare 
[edit interfaces]
+   ge-0/0/5 {
+       unit 0 {
+           family ethernet-switching {
+               interface-mode access;
+               vlan {
+                   members internal;
+               }
+           }
+       }
+   }
 
[edit]
admin@Juniper#

完成以上的预配置之后我们需要让其生效。正如我之前提到过,Juniper 的配置是需要 commit 提交以后才能生效的,但是为了避免提交配置以后,出现意外情况导致工程师丢失与路由器的管理连接,JUNOS 引入了自动倒回功能。


工具9: commit confirm xxx comment “xxx”  (提交配置,若没有工程师确认,系统会在xx分钟之内倒回,并附上配置备注)


这是 JUNOS 最让人爱不释手的一个功能。先看例子:使用 commit confirm comment 来提交配置

admin@Juniper# commit confirmed 2 comment "add new interfaces as well as vlan configuration" 
 
commit confirmed will be automatically rolled back in 2 minutes unless confirmed
commit complete
 
# commit confirmed will be rolled back in 2 minutes
[edit]
admin@Juniper#

如上所示,confirm 2 是告知路由器,两分钟之内如果工程师没有确认此配置,那么之前配置的内容将被删除并还原回配置之前的状态。如果在 confirm 之后不加数字,默认是 10 分钟。最低可以设置一分钟。


更贴心的是,你还可以使用 comment 关键字添加备注,这样大大方便了后续核查的时候了解每次操作的大概内容。以上面的配置为例,通过备注可以知道此次配置内容为新增两个接口和一个 vlan。


下面再来演示一下 Juniper 设备在 2 分钟后无人确认配置的情况下,自动倒回的输出:

[edit]
                                                                              
Broadcast Message from root@Juniper                                            
        (no tty) at 17:35 NZST...                                              
                                                                              
Commit was not confirmed; automatic rollback complete.                                                                              
 
[edit]
admin@Juniper#


那么在 commit 之后,一切工作正常,我如何避免配置被自动倒回呢?


我们只需要在倒回时间超时之前再做一个核查配置的 commit check 就行了。如下所示:

# commit confirmed will be rolled back in 2 minute
[edit]

admin@Juniper# commit check

configuration check succeeds
 
[edit]
admin@Juniper#


是不是很贴心?



割接中


因为有前期的预配置,割接就显得很轻松了。我们只需要删除 disable 以及 deactivate 的命令行就完成了。这里会用到如下工具:

 

工具 10: activate(激活忽略的预配置)

通过删除之前的disable 配置,并activate之前的deactivate的配置,就可以激活之前加载的所有预配置。

admin@Juniper# load set terminal 
[Type ^D at a new line to end input]
 
delete interfaces ge-0/0/6 disable
delete interfaces ge-0/0/7 disable
activate interfaces irb unit 5 family inet address192.168.1.1/24
 
load complete
[edit]


用 show | compare 确认激活行为:

admin@Juniper# show |compare 
[edit interfacesge-0/0/6]
-   disable;
[edit interfacesge-0/0/7]
-   disable;
[edit interfaces irbunit 5 family inet]
!        active: address 192.168.1.1/24 { ... }


工具 11: commit at(定点提交配置)

激活配置以后,同样我们也需要向 JUNOS 提交配置,相比之前的 commit confirm,这次我们换一个方法,使用 commitat。如下所示,它会告知路由器,请在晚上 10 点整的时候提交这个配置。(你可以根据自己的时间修改,但是需要比当前时间晚。)

admin@Juniper# commitcomment "cut over the vlan and ge-0/0/5,ge-0/0/6" at 22:00    

configuration checksucceeds

commit at will beexecuted at 2017-09-14 22:00:00 NZST

The configuration hasbeen changed but not committed

Exiting configurationmode

如上所示,系统提示配置会在晚上10点被执行。


需要说明的是,为了给大家展现各个工具的使用方法,特地挑选了一个及其简单的案例。但是带来的副作用就是没有完全体现出预先加载割接配置的优势。但是试想一下如果此次割接需要大量的配置,例如大量的 VRF 配置,大量的 BGP 邻居配置以及接口配置等。通过在割接前加载所有配置并 deactivate 掉,割接时只需要少量命令行来 activate 激活预配置,从而大大简化了割接的步骤和复杂度,进而减小了犯错误的可能性。



割接完成


割接完成以后,最重要的就是核查网络运行情况,确认提交的配置是否按照预期运行,并且没有引入任何其他网络故障。为了达到这样的目的,我们可以采用以下介绍的工具:


工具11: monitor interface(设备接口流量监控)

完成接口配置以后,我们需要核查接口是否有流量。如果用传统的 show interface xxx 看到的都是静态数据,那有没有更好的方法?例如动态地观测数据。


借助 monitor interface,我们就可以轻松实现这个功能,如下实例:

admin@Juniper>monitor interface ge-0/0/5
 
Interface: ge-0/0/5,Enabled, Link is Up
Encapsulation:Ethernet, Speed: 1000mbps
Trafficstatistics:                                             Current delta
<以下为接口实时动态输入输出流量,每秒都在刷新,我只截取了某一秒的输出内容>
  Input bytes:                  17411220 (200 bps)                        [52]
  Output bytes:                 24971481 (947704 bps)                 [438150]
  Input packets:                  324059 (0 pps)                           [1]
  Output packets:                 319355 (789 pps)                      [2921]
Errorstatistics:
  Input errors:                        0                                   [0]
  Input drops:                         0                                   [0]
  Input framing errors:                0                                   [0]
  Policed discards:                    0                                   [0]
  L3 incompletes:                      0                                   [0]
  L2 channel errors:                 232                                   [0]
  L2 mismatch timeouts:                0                                   [0]
  Carrier transitions:                 1                                   [0]
  Output errors:                       0                                   [0]
  Output drops:                        0                                   [0]
  Aged packets:                        0                                   [0]
 
<为了便于阅读,此处省略了其他无关的输出内容>

此命令是每秒钟都在刷新,如果大家有条件可以在设备上尝试一下,博客上无法动态展现给大家。


工具 12: monitor traffic interface (cli 层面的tcpdump 数据抓包)

有些时候配置了路由协议,但是发现其没有正常工作,在开启 debug 模式之前,我们还有一个最简单的办法来排错,那就是抓包。


想到抓包,大家是不是第一印象就是做镜像端口,然后把 PC 接入设备用 Wireshark 抓取。


在 Juniper 设备上,如果你只是想抓取到达路由器本身的流量,例如像上面所述的路由协议排查,我们可以很简单地在命令行模式下抓取到达路由器的数据包。


下面演示一个命令行模式下用 monitor trafficinterface 的抓包:

admin@Juniper>monitor traffic interface ge-1/1/4.100 no-resolve    
verbose outputsuppressed, use <detail> or <extensive> for full protocol decode
Address resolution isOFF.
Listening onge-1/1/4.100, capture size 96 bytes
 
s00:46:38.271636  In IP 1.2.3.4.179 > 1.2.3.5.61855: P662902184:662902203(19) ack 2900796289 win 16384 <nop,nop,timestamp3271803181 643396392>: BGP, length: 19
00:46:38.371433 Out IPtruncated-ip - 2 bytes missing! 1.2.3.5.61855 > 1.2.3.4.179: . ack 19 win16384 <nop,nop,timestamp 643418995[|tcp]>
00:46:38.724938 OutIS-IS, L2 Lan IIH, src-id 0011.0000.0001, lan-id 0011.0000.0001.03, prio 64,length 47
00:46:39.174455 OutES-IS, ISH, length 26
00:46:41.199436 OutIS-IS, L2 Lan IIH, src-id 0011.0000.0001, lan-id 0011.0000.0001.03, prio 64,length 47
00:46:42.161045  In IS-IS, L2 Lan IIH, src-id 0011.0000.0254,lan-id 0011.0000.0001.03, prio 64, length 47
00:46:42.481016 OutIS-IS, L2 CSNP, src-id 0011.0000.0001.00, length 47
00:46:43.797914 OutIS-IS, L2 Lan IIH, src-id 0011.0000.0001, lan-id 0011.0000.0001.03, prio 64,length 47
00:46:43.864907 Out IPtruncated-ip - 21 bytes missing! 1.2.3.5.61855 > 1.2.3.4.179: P 1:20(19) ack19 win 16384 <nop,nop,timestamp 643424488[|tcp]>
00:46:43.964852  In IP 1.2.3.4.179 > 1.2.3.5.61855: . ack20 win 16384 <nop,nop,timestamp 3271808875 643424488>
00:46:46.147386 OutIS-IS, L2 Lan IIH, src-id 0011.0000.0001, lan-id 0011.0000.0001.03, prio 64,length 47
00:46:48.400363 OutIS-IS, L2 Lan IIH, src-id 0011.0000.0001, lan-id 0011.0000.0001.03, prio 64,length 47
00:46:49.340934  In IS-IS, L2 Lan IIH, src-id 0011.0000.0254,lan-id 0011.0000.0001.03, prio 64, length 47
^C
15 packets received byfilter
0 packets dropped bykernel

从上面输出可以看出,两台路由器之间有 BGP 通信流量,同时还有 IS-IS IGP 路由协议流量。


当然,monitor traffic interface 还有更多选项。例如 extensive 可以看到更多的数据包内容,通过 match 可以像 tcpdump 一样,设定源、目标地址,端口等信息来过滤数据包。

 

工具 13: show interface terse | refresh xxx (定期自动刷新)

此工具是用于定时自动刷新某些显示的命令行内容。打个比方,有时候我们难免遇到需要同远端联调设备端口。在完成相应配置后,双方需要确认接口是否 up。一般方法是按向上的方向键调出命令不断手工刷新状态,其实更简单的办法就是使用 refresh。


Refresh 可以用于任何状态显示的自动定期刷新,例如定期接口状态,定期刷新 OSPF,ISIS,BGP 邻居状态等。


如下案例,设定路由器每 秒钟自动刷新一次接口状态。

admin@Juniper> showinterfaces terse ge-0/0/2 | refresh 1 | no-more 
---(refreshed at2017-09-14 22:00:55 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up  
---(refreshed at2017-09-14 22:00:56 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up  
---(refreshed at2017-09-14 22:00:58 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up  
---(refreshed at2017-09-14 22:00:59 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up  
---(refreshed at2017-09-14 22:01:00 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up  
---(refreshed at2017-09-14 22:01:01 NZST)---
Interface               Admin Link Proto    Local                 Remote
ge-0/0/2                up    up
ge-0/0/2.10             up    up  
ge-0/0/2.32767          up   up

### 割接结束 ####


以上就是在使用 Juniper 设备过程中常用的运维技巧和方法,相信有了这么多工具和思路的帮助下,对于大家的日常工作相比原来是否就不那么恐慌了。至少可以对自己的配置胸有成竹,自信的敲下 commit 的回车键了!




附录:以下为额外赠送的福利,拿走不谢。


福利一:apply-group

你是不是在配置 Juniper SRX 的时候希望在每一个 zone 层级下配置 host-inbound-traffic 允许基本的 ping 和 traceroute。


例如有三个 zone:internal,external,dmz。普通的方法就是针对每一个 zone,配置对应的 host-inbound-policy,其实还有更简单的方法,那就是利用 apply-group。


示例:

set groups ALLOW_PING_TRACEsecurity zones security-zone <*> interfaces <*>host-inbound-traffic system-services ping
set groupsALLOW_PING_TRACE security zones security-zone <*> interfaces <*>host-inbound-traffic system-services traceroute


你会发现这里使用了通配符。这就是秘诀所在,通过通配符的方式,你可以匹配任意的 security zone 的任意接口。并在其底下允许 ping 和 traceroute


应用 groups:

set security zonesapply-groups ALLOW_PING_TRACE


查看配置,以 internal zone 为例:

admin@JuniperSRX>show configuration security zones security-zone internal |display set            
set security zones security-zoneinternal interfaces irb.5


貌似没看见配置?别急,让我们使用 inheritance 的查看方式,此命令用于查看从其他地方继承下来的配置,例如上文的 groups 配置。 

lg@JuniperSRX>show configuration security zones security-zone internal |display inheritance 
interfaces {
    irb.5 {
        ##
        ## 'host-inbound-traffic' was inheritedfrom group ALLOW_PING_TRACE
        ##
        host-inbound-traffic {
            system-services {
                ##
                ## 'ping' was inherited fromgroup ALLOW_PING_TRACE
                ##
                ping;
                ##
                ## 'traceroute' was inheritedfrom group ALLOW_PING_TRACE
                ##
                traceroute;
            }
        }
    }
}


福利二:apply-path

大家在配置 Juniper 路由器自身防护的时候,希望只允许设备配置的 BGP 邻居与设备通过 TCP 端口 179 通讯,对于其他未配置的 BGP 邻居丢弃目标为 TCP 端口 179 的数据。


通常方法为,先搜集设备配置的所有 BGP 邻居 IP 地址,在 firewall filter 里面逐个添加。


费时费力不说,最不方便的是它是静态配置,如果后续有新的 BGP 邻居添加的时候,还得同步更新此 firewall filter。


那有什么既省时,又省力的方法呢?让我们来看看神奇的 apply-path


示例:

在这一台 MX 路由器上,有如下的 BGP 邻居配置:

admin@MX480> show configuration | grep bgp | display set | except "firewall|policy" |grep local-add 

set protocols bgp group TO_RR local-address 1.1.0.1

set routing-instances Internet protocols bgp group UpStream_Peering neighbor 2.2.2.1 local-address2.2.2.2

set routing-instances Internet protocols bgp group UpStream_Peering-IPv6 neighbor 2:2:37::2local-address 2:2:37::1

set routing-instances Internet protocols bgp group CUSTOMER_InternetA neighbor 1.1.4.4 local-address1.1.4.5

set routing-instances Internet protocols bgp group CUSTOMER_InternetA-IPv6 neighbor 1:1:4::4local-address 1:1:4::5

set routing-instances VRF_A protocols bgp group customer_A neighbor 10.10.2.100 local-address10.10.2.1

set routing-instances VRF_A protocols bgp group customer_A_v6 neighbor 10:10:2::100 local-address10:10:2::1

set routing-instances VRF_A protocols bgp group customer_B_v6 neighbor 10:10:20::100 local-address10:10:20::1


通过 apply-path 自动挑出邻居 IP


先在 prefix-list 里面定义 apply-path:

set policy-optionsprefix-list bgp-neighbors apply-path "protocols bgp group <*>neighbor <*>"

set policy-optionsprefix-list bgp-neighbors-logical-systems apply-path "logical-systems<*> protocols bgp group <*> neighbor <*>"

set policy-optionsprefix-list bgp-neighbors-routing-instance apply-path "routing-instances<*> protocols bgp group <*> neighbor <*>"

set policy-optionsprefix-list bgp-neighbors-routing-instance-logical-systems apply-path"logical-systems <*> routing-instances <*> protocols bgp group<*> neighbor <*>"


这个命令会挑出符合以上路径的最后一个通配符的数值,在这里就是 neighbor 后面的 IP 地址。一般情况在 Juniper 里面 bgp 会存在于三个地方,全局路由表下,VRF 下,以及逻辑路由器下。所以上面就定义了三个 apply-path,并分别放置在不同的 prefix-list 内部。


让我们来查看一下匹配是否成功,还是通过 inheritance 查看全局路由表的 BGP 邻居匹配情况:

admin@MX480# showpolicy-options prefix-list bgp-neighbors | display inheritance 
##
## apply-path wasexpanded to:
##     1.1.0.1/32; 
##
apply-path"protocols bgp group <*> neighbor <*>";


最后就是引用prefix-list :

set firewall family inet filter router-protect term 1-accept-bgp from source-prefix-list bgp-neighbors

set firewall family inet filter router-protect term 1-accept-bgp from source-prefix-list bgp-neighbors-routing-instance

set firewall family inet filter router-protect term 1-accept-bgp from source-prefix-list bgp-neighbors-logical-systems

set firewall family inet filter router-protect term 1-accept-bgp from source-prefix-list bgp-neighbors-routing-instance-logical-systems

set firewall family inet6 filter router-protect6 term 1-accept-bgp from source-prefix-list bgp-neighbors

set firewall family inet6 filter router-protect6 term 1-accept-bgp from source-prefix-list bgp-neighbors-routing-instance

set firewall family inet6 filter router-protect6 term 1-accept-bgp from source-prefix-list bgp-neighbors-logical-systems

set firewall family inet6 filter router-protect6 term 1-accept-bgp from source-prefix-list bgp-neighbors-routing-instance-logical-systems


并把 firewall filter 应用到 lo0 接口上。(注:在 Juniper 的 JUNOS 内,路由器防护一般方法就是添加 ACL 并绑定在 lo0 接口上)

set interfaces lo0 unit 0 family inet filter input router-protect
set interfaces lo0 unit 0 family inet6 filter input router-protect6


大功告成!码字很辛苦,赞一个吧?