CCNA學習筆記(五) 安全(訪問控制列表)
訪問控制列表(ACL)例項詳解
引言
這篇文章介紹訪問控制列表的作用;分別介紹標準、擴充套件、命名訪問控制列表的配置和需要注意的問題。文章後半部分會例項演示一些高階訪問控制列表的配置,包括動態、反射、和基於時間的訪問控制列表(本文中所有配置都可以在GNS3中完成,使用的路由ios為c3640)。
文章目錄
0×1.ACL概述
ACL(Access Control List,訪問控制列表),是一系列運用到路由器介面的指令列表,路由根據ACL中指定的條件對經過路由器介面的資料包進行檢查。本篇文章僅討論IP的訪問控制列表,針對IP協議在路由的每個埠可以建立兩個ACL:一個用於過濾進入埠的資料,另外一個用於過濾流出埠的資料。
ACL指令的放置順序是很重要的,Cisco的IOS軟體,按照ACL中指令的順序依次檢查資料包是否滿足某一個指令條件,當檢測到某個指令滿足條件時就執行該指令規定的動作,並且不會再檢測後面的指令條件。
a.ACL的作用
ACL的作用大致分為下面這幾點:
限制網路流量,提高網路效能。
提供資料流控制。
為網路訪問提供基本的安全層。
決定轉發或阻止哪些型別的資料流。
b.ACL的工作流程
下圖為ACL的工作流程圖,當路由器的進入方向的介面收到一個分組的時候,首先檢查它是否是可路由的,如果不可路由(比如並非是發往本路由的分組),則直接丟棄。
如果可路由,接下來判斷進入方向的介面是否配置了ACL,如果沒有配置進入方向的ACL,則直接查詢路由表,然後根據路由表中找到的埠準備往外轉發;如果配置了進入方向的ACL則檢查指令組是否允許該分組通過,不允許則丟棄,允許則查詢路由表,選擇外出介面準備往外轉發,從這裡可以看出入站的ACL檢查是在查詢路由表之前執行的。
外出介面選擇好之後,再檢查外出介面上有沒有配置ACL,如果配置了ACL則檢查ACL指令組是否允許,沒有配置ACL則直接轉發。
在ACL流程圖中的"ACL指令組"可能包含多條語句,"ACL指令組"的工作流程圖如下:
"ACL指令組"是逐條執行的,在逐條執行的過程中,只要發現有一條匹配,則使用那一條規定動作確定允許或拒絕(比如執行第一條的時候就匹配了,那麼就使用第一條規定的動作允許或拒絕,後面的語句就不會被執行了),如果所有指令都不匹配,預設的動作是拒絕。
c.萬用字元掩碼在ACL中的作用
路由器使用萬用字元掩碼(Wildcard Masking)與源或目標地址一起來分辨匹配的地址範圍,在訪問控制列表中,將萬用字元掩碼中的位設定成1表示忽略IP地址中對應的位,設定成0表示必須精確匹配IP地址中對應的位,下面舉幾個淺顯易懂的例子:
192.168.1.0 0.0.0.255
這個例子中,萬用字元掩碼是0.0.0.255,前面24位是0,最後8位是1,也就是前面24位必須精確匹配,最後8位是什麼都沒關係。將這個萬用字元和前面的IP地址192.168.1.0結合起來意思就是,匹配從192.168.1.0到192.168.1.255的所有IP地址(這和OSPF或EIGRP中的反掩碼是一個道理)。
192.168.0.0 0.0.255.255
匹配的IP地址範圍是192.168.0.0-192.168.255.255。
192.168.16.0 0.0.7.255
這個例子中,萬用字元掩碼的第三個數是7,IP地址的第三位是16,對他們進行分解轉化成二進位制;
7 = 00000 111
16 = 00010 000
前面說過,萬用字元掩碼中0的部分必須精確匹配,1的部分什麼都可以,也就是說16的二進位制表示法前面的5位(00010)必須精確匹配,最後3位的取值範圍可以是(000-111),那麼就是;
00010 000-00010 111,轉化成十進位制就是16-23。
所以這條規則匹配的IP地址範圍是"192.168.16.0-192.168.23.255"。
192.168.1.0 0.0.0.254
匹配192.168.1.0中所有偶數IP地址。
192.168.1.1 0.0.0.254
匹配192.168.1.0中所有奇數IP地址。
上面這些例子說明了怎麼通過規則中的萬用字元掩碼確定匹配的IP地址範圍,如果一個數據包中包含了源IP地址"192.168.0.2"到達路由器,假設路由器上的訪問控制列表語句中包含"192.168.0.0 0.0.0.255",路由器按照下面的步驟匹配這個IP地址:
1)使用訪問控制列表中的地址對"192.168.0.0 0.0.0.255"執行邏輯或操作(192.168.0.0和0.0.0.255執行邏輯或運算),得到結果192.168.0.255。
2)用地址對中的萬用字元掩碼(0.0.0.255)和資料包頭中的IP(192.168.0.2)執行邏輯或操作,結果為192.168.0.255。
3)將得到的兩個結果相減,如果結果是0則匹配,如果結果非0,則說明不匹配。對接下來的ACL條目都重複以上三步相同的操作。
在IP訪問控制列表地址掩碼對中,有兩個關鍵詞可以用來省略一些輸出:
"any":它可以用來代替地址掩碼對"0.0.0.0 255.255.255.255",該地址掩碼對匹配任何IP地址。
"host":它可以用來代替萬用字元掩碼"0.0.0.0",該萬用字元掩碼只能匹配一個IP地址。比如"host 192.168.1.1"等同於地址對"192.168.1.1 0.0.0.0"。在標準的訪問控制列表中,如果僅匹配一個IP地址,可以省略關鍵字host,也就是說在標準訪問控制列表條目中,沒有萬用字元掩碼,說明掩碼是"0.0.0.0";而在擴充套件的訪問控制列表中不能省略host關鍵字。
0×2.標準ACL配置
這一部分的實驗全部在GNS3中完成,使用的路由ios為c3640。
a.如何配置標準ACL
首先配置下面的拓撲(圖3),保證全網可以互通:
R1配置:
1 |
R1(config)# int s 0/0 |
2 |
R1(config-if)# ip add 12.1.1.1 255.255.255.0 |
3 |
R1(config-if)# no shut |
4 |
R1(config)# ip route 0.0.0.0 0.0.0.0 12.1.1.2 |
5 |
R1(config)# end |
R2配置:
1 |
R2(config-if)# int s 0/1 |
2 |
R2(config-if)# ip add 23.1.1.2 255.255.255.0 |
3 |
R2(config-if)# no shut |
4 |
R2(config-if)# int s 0/0 |
5 |
R2(config-if)# ip add 12.1.1.2 255.255.255.0 |
6 |
R2(config-if)# no shut |
7 |
R2(config-if)# end |
R3配置:
1 |
R3(config)# int s 0/1 |
2 |
R3(config-if)# ip add 23.1.1.3 255.255.255.0 |
3 |
R3(config-if)# no shut |
4 |
R3(config-if)# exit |
5 |
R3(config)# ip route 0.0.0.0 0.0.0.0 23.1.1.2 |
6 |
R3(config)# end |
完成基本連通性的配置後,下面來建立和應用標準的訪問控制列表。
訪問控制列表是在路由器的全域性配置模式輸入的,增加一條標準的訪問控制列表語法格式如下:
01 |
Router(config)# access-list {ACL的編號} { deny |permint} { source [ source -wildcard]|any}
[log] |
02 |
03 |
/* |
04 |
* 其中大括號裡面的類容表示必選,中括號裡面的類容表示可選, |
05 |
* |
06 |
* {ACL的編號}: |
07 |
* 標準ACL的編號範圍是1-99之間的整數, |
08 |
* 擴充套件ACL的編號是100-199之間的整數。 |
09 |
* |
10 |
* { deny |permint}: |
11 |
* 指定匹配這條規則的資料是允許(permint)還是拒絕( deny ), |
12 |
* |
13 |
* { source [ source -wildcard]|any} : |
14 |
* 指定了一個IP地址範圍,使用地址對的形式,比如, |
15 |
* "192.168.1.0 0.0.0.255" , "host 192.168.1.1" 或者 "any" 。 |
16 |
* 這個引數在前面的 "萬用字元掩碼在ACL中的作用" 中詳細介紹過。 |
17 |
* |
18 |
* [log]:可選引數,表示要不要將匹配的條目顯示在控制檯輸出中, |
19 |
* 或者輸出到特定的伺服器。 |
20 |
*/ |
在R3上建立一條標準ACL,禁止IP(12.1.1.1)的訪問:
R3配置:
01 |
/* |
02 |
* 建立標準的ACL,編號是1,第一個條目是阻止12.1.1.1, |
03 |
* 第二個條目是允許任何IP地址的訪問, |
04 |
* 兩個條目的順序很重要,不能顛倒,如果將允許任何IP地址放在第一條, |
05 |
* 那麼由於每個IP地址都能匹配第一條,所以第二條將永遠不會被執行到。 |
06 |
* 這個ACL的第一條還可以簡寫成 "access-list 1 deny 12.1.1.1" , |
07 |
* 這是標準ACL的簡寫規則,在擴充套件ACL中不能省略關鍵字 host 。 |
08 |
*/ |
09 |
R3(config)# access-list 1 deny
host 12.1.1.1 |
10 |
R3(config)# access-list 1 permit
any |
11 |
12 |
/* |
13 |
* 將編號是1的標準ACL應用到路由器的s0/1介面上, |
14 |
* 方向是in,即進入的方向。 |
15 |
*/ |
16 |
R3(config)# int s 0/1 |
17 |
R3(config-if)# ip access -group 1 in |
18 |
R3(config-if)# end |
19 |
20 |
/*在R1上 ping R3測試*/ |
21 |
R1# ping 23.1.1.3 |
22 |
23 |
U.U.U /* ping 不通了*/ |
這條標準的ACL僅僅是禁止了一個IP地址12.1.1.1,如果R1上面還有其他介面,使用高階ping命令讓其他介面的IP地址作為源,去ping R3的s0/1介面IP,還是可以ping通的。
下面看一下如何編輯這個建立好了的標準ACL。
b.如何編輯標準ACL
完成上面的配置後,可以在R3上使用下面的命令來檢視ACL條目:
1 |
/* |
2 |
* "Standard IP access list 1" ACL型別和編號, |
3 |
* 每一行是一個條目,其中 "10" 是行號, |
4 |
* 後面是執行的操作,(22 matches)表示匹配的次數。 |
5 |
*/ |
6 |
R3# show access -lists |
7 |
Standard IP access list 1 |
8 |
10
deny 12.1.1.1 (22 matches) |
9 |
20
permit any (15 matches) |
可以使用下面的命令來刪除標準ACL中對應的條目:
1 |
/*首先進入標準ACL 1的編輯模式*/ |
2 |
R3(config)# ip access-list standard
1 |
3 |
R3(config-std-nacl)# no 10 /*刪除行號是10的這一行*/ |
4 |
R3(config-std-nacl)# end |
5 |
6 |
/*再次檢視,發現只剩下行號是20的了*/ |
7 |
R3# show access -lists |
8 |
Standard IP access list 1 |
9 |
20
permit any (30 matches) |
注意,這種刪除方法只能適用於Cisco的IOS 12.0之後的版本(包括12.0),有個簡單的判斷方法,如果使用"show access-lists"看不到每個條目前面的行號,就說明當前路由器的IOS版本不支援這種方法,也同樣不支援接下來要介紹到的"標準命名ACL"。
標準ACL配置完成後,如果不需要了可以用下面的方法來刪除ACL:
1 |
/*刪除編號是1的標準ACL*/ |
2 |
R3(config)# no access-list 1 |
3 |
4 |
/*刪除在介面上的呼叫*/ |
5 |
R3(config)# int s 0/1 |
6 |
R3(config-if)# no ip access -group 1 in |
7 |
R3(config-if)# end |
c.標準ACL放置的位置
標準的ACL只能對源地址進行控制,如下圖(圖4)所示,將R1的s0/0介面作為源地址,R3的s0/1作為目的地址,資料一共要經過四個介面。
如果將前面建立的ACL 1配置在R1的s0/0上,方向是Out,結果將不起作用,因為ACL僅對穿越流量起作用,對本路由器起源的流量不起作用。
如果將前面建立的ACL 1配置在R2的s0/0上,方向是In,結果起作用,R1不能訪問R3了,但同時R1也不能訪問R2了,因為標準ACL只針對源地址進行過濾。
如果將前面建立的ACL 1配置在R2的s0/1上,方向是Out,結果正確,R1能正常訪問R2,但是不能訪問R3。
如果將前面建立的ACL 1配置在R3的s0/1上,方向是In,結果同樣正確。
經過上面四步的分析,可以得出這樣的結論,標準訪問控制列表要儘可能的應用在靠近目標端,因為標準ACL只針對源地址進行過濾。
b.如何配置標準命名ACL
可以使用字元來代替數字標識ACL,稱為命名ACL,命名ACL與Cisco IOS 11.2以前的版本不相容,現在一般都是12.0以後的版本。另外,不能為多個ACL使用相同的名字,不能使用相同的名字來命名不同型別的ACL,比如,不能使用相同的名字來命名一個標準ACL和一個擴充套件ACL。
下面使用標準命名ACL來實現拒絕R1訪問R3:
01 |
/* "deny-r1" 就是這條標準ACL的自定義名稱*/ |
02 |
R3(config)# ip access-list standard
deny -r1 |
03 |
R3(config-std-nacl)# deny 12.1.1.1 /*第一條規則,阻止12.1.1.1*/ |
04 |
R3(config-std-nacl)# permit any /*第二條規則允許所有IP*/ |
05 |
R3(config-std-nacl)# exit |
06 |
R3(config)# int s 0/1 /*在R3的s0/1介面上呼叫它*/ |
07 |
R3(config-if)# ip access -group deny -r1 in |
08 |
R3(config-if)# end |
09 |
10 |
/*檢視ACL*/ |
11 |
R3# show access -lists |
12 |
Standard IP access list deny -r1 |
13 |
10
deny 12.1.1.1 |
14 |
20
permit any |
標準命名的ACL也可以使用標準ACL裡面的編輯語句來編輯它:
01 |
/*刪除編號是20的條目*/ |
02 |
R3(config)# ip access-list standard
deny -r1 |
03 |
R3(config-std-nacl)# no 20 |
04 |
R3(config-std-nacl)# end |
05 |
06 |
/*再次檢視,發現只剩下一條ACL條目了*/ |
07 |
R3# show access -lists |
08 |
Standard IP access list deny -r1 |
09 |
10
deny 12.1.1.1 |
10 |
11 |
/*可以使用下面的方法刪除這個標準命名ACL,並在介面上刪除對它的呼叫*/ |
12 |
R3# conf t |
13 |
R3(config)# no ip access-list
standard deny -r1 |
14 |
R3(config)# int s 0/1 |
15 |
R3(config-if)# no ip access -group deny -r1 in |
16 |
R3(config-if)# end |
0×3.擴充套件ACL配置
a.如何配置擴充套件ACL
配置擴充套件ACL也分為兩個步驟——建立ACL和在介面下呼叫;擴充套件ACL的結尾也是隱式的拒絕所有。下面是建立擴充套件ACL的基本格式:
01 |
Router(config)# access-list access-list -number { deny | permit |remark}
protocol source source -wildcard [operator operand] [port port-name or name] destination destination -wildcard
[operator operand] [port port-name or name] [established] |
02 |
03 |
/* |
04 |
* "access-list-number" 是擴充套件ACL編號,範圍從100-199。 |
05 |
* |
06 |
* { deny | permit |remark} 是這條ACL條目執行的操作,拒絕|允許|註釋, |
07 |
* 其中的 "remark" 是添加註釋,相當於程式設計中的註釋語句。 |
08 |
* |
09 |
* "protocol" 代表協議,可以用具體的協議名稱代替,比如TCP、UDP、ICMP、IP等。 |
10 |
* |
11 |
* "source source-wildcard" ,表示源地址以及萬用字元掩碼。 |
12 |
* |
13 |
* "destination destination-wildcard" ,表示目的地址以及萬用字元掩碼。 |
14 |
* |
15 |
* "[port port-name or name]" 表示埠號或名稱,輸入telnet和23的效果是一樣的。 |
16 |
* |
17 |
* "[established]" 在後面的 "擴充套件ACL中的established" 中介紹。 |
18 |
*/ |
下面舉個例子,還是使用上面的圖三作為拓撲圖,配置擴充套件ACL拒絕R1去往R3的Telnet通訊。
在R2上配置擴充套件ACL然後呼叫它:
01 |
/* |
02 |
* 擴充套件ACL號為100,第一條命令拒絕tcp型別的連線, |
03 |
* 源主機是12.1.1.1,沒有配置源埠,預設就匹配所有埠, |
04 |
* 目的主機是23.1.1.3,目的埠是23,即telnet。 |
05 |
*/ |
06 |
R2(config)# access-list 100 deny
tcp host 12.1.1.1
host 23.1.1.3 eq telnet |
07 |
08 |
/*第二條命令允許所有IP通訊,源和目的是任意主機。*/ |
09 |
R2(config)# access-list 100 permit
ip any any |
10 |
11 |
/*在R2的s0/0介面上呼叫它*/ |
12 |
R2(config)# int s 0/0 |
13 |
R2(config-if)# ip access -group 100 in |
14 |
R2(config-if)# end |
在R3上配置VTY:
1 |
/* "www.qingsword.com" 被配置成特權密碼與 vty 登陸密碼*/ |
2 |
R3(config)# enable secret www.qingsword.com |
3 |
R3(config)#line vty 0 4 |
4 |
R3(config-line)# password www.qingsword.com |
5 |
R3(config-line)# login |
6 |
R3(config-line)# end |
測試在R1上telnet R3:
1 |
R1#telnet 23.1.1.3 |
2 |
Trying 23.1.1.3 ... |
3 |
% Destination unreachable; gateway or
host down |
4 |
/*發現無法連線上,說明ACL起作用了*/ |
這裡需要注意,因為這個實驗是在前面的標準ACL實驗的基礎上進行的,請確保靜態路由配置無誤,全網能夠互相通訊。如果之前沒有刪除標準ACL請先刪除它,之後再進行擴充套件ACL的實驗。
那麼為什麼要將擴充套件ACL配置在R2上呢?下面這一部分將介紹擴充套件ACL推薦放置的位置。
b.擴充套件ACL放置的位置
利用上面的圖4來進行說明,R1的12.1.1.1是源地址,R3的23.1.1.3是目的地址:
如果將擴充套件ACL 100放在R1的s0/0介面上,方向是Out,結果將不起作用,前面介紹過,ACL只對穿越流量起作用,對本地起源的流量不起作用。
如果將擴充套件ACL 100放在R2的s0/0介面上,方向是In,結果正確,並無其他影響。
如果將擴充套件ACL 100放在R2的s0/1介面上,方向是Out,結果正確,並無其他影響。
如果將擴充套件ACL 100放在R3的s0/1介面上,方向是In,結果正確,並無其他影響。
經過上面四步的分析,因為擴充套件ACL是可以根據源和目的地址以及埠進行過濾,放在R2和R3的任何介面上都不會影響其他資料流量。但有以下兩點需要注意:
放在R2的s0/1介面,方向是Out,根據前面的"ACL工作流程示意圖"可以知道,路由器會先處理這個資料,並且查詢路由表準備轉發,轉發的時候發現在轉發埠上面呼叫的擴充套件ACL 100中,有一個條目匹配,並且動作是阻止,這個資料在這個時候被丟棄,這就浪費了R2的CPU資源(需要查詢路由表)。
放在R3的s0/1介面,方向是In,不但會因為一個最終會被丟棄的資料浪費R2和R3的CPU資源,還會造成頻寬資源的浪費。
從上面的分析得出結論,擴充套件ACL應該儘可能的放在靠近源端,這樣可以使得一些非法的資料流儘早的被丟棄。所以在上面的例項中,擴充套件ACL 100被放置在R2的s0/0介面上,方向是In,這是最靠近源的埠。
c.如何編輯擴充套件ACL
這一部分的命令適用於擴充套件ACL以及擴充套件命名ACL,下面介紹如何檢視、新增、刪除、更改擴充套件ACL:
在R2的ACL 100中,只是阻止了R1對R3的telnet訪問,R1此時是可以ping通R3的,可以使用下面的命令禁止R1 ping R3的23.1.1.3:
01 |
/*首先檢視R2上面的擴充套件ACL*/ |
02 |
R2# show access -lists |
03 |
Extended IP access list 100 |
04 |
10
deny tcp host 12.1.1.1 host
23.1.1.3 eq telnet (3 matches) |
05 |
20
permit ip
any any |
06 |
07 |
/*在R1上測試Ping*/ |
08 |
R1# ping 23.1.1.3 |
09 |
10 |
!!!!! /*可以 ping 通*/ |
11 |
12 |
/* |
13 |
* 在R2上新增ACL條目到ACL 100,讓R1無法 ping 通R3, |
14 |
* 進入ACL 100編輯模式。 |
15 |
*/ |
16 |
R2(config)# ip access-list extended
100 |
17 |
18 |
/* |
19 |
* 新增一條新的規則,阻止ICMP協議, |
20 |
* 源地址是12.1.1.1,目的地址是23.1.1.3。 |
21 |
*/ |
22 |
R2(config-ext-nacl)# deny icmp host
12.1.1.1 host 23.1.1.3 |
23 |
R2(config-ext-nacl)# end |
24 |
25 |
/* |
26 |
* 檢視ACL 100,發現了一個問題, |
27 |
* 新新增的ACL條目被增加到了ACL的末尾, |
28 |
* 而在此之前有一條 "permit ip any any" , |
29 |
* 這樣,新增加的那個條目永遠也別想執行到, |
30 |
* 這個時候在R1上 ping R3的23.1.1.3任然能夠Ping通。 |
31 |
*/ |
32 |
R2# show access-list |
33 |
Extended IP access list 100 |
34 |
10
deny tcp host 12.1.1.1 host
23.1.1.3 eq telnet (3 matches) |
35 |
20
permit ip
any any (5 matches) |
36 |
30
deny icmp host 12.1.1.1 host
23.1.1.3 |
37 |
38 |
/*先用下面的命令刪除最新新增的ACL條目*/ |
39 |
R2(config)# ip access-list extended
100 |
40 |
R2(config-ext-nacl)# no 30 |
41 |
42 |
/* |
43 |
* 然後用這條命令在中間插入一條ACL條目, |
44 |
* 前面的數字15是條目編號,可以是10-20之間的任何整數, |
45 |
* 這樣這條條目就會被自動插入到ACL100的10到20之間。 |