標準ACLによるルーティング実験

#はじめに
先日、標準ACLを用いたルーティングの実験を行なったので、ここに書き記したいと思います。

#ACLとは？
まず、ACLについての知識を整理したいと思います。
ACLというのは(Access Control List)の略称のことで、トラフィックを識別し、制御するための条件を記述したリストのことです。管理者の定義したACLとルータを通過するパケットを照らし合わせ、ACLに一致した場合、そのパケットは通過することが許され、そうでない場合は拒否されます。アクセス制御にもなるため、ネットワークの基本的なセキュリティの一つとなります。

###ACLの種類
ACLには、標準ACLと拡張ACLの二種類があります。
#####標準ACL
標準ACLは送信元IPアドレスだけを条件として指定することができます。パケットのIPヘッダ内の送信元IPアドレスをチェックし、許可あるいは拒否を決定します。
#####拡張ACL
拡張ACLは送信元IPアドレス、宛先IPアドレスの両方を条件として指定することがすることができます。パケットのIPヘッダおよびTCP/UDPヘッダ内をチェックし、許可あるいは拒否を決定します。



#実験環境
PC4台 (ubuntu2 Windows2)
Cisco 892 1台

#準備　
![スクリーンショット 2021-10-27 17.38.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2199816/bf849609-21e1-9691-d3ea-542e920f2e28.png)

図1(Cisco Packet Tracer)

この図のようにセッティングをしました。しかし、今回の実験に使用したCisco 892 は統合型ルータであるため、実験の際にはこの図の通りにはなっていません。
統合型ルータであるCisco 892 のFastEthernet 0 にPC2(ubuntu)を、FastEthernet 1 にPC4(Windows)を、FastEthernet 8 にPC1(Windows)を、GigabitEthernet 0 にPC3(ubuntu)を繋ぎます。
Vlan 1 として192.168.2.1 255.255.255.0を設定します。PC2、PC4のデフォルトゲートウェイとして同じ値(IPアドレス)を設定します。FastEthernet 8 には192.168.1.1 255.255.255.0
GigabitEthernet 0 には192.168.3.1 255.255.255.0を設定し、同じ操作をそれぞれのPCのデフォルトゲートウェイを設定します。
全てのPCの設定が終了したのち、pingが通ることを確認できれば準備は完了です。

#標準ACL実験
まずはPC2からのパケットを拒否するACLを作成します。    
(config)#`access-list 1 deny host 192.168.2.10`
(config)#`access-list 1 permit any`    
これでアクセスリスト1を作成することができました。アクセスリスト1の内容は192.168.2.10(PC2)からのパケットを拒否し、それ以外のパケット許可するというものです。標準ACLのアクセスリストナンバー(acl-number)は1~99、1300~1999の範囲で指定することができます。ACLには__暗黙のdeny__と呼ばれる機能があり、これを考慮する必要があります。__暗黙のdeny__はアクセスリストの最終行に自動的に記述されます。`access-list 1 permit any`がなければ、__暗黙のdeny__が発動し、全てのパケットが破棄されてしまいます。__暗黙のdeny__を封じるためには少なくとも一つはパケット許可を意味する__permit__が含まれた文(ステートメント)が必要です。

作成したアクセスリスト1をインターフェイスに適用します。    
実験時
(config)#`interface vlan 1`
(config-if)#`ip access-group 1 in`   

これでアクセスリスト1が vlan 1 に適用することができました。`access-group 1 in`の__1__はアクセスリストナンバーを指しています。アクセスリストナンバーに続いて__in__という単語入っていますが、そこには__in__あるいは__out__のどちらかが入ります。PC2のパケットはFa0からそれぞれのPCへと向かうので__in__となります。ルータの入り口に適用させる場合は__in__、出口に適用させたい場合は__out__というように考えれば分かりやすいのかもしれません。

ACLを作成し、インターフェイスに適用したので実際にPC2(192.168.2.10)からpingを飛ばしてみます。
まずはPC1(192.168.1.10)に飛ばします。  

```
$ ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) バイトのデータ
送信元　192.168.2.1 icmp_seq= 1 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 2 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 3 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 4 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 5 パケットがフィルタリングされました。
```
    
と、端末には上記のように表示されました。PC3(192.168.3.10)にもpingを飛ばしてみます。

```    
$ ping 192.168.3.10
PING 192.168.3.10 (192.168.3.10) 56(84) バイトのデータ
送信元　192.168.2.1 icmp_seq= 1 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 2 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 3 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 4 パケットがフィルタリングされました。
送信元　192.168.2.1 icmp_seq= 5 パケットがフィルタリングされました。
```    
と、先ほどと同じような結果となりました。PC2のパケットはPC1、PC3には届かないことが確認できました。ちなみにPC2のパケットはPC4にはpingは通ります。PC2とPC4を繋いでいるそれぞれのポートがVlan 1 に所属している為です。PC1、3がPC1(192.168.2.10)に向けてpingを飛ばしても、もちろん通りませんし、PC1、3に対するPC4からのpingは通ります。    
では、PC2からのパケットを特定のPCにのみ送りたい場合、例えばPC1には送りたいがPC3には送りたくないという場合はどうすれば良いでしょうか。先ほどはPC2から見たときにルータの入り口である部分にACLを適用させました。そうしたことでPC1にもPC3にもpingは通りませんでした。そうです、出口にACLを適用させれば良いという仮説が成り立ちます。    
では早速、仮説を検証していきたいと思います。
まずは現時点でインターフェイスに適用されているACLを解除していきます。    
(config)#`interface vlan 1`
(config-if)#`no ip access-group 1 in`     
これで外せました。本当に解除できたかどうかpingを飛ばして確かめても良いですし、`show ip interface`で確認するのも良いと思います。    
(config)#`interface gi0`
(config-if)#`ip access-group 1 out`   
今回は出口に適用させるので__out__となります。
では、pingをPC1、3に飛ばしてみます。

```    
$ ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) バイトのデータ
64 バイト応答 送信元 192.168.1.10: icmp_seq=1 ttl=127 時間=0.722ミリ秒
64 バイト応答 送信元 192.168.1.10: icmp_seq=2 ttl=127 時間=0.746ミリ秒
64 バイト応答 送信元 192.168.1.10: icmp_seq=3 ttl=127 時間=0.744ミリ秒
64 バイト応答 送信元 192.168.1.10: icmp_seq=4 ttl=127 時間=0.730ミリ秒
64 バイト応答 送信元 192.168.1.10: icmp_seq=5 ttl=127 時間=0.735ミリ秒  
```   

```  
$ ping 192.168.3.10
PING 192.168.3.10 (192.168.3.10) 56(84) バイトのデータ
送信元 192.168.2.1 icmp_seq=1 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=2 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=3 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=4 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=5 パケットがフィルタリングされました。
```    
   
以上の結果となり、PC2からのパケットをPC3には送らず、PC1には送ることに成功しました。
これで仮説が正しいということが検証できました。    
また、PC1には送らず、PC3にパケットを送りたい場合は今と同じような考え方をします。    
(config)#`interface gi0`
(config-if)#`no ip access-group 1 out`
(config-if)#`exit`
(config)#`interface fa8`
(config-if)#`ip access-group 1 out`   
では、再び、PC1、3にpingを飛ばしてみます。

```    
$ ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) バイトのデータ
送信元 192.168.2.1 icmp_seq=1 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=2 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=3 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=4 パケットがフィルタリングされました。
送信元 192.168.2.1 icmp_seq=5 パケットがフィルタリングされました。 
``` 
``` 
$ ping 192.168.3.10
PING 192.168.3.10 (192.168.3.10) 56(84) バイトのデータ
64 バイト応答 送信元 192.168.3.10: icmp_seq=1 ttl=63 時間=0.555ミリ秒
64 バイト応答 送信元 192.168.3.10: icmp_seq=2 ttl=63 時間=0.560ミリ秒
64 バイト応答 送信元 192.168.3.10: icmp_seq=3 ttl=63 時間=0.563ミリ秒
64 バイト応答 送信元 192.168.3.10: icmp_seq=4 ttl=63 時間=0.574ミリ秒
64 バイト応答 送信元 192.168.3.10: icmp_seq=5 ttl=63 時間=0.557ミリ秒
```

これでPC1にパケットを送ることなく、PC3にパケットを送ることができました。    
#おまけ
おまけとして`access-list 1 deny host 192.168.2.10`の__deny__を__permit__に変えたらどうなるのか実験したいと思います。
まずは現在のACLの内容を確認してみます。    
＃`show access-list 1`
   10 deny host 192.168.2.10
   20 permit any   
ACL内のステートメントの先頭についているシーケンス番号は一文ごとにデフォルトで10ずつ増えていきます。

まずは`10 deny host 192.168.2.10`を早速消していきたいと思います。     
(config)#`ip access-list standard 1`
(config-std-nacl)#`no 10`    
`ip access-list standard 1` の__1__はアクセスリスト1を表しています。`no 10`はアクセスリスト1のシーケンス番号__10__を消すという意味になります。 再び`show access-list 1`でアクセスリスト1の中身を見ると__permit any__だけしかないことがわかります。さらにその__permit any__も消します。    
(config)#`ip access-list standard 1`
(config-std-nacl)#`no 20`    
 これでアクセスリスト1の中身は何もありません。
では、アクセスリスト1に新たな文を追加します。
   
(config)#`access-list 1 permit host 192.168.2.10`
このアクセスリス1をVlan 1に適用したいと思います。
適用手順はここでは割愛します。
PC2からPC1、3にpingは通ります。先ほど追加した__permit__文により許可されているためです。
では、PC4はどうでしょうか？　PC4(Windows)からPC1、3に通るか確かめます。  

```  
c:>ping 192.168.1.10
192.168.1.10 に ping を送信しています 32バイトのデータ:
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
```
```    
c:>ping 192.168.3.10
192.168.3.10 に ping を送信しています 32バイトのデータ:
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
192.168.2.1 からの応答: 宛先ネットワークに到達できません。
```    
PC4からのpingは通りませんでした。理由は__暗黙deny__です。
アクセスリスト1にはpermit host 192.168.2.10しか記述されていません。しかし、そこには__暗黙deny__が発動します。『192.168.2.10からのパケットを許可する』これが__暗黙のdeny__により『192.168.2.10以外のパケットを拒否する』という意味合いに変わってしまうのです。    
#最後に
今回は標準ACLについての実験を行いました。
__permit__や__deny__の違いがどのような影響を及ぼすのか自分の目で確かめることができました。