4-1 ACL — 標準・拡張・名前付きとパケットフィルタリングの基礎
標準 / 拡張 / 名前付き ACL の違い、ワイルドカードマスク、暗黙の deny、適用方向を CML 実機の permit / deny 対照とヒットカウンタで整理する。csr1000v 3 台構成で送信元を撃ち分けた検証付き。
1. L3 編からセキュリティ編へ — トラフィックを「選ぶ」仕組み
第 3 章では、IP アドレッシングから RIP / EIGRP / OSPF / BGP のルーティングプロトコル、IPv6、マルチキャストまで、L3 (ネットワーク層) の 経路制御 を扱いました。経路制御の目的は「パケットを正しい宛先まで届けること」であり、ルータは到達可能な経路をできるだけ多く学習するよう設計されています。
第 4 章セキュリティ編では、視点を反転させます。届けられる経路の上で、どの通信を通し、どの通信を止めるか を判断する仕組みを扱います。本節で扱う ACL (Access Control List) はその出発点であり、ルータ / L3 スイッチが備える最も基本的なトラフィック制御の手段です。
本節では ACL の動作原理 (順次評価・暗黙の deny)、ワイルドカードマスク、標準 / 拡張 / 名前付きの 3 種類、適用方向 (inbound / outbound) を整理し、CML 上の csr1000v 3 台構成で permit / deny の差分とヒットカウンタを実機検証します。
2. ACL とは — 順次評価と暗黙の deny
ACL (Access Control List) は、パケットを 条件と動作 (permit / deny) の組 で並べたリストであり、ルータを通過するパケットを 1 つずつこのリストに照合して通過の可否を決める仕組みです。この用途を パケットフィルタリング (Packet Filtering) と呼びます。
ACL の評価には 3 つの絶対的なルールがあります。
第一に、上から順に評価する (順次評価) こと。ACL は複数の行 (Access Control Entry、ACE) からなり、パケットは先頭の行から順番に照合されます。
第二に、最初に一致した行で判定が確定する こと。あるパケットが 3 行目の条件に一致したら、その行の動作 (permit または deny) が適用され、4 行目以降は評価されません。したがって ACL は 並び順がそのまま意味を持ちます。具体的な条件を上に、広い条件を下に置くのが原則となります。
第三に、リストの末尾に「暗黙の deny any (implicit deny)」が必ず存在する こと。どの行にも一致しなかったパケットは、明示的に書かれていなくても最後で破棄されます。「許可したいものだけ permit で書けば、書かなかったものは自動的に落ちる」のが ACL の基本的な発想です。この暗黙の deny は設定上見えませんが、確実に効いています (§6 で実機の挙動を確認します)。
順次評価・最初の一致・暗黙の deny という 3 つの性質から、ACL の設計では「許可する通信を具体的に列挙し、最後はすべて落とす」という構造が自然に導かれます。
3. ワイルドカードマスク — サブネットマスクの逆
ACL で送信元や宛先の IP アドレス範囲を指定するとき、サブネットマスクではなく ワイルドカードマスク (Wildcard Mask) を使います。ワイルドカードマスクは、アドレスのどのビットを照合し、どのビットを無視するかを指定する 32 ビットの値です。
ワイルドカードマスクのビットの意味は、サブネットマスクと逆になります。
- 0 のビット: そのビットは 一致しなければならない (照合対象)
- 1 のビット: そのビットは 任意 (無視する)
サブネットマスクが「1 = ネットワーク部、0 = ホスト部」であるのに対し、ワイルドカードマスクは「0 = 照合、1 = 任意」です。両者は ビット反転の関係 にあり、ワイルドカードマスクは「逆マスク」とも呼ばれます。
主なプレフィックス長とワイルドカードマスクの対応は以下のとおりです。
| プレフィックス | サブネットマスク | ワイルドカードマスク | 意味 |
|---|---|---|---|
| /24 | 255.255.255.0 | 0.0.0.255 | 上位 24 ビット一致、下位 8 ビット任意 |
| /30 | 255.255.255.252 | 0.0.0.3 | 上位 30 ビット一致、下位 2 ビット任意 |
| /16 | 255.255.0.0 | 0.0.255.255 | 上位 16 ビット一致、下位 16 ビット任意 |
| /32 (ホスト) | 255.255.255.255 | 0.0.0.0 | 全 32 ビット一致 (1 台だけ指定) |
たとえば 10.0.10.0 0.0.0.255 は「10.0.10.0/24 に属するすべての送信元」を意味します。ワイルドカードマスクはビット単位の照合であり、下位 8 ビットがすべて任意なので、照合上は 10.0.10.0 から 10.0.10.255 までの 256 通りすべてに一致します (ACL はネットワークアドレス .0 やブロードキャストアドレス .255 を特別扱いして除外することはありません)。実際に通信を行うホストに割り当てられるのはこのうち 10.0.10.1 から 10.0.10.254 の範囲ですが、ACL の照合条件としては .0 と .255 も含めて一致する点に注意します。
特殊な指定として、0.0.0.0 (全ビット一致) は host キーワード で host 10.0.20.1 と書け、255.255.255.255 (全ビット任意) は any キーワード で表現できます。本節のラボでも host 10.0.20.1 (サーバ 1 台を指定) と any (すべて) を使います。
4. 標準 ACL と拡張 ACL — 判定材料の違い
ACL には判定材料の異なる 2 種類があり、番号の範囲で区別されます。
標準 ACL (Standard ACL) は 送信元 IP アドレスのみ で判定します。番号の範囲は 1〜99 と、拡張番号の 1300〜1999 です。判定材料が送信元 IP だけなので、「どの宛先へ」「どのプロトコルで」「どのポートへ」の通信かは区別できません。送信元アドレスだけで一括して許可 / 拒否する用途に向きます。
拡張 ACL (Extended ACL) は 送信元 IP・宛先 IP・プロトコル (IP / TCP / UDP / ICMP など)・ポート番号 を組み合わせて判定します。番号の範囲は 100〜199 と、拡張番号の 2000〜2699 です。「送信元 A から宛先 B への TCP/80 のみ許可、同じ A から B への ICMP は拒否」といった細かい制御ができます。
両者の比較は以下のとおりです。
| 項目 | 標準 ACL | 拡張 ACL |
|---|---|---|
| 判定材料 | 送信元 IP のみ | 送信元 IP + 宛先 IP + プロトコル + ポート |
| 番号範囲 | 1〜99 / 1300〜1999 | 100〜199 / 2000〜2699 |
| 制御の粒度 | 粗い (送信元単位) | 細かい (フロー単位) |
| 推奨適用位置 | 宛先に近い側 | 送信元に近い側 |
適用位置について補足します。標準 ACL は送信元 IP しか見ないため、送信元に近い場所に置くと、本来通したい別の宛先への通信まで巻き込んで落としかねません。そのため 宛先に近い側 に置くのが原則です。一方、拡張 ACL はフロー単位で精密に絞れるため、送信元に近い側 に置いて不要なトラフィックを早い段階で落とすのが原則となります。
5. ラボトポロジ — 送信元を撃ち分けて permit / deny を対照する
本ラボは csr1000v 3 台 (R1 / R2 / R3) で構成します。ACL の効果を「遮断の差分」として見せるため、ACL 投入前は全到達できる素の状態を作っておきます。
- R1 = 送信元 (クライアント) 役: 2 つの送信元サブネットを Loopback で持ちます。Lo10
10.0.10.0/24を 営業 (許可したい送信元)、Lo1110.0.11.0/24を ゲスト (拒否したい送信元) と位置づけ、ping <宛先> source Lo10/source Lo11で送信元を撃ち分けます。 - R2 = ACL 適用点 (中継ルータ): ここに ACL を置きます。R1 側の Gi2 に inbound で適用します。
- R3 = 宛先 (サーバ) 役: 宛先サブネットを 2 つ持ちます。Lo20
10.0.20.0/24を 社内サーバ、Lo2110.0.21.0/24を DMZ と位置づけ、拡張 ACL の宛先絞り込みの対照に使います。
ルーティングは OSPF 単一エリア (area 0) で全 Loopback とリンクを広告します。ACL を入れる前に、R1 から R3 の Loopback への経路が OSPF で学習できていることを確認します。
show ip route ospf
...
10.0.0.0/8 is variably subnetted, 12 subnets, 3 masks
O 10.0.2.1/32 [110/2] via 10.12.0.2, 00:02:41, GigabitEthernet2
O 10.0.3.1/32 [110/3] via 10.12.0.2, 00:02:22, GigabitEthernet2
O 10.0.20.1/32 [110/3] via 10.12.0.2, 00:02:22, GigabitEthernet2
O 10.0.21.1/32 [110/3] via 10.12.0.2, 00:02:22, GigabitEthernet2
O 10.23.0.0/30 [110/2] via 10.12.0.2, 00:02:27, GigabitEthernet2
R1#R3 の社内サーバ 10.0.20.1/32 と DMZ 10.0.21.1/32 が、いずれも O [110/3] via 10.12.0.2 (= R2 経由) で学習できています。ACL を入れていないこの状態で、営業・ゲストの両方から R3 へ ping を撃つと、いずれも全到達します。
ping 10.0.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.20.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.10.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms
R1#ping 10.0.20.1 source Loopback11 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.20.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.11.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/3 ms
R1#営業 (送信元 10.0.10.1) もゲスト (送信元 10.0.11.1) も !!!!! の 100% (5/5) です。これが baseline であり、以降の各フェーズでは、この基準からの「遮断の差分」で ACL の効果を読み取ります。
6. 標準 ACL の実機検証 — 送信元 IP だけで通す / 落とす
標準 ACL を R2 に入れ、営業を通しゲストを落とす設定を確認します。R2 に番号 10 の標準 ACL を作り、営業の 10.0.10.0/24 を permit し、それを R2 Gi2 の inbound に適用します。
access-list 10 permit 10.0.10.0 0.0.0.255
!
interface GigabitEthernet2
ip access-group 10 inaccess-list 10 permit 10.0.10.0 0.0.0.255 で「送信元が 10.0.10.0/24 のパケットを許可」と宣言し、ip access-group 10 in で Gi2 の inbound 方向に適用します。permit 行は 1 行だけで、ゲストの 10.0.11.0/24 は明示的には書きません。書かなくても、§2 の暗黙の deny が末尾で落とします。
この状態で営業・ゲストから R3 へ ping を撃つと、結果が分かれます。
ping 10.0.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.20.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.10.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms
R1#ping 10.0.20.1 source Loopback11 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.20.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.11.1
U.U.U
Success rate is 0 percent (0/5)
R1#営業 (10.0.10.1) は permit にヒットして 100% (5/5) のまま、ゲスト (10.0.11.1) は暗黙の deny にヒットして 0% (0/5) になりました。ゲスト側の出力が ..... (タイムアウト) ではなく U.U.U になっている点が注目箇所です。U は ICMP の到達不能 (unreachable) 応答 であり、R2 が ACL でパケットを落とすとき、送信元へ「administratively prohibited (管理上禁止)」を通知して返したことを示します。U と . が混在しているのは、ICMP unreachable がレート制限 (既定 500ms に 1 回) されるためで、5 回すべてには返りません。
ヒットの内訳は show access-lists で確認します。
show access-lists 10
Standard IP access list 10
10 permit 10.0.10.0, wildcard bits 0.0.0.255 (5 matches)
R2#permit 行に (5 matches) が記録されています。これは営業の ping 5 パケットが permit にヒットした数です。ここで重要なのは、ゲストの 5 パケットを落とした暗黙の deny は、この出力に行として現れない ことです。ゲストは ping が 0% で確実に落ちていますが、暗黙の deny にはヒットカウンタが表示されません。「暗黙の deny は効いているが、ヒット数は show access-lists では見えない」というのが IOS-XE の挙動です (§11 で補足します)。
適用方向は show ip interface で確認できます。
show ip interface GigabitEthernet2 | include access list
Outgoing Common access list is not set
Outgoing access list is not set
Inbound Common access list is not set
Inbound access list is 10
R2#Inbound access list is 10 で、ACL 10 が Gi2 の inbound 方向に適用されていることが確認できます。
標準 ACL のこの結果は、送信元 IP だけで通す / 落とすを切り分けています。逆に言えば、営業から通す限り、その営業が R3 の社内サーバへ向かおうと DMZ へ向かおうと、ICMP だろうと TCP だろうと、すべて同じ扱い になります。宛先やプロトコルで区別したい場合は標準 ACL では表現できず、次の拡張 ACL が必要になります。
7. 拡張 ACL の実機検証 — 同じ送信元・宛先でもプロトコルで分岐させる
拡張 ACL を使い、標準 ACL では不可能だった「同じ送信元・同じ宛先でも、プロトコル単位で許可 / 拒否を分ける」制御を確認します。R2 に番号 100 の拡張 ACL を作ります。
access-list 100 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq 80
access-list 100 deny icmp any host 10.0.20.1
access-list 100 permit ip any any
!
interface GigabitEthernet2
ip access-group 100 in3 行の意味は以下のとおりです。
permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq 80: 営業 (10.0.10.0/24) から社内サーバ (10.0.20.1) への TCP/80 (HTTP) のみ許可。deny icmp any host 10.0.20.1: 送信元を問わず、社内サーバ (10.0.20.1) への ICMP を明示的に拒否。permit ip any any: それ以外のすべてを許可。
この ACL を入れた状態で、営業から社内サーバへ TCP/80 と ICMP (ping) を両方撃ち、結果が L4 で分岐することを確認します。TCP/80 を試すために、宛先の R3 では ip http server で 80 番ポートを待ち受けさせてあります。まず TCP/80 への接続を見ます。
telnet 10.0.20.1 80 /source-interface Loopback10
Trying 10.0.20.1, 80 ... OpenTrying 10.0.20.1, 80 ... Open の Open が、TCP セッションが確立したこと = 1 行目の permit が効いていることを示します。一方、同じ営業から同じ社内サーバへの ping (ICMP) は落ちます。
ping 10.0.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.20.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.10.1
U.U.U
Success rate is 0 percent (0/5)
R1#営業から社内サーバへの ICMP は 2 行目の deny icmp にヒットして 0% (0/5) です。送信元 (10.0.10.0/24) も宛先 (10.0.20.1) も同じなのに、TCP/80 は通り ICMP は落ちる という、標準 ACL では表現できなかった分岐が実現しています。
さらに、営業から DMZ (10.0.21.1) への ping を撃つと、こちらは通ります。
ping 10.0.21.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.21.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.10.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms
R1#DMZ (10.0.21.1) は 2 行目の deny icmp any host 10.0.20.1 の宛先 (10.0.20.1) と一致しないため deny を素通りし、3 行目の permit ip any any で通ります。社内サーバへの ICMP は落ちるが DMZ への ICMP は通る、という 宛先単位 の分岐も確認できます。
ヒットの内訳を show access-lists で確認します。
show access-lists 100
Extended IP access list 100
10 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq www (6 matches)
20 deny icmp any host 10.0.20.1 (5 matches)
30 permit ip any any (17 matches)
R2#3 行それぞれにヒットカウンタが付いています。1 行目 (TCP/80 permit) の (6 matches) は TCP の接続でヒットした数、2 行目 (ICMP deny) の (5 matches) は営業から社内サーバへの ping 5 パケット、3 行目 (permit ip any any) の (17 matches) は DMZ への ping を含むその他の通過パケットです。
ここで設定と表示の差に注意します。設定では eq 80 と書きましたが、show access-lists では eq www と表示されています。IOS-XE は well-known ポート番号を対応するサービス名で表示するため、80 番は www と出ます。設定時は eq 80 でも eq www でも構いません。標準 ACL の (5 matches) (deny は暗黙で見えなかった) と異なり、拡張 ACL では 明示的に書いた deny 行 (2 行目) はヒットカウンタが表示される点も対照的です。
8. 名前付き ACL の実機検証 — シーケンス番号による編集性
ここまでは番号で識別する ACL を扱いました。名前付き ACL (Named ACL) は、番号の代わりに任意の名前で ACL を識別する方式です。名前で意図を表現できる (config が読みやすい) ことに加え、シーケンス番号を使って行を任意の位置に挿入・削除できる編集性 が最大の利点です。
名前付き拡張 ACL NAMED-EXT を作り、§7 と同じ 3 行を入れた直後の状態を見ます。
show ip access-lists NAMED-EXT
Extended IP access list NAMED-EXT
10 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq www
20 deny icmp any host 10.0.20.1
30 permit ip any any
R2#各行の先頭に 10 / 20 / 30 という シーケンス番号 が自動採番されています。既定では 10 刻みで採番され、行と行の間に挿入する余地が確保されます。
ここで、10 と 20 の間に「ゲスト (10.0.11.1) から社内サーバへの TCP/80 を拒否する」行を、シーケンス番号 15 を指定して挿入します。ip access-list extended NAMED-EXT のモードで 15 deny tcp host 10.0.11.1 host 10.0.20.1 eq www と入力するだけで、ACL 全体を作り直すことなく 1 行が挿入されます。
show ip access-lists NAMED-EXT
Extended IP access list NAMED-EXT
10 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq www
15 deny tcp host 10.0.11.1 host 10.0.20.1 eq www
20 deny icmp any host 10.0.20.1
30 permit ip any any (12 matches)
R2#挿入後の順序が 10 / 15 / 20 / 30 になり、追加した 15 deny tcp host 10.0.11.1 ... が 10 と 20 の間に正しく配置されています。ACL は順次評価のため、この挿入位置 (1 行目の permit より後、2 行目の deny icmp より前) が意味を持ちます。
この「任意位置への 1 行挿入」が名前付き ACL の核心的な利点です。なお、IOS-XE では番号付き ACL でも同様にシーケンス番号による編集が可能ですが、名前付き ACL は名前で意図を表せるぶん config 管理上わかりやすく、運用では名前付きが好まれます。
9. 適用方向 inbound / outbound — 評価される位置の違い
ACL は インターフェースに適用するとき、inbound (in) か outbound (out) の方向を指定します。この方向は、ACL が評価されるタイミングを決めます。
- inbound (in): パケットがそのインターフェースに 入った直後、ルーティング判断の 前 に評価されます。deny されたパケットはルーティングテーブルの参照すら行われずに破棄されます。
- outbound (out): パケットがルーティング判断を終え、そのインターフェースから 出る直前 に評価されます。
同じ ACL でも、適用するインターフェースと方向が変われば、評価対象のトラフィックが変わります。本ラボでは R2 Gi2 (R1 側) の inbound に適用しているため、R1 から R2 へ入ってくる方向のトラフィックが、R2 がルーティングする前に評価されます。仮に同じ ACL を R2 Gi3 (R3 側) の outbound に付け替えると、R2 から R3 へ出ていくトラフィックが評価対象になり、効く対象が変わります。
ACL を設計するときは「どのインターフェースの、どの方向で、何を評価したいのか」を最初に決めることが要点です。inbound はルーティング前に落とせるためルータの負荷を早く減らせる利点があり、outbound は複数の入口から来たトラフィックを 1 つの出口でまとめて制御できる利点があります。
10. ACL ログの実機検証 — どのパケットが落ちたかを記録する
ACL の行に log キーワード を付けると、その行にヒットしたパケットの情報をログに記録できます。運用で「どの送信元からどの宛先への通信が、いつ落ちたか」を可視化する手段です。
R2 で、ゲスト (10.0.11.0/24) を log 付きで deny する ACL を入れます。access-list 10 deny 10.0.11.0 0.0.0.255 log と access-list 10 permit any を Gi2 の inbound に適用し、ゲストから ping を撃った後にログを確認します。
show logging | include IPACCESSLOG
*Jun 14 12:54:16.755: %FMANFP-6-IPACCESSLOGDP: R0/0: fman_fp_image: list 10 denied icmp 10.0.11.1 -> 10.0.20.1 (2048/0), 1 packet
R2#list 10 denied icmp 10.0.11.1 -> 10.0.20.1 で、ACL 10 がゲスト (10.0.11.1) から社内サーバ (10.0.20.1) への ICMP を deny したことが記録されています。
注目すべきは、ログのファシリティ名が %FMANFP-6-IPACCESSLOGDP である点です。従来の IOS (IOS Classic) では ACL ログは %SEC-6-IPACCESSLOGP というファシリティで出力されますが、本ラボの csr1000v (IOS-XE) では %FMANFP-6-IPACCESSLOGDP (Forwarding Manager FP) で出力されました。これは IOS-XE のデータプレーンが CPP (QFP) という専用フォワーディングエンジンで動作する構造を反映した違いです。なお IOS-XE はプラットフォームや機能により転送面の実装が異なるため、ファシリティ名がこの csr1000v 環境と完全に一致するとは限りません (§11 で補足します)。
log 付き deny 行のヒットカウンタも show access-lists で確認できます。
show access-lists 10
Standard IP access list 10
10 deny 10.0.11.0, wildcard bits 0.0.0.255 log (10 matches)
20 permit any (14 matches)
R2#10 deny ... log (10 matches) のとおり、log 付きで明示的に書いた deny 行 はヒットカウンタが表示されます。§6 の暗黙の deny がヒットカウンタを表示しなかったのと対照的で、「明示 deny は見える、暗黙 deny は見えない」という違いがここでも確認できます。
11. 落とし穴・補足
実機検証で露呈した、教科書の記述と実機挙動のギャップや運用上の注意点を記録します。
暗黙の deny はヒットカウンタが見えない — 末尾の暗黙の deny any は確実に効いていますが、
show access-listsには行として現れず、何パケット落としたかも表示されません (§6)。「ACL を入れたのに通信が落ちる、しかしshow access-listsのどの行も matches が増えていない」という状況は、暗黙の deny にヒットしている可能性が高いと判断します。落ちたパケット数を数えたいなら、末尾に明示的なdeny ip any any logを 1 行足して可視化するのが運用の定石です。IOS-XE の ACL ログ文言は IOS Classic と異なる — 本ラボの csr1000v (IOS-XE) では
%FMANFP-6-IPACCESSLOGDP、IOS Classic では%SEC-6-IPACCESSLOGPでログが出ました (§10)。文言で grep / フィルタする監視を組むときは、対象機器の OS によってマッチさせる文字列が変わる点に注意します。データプレーンが CPP (QFP) で動く IOS-XE では、ACL ログも Forwarding Manager FP が上げるためファシリティ名が変わります。ただし IOS-XE はプラットフォームにより転送面の実装が異なるため、ファシリティ名がこの環境と完全に一致するとは限りません。ACL ログは既定では即時に出ないことがある — log キーワード付きの行も、
logging bufferedが設定されていないと console にしか出ず、show loggingには現れません。さらに ACL ログには集約機構があり、しきい値に達するまでログ更新をまとめる挙動があります。このしきい値はグローバル設定コマンドip access-list log-update threshold <マッチ数>で調整でき、小さい値にするほど早くログが上がります。本ラボではlogging bufferedを設定したうえで、ゲストから複数回 ping を撃って初回ヒットのログをshow loggingに出しました。運用で ACL ログを監視に流すときは、まずlogging buffered(または syslog 送信) が設定されているかを確認します。ping の往復で片方向遮断が両方向失敗に見える — ping は echo request (往路) と echo reply (復路) の往復で成立します。ACL が片方向だけを塞いだ場合でも、往路が通って復路が落ちれば、結果として ping は失敗します。「ping が失敗した」という事実だけでは、どちらの方向が遮断されたのかは判別できません。本ラボの ICMP deny は社内サーバ宛 (往路) を落としていますが、復路だけを落とす ACL でも ping の見た目は同じ失敗になります。遮断の方向を切り分けるには、ACL のヒットカウンタや log で「どの行が、どの向きのパケットを落としたか」を確認します。
eq 80はeq wwwと表示される — 設定でeq 80と書いても、show access-listsでは well-known ポート名のeq wwwで表示されます (§7)。番号で書いた設定が名前で表示されることに戸惑わないよう、両者が同じものを指していると押さえておきます。ACL は制御プレーンの通信にも効く — ACL を inbound に適用すると、データ通信だけでなく、そのインターフェースで動く OSPF Hello などのルーティングプロトコルの通信も評価対象になります。本ラボの標準 ACL (§6) は営業の
10.0.10.0/24だけを permit したため、R1-R2 リンク上の OSPF 通信も暗黙の deny に該当し得ます。短時間の検証では ping の差分を観測できますが、ACL を本番のインターフェースに当てるときは、必要な制御プレーン通信 (OSPF / BGP / その他) を明示的に permit するか、適用方向と対象を吟味して隣接関係を落とさないよう注意します。
次節
本節では、ACL によるパケットフィルタリングの基礎として、順次評価・暗黙の deny・ワイルドカードマスクと、標準 / 拡張 / 名前付きの 3 種類、適用方向 (inbound / outbound) を実機で確認しました。ACL は「送信元・宛先・プロトコル・ポート」というパケットの属性で通信を選別する仕組みであり、第 4 章セキュリティ編で扱う各種の制御の土台となります。
次節 4-2 AAA では、視点をパケットから 利用者 へ移します。ACL が「どの通信を通すか」を制御するのに対し、AAA (Authentication / Authorization / Accounting) は「誰がログインでき、何を実行でき、何をしたかを記録するか」を制御する仕組みです。ネットワーク機器そのものへのアクセス制御を実機で見ていきましょう。
そこが ACL の一番大事な性質だ。絶対に外せないルールが 3 つある。
- 上から順に評価する(順次評価)
- 最初に一致した行で判定が確定する(それ以降の行は見ない)
- リストの末尾に「暗黙の deny」が必ず居る(どこにも一致しなければ最後で落とされる)
この 3 つから、ACL の設計は自然に「通したいものを具体的に列挙して、書かなかったものは全部落ちる」という形になる。
それが ACL 独特のところで、ワイルドカードマスクを使う。サブネットマスクと似てるけど、ビットの意味が逆なんだ。
- 0 のビット → そこは一致しなければならない(照合する)
- 1 のビット → そこは任意(無視する)
サブネットマスクは「1 = ネットワーク部」だっただろ。ワイルドカードは「0 = 照合」。ちょうどビット反転の関係で、「逆マスク」とも呼ばれる。
表で並べると掴みやすい。
| プレフィックス | サブネットマスク | ワイルドカードマスク |
|---|---|---|
| /24 | 255.255.255.0 | 0.0.0.255 |
| /30 | 255.255.255.252 | 0.0.0.3 |
| /16 | 255.255.0.0 | 0.0.255.255 |
| /32(1 台だけ) | 255.255.255.255 | 0.0.0.0 |
10.0.10.0 0.0.0.255 なら「上位 24 ビットは一致、下位 8 ビットは任意」= 10.0.10.0/24 の全部だ。ちなみに ACL はビット単位の照合だから、.0(ネットワークアドレス)や .255(ブロードキャスト)も特別扱いせず一致に含める。ホストとして使えるのは .1〜.254 でも、照合条件としては 256 通り全部にマッチする、と押さえておけばいい。
0.0.0.0(全ビット一致 = 1 台だけ)は host キーワードで host 10.0.20.1 と書ける。255.255.255.255(全ビット任意 = 誰でも)は any キーワードだ。この 2 つは ACL で頻出だから覚えておくといい。いい質問だ。判定材料の違いで 2 種類あって、番号の範囲で区別する。
| 項目 | 標準 ACL | 拡張 ACL |
|---|---|---|
| 判定材料 | 送信元 IP のみ | 送信元 IP + 宛先 IP + プロトコル + ポート |
| 番号範囲 | 1〜99 / 1300〜1999 | 100〜199 / 2000〜2699 |
| 粒度 | 粗い(送信元単位) | 細かい(フロー単位) |
| 置く場所 | 宛先に近い側 | 送信元に近い側 |
10.0.10.0/24 を「営業(通したい)」、Lo11 の 10.0.11.0/24 を「ゲスト(落としたい)」にする。R3 は宛先を 2 つ ── Lo20 が社内サーバ、Lo21 が DMZ だ。ACL を入れる前は OSPF で全部到達する素の状態を作っておく。ping <宛先> source Lo10 みたいに、ping の送信元インターフェースを指定するんだ。営業のフリ(source Lo10)とゲストのフリ(source Lo11)を切り替えて撃てば、ACL がどっちを通してどっちを落とすか、差分で見える。まず ACL を入れる前は両方 100% 通る。これが baseline だよ。そう。R2 に番号 10 の標準 ACL を作って、営業だけ permit する。
access-list 10 permit 10.0.10.0 0.0.0.255
!
interface GigabitEthernet2
ip access-group 10 inpermit は 1 行だけ。ゲストの 10.0.11.0/24 はわざと書かない。書かなくても、さっき話した暗黙の deny が末尾で落とす。これで撃ち分けると ──
..... じゃなくて U.U.U になってるりん。この U って何りん?U は ICMP の到達不能(unreachable)応答だ。R2 が ACL でパケットを落とすとき、黙って捨てるんじゃなく送信元に「administratively prohibited(管理上禁止した)」と教えて返している。U と . が混じるのは、この unreachable 通知にレート制限(既定 500ms に 1 回)があって、5 回全部には返らないからだよ。show access-lists 10 だ。
Standard IP access list 10
10 permit 10.0.10.0, wildcard bits 0.0.0.255 (5 matches)permit 行に (5 matches) ── 営業の 5 パケットがヒットした数だ。ここで大事な落とし穴がある。ゲストの 5 パケットを落とした暗黙の deny は、この出力に行として出てこない。ゲストは確実に 0% で落ちているのに、暗黙 deny のヒット数はどこにも表示されないんだ。
access-list 10 deny any log(拡張 ACL なら deny ip any any log)だ。暗黙のままだと数えられないからな。この「明示 deny は見える、暗黙 deny は見えない」の対比は、このあと何度も出てくる。「同じ送信元・同じ宛先でも、プロトコルで許可/拒否を分ける」ができる。R2 に番号 100 で 3 行入れてみよう。
access-list 100 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq 80
access-list 100 deny icmp any host 10.0.20.1
access-list 100 permit ip any any- 1 行目 = 営業から社内サーバ(10.0.20.1)への TCP/80(HTTP) だけ許可
- 2 行目 = 送信元を問わず社内サーバへの ICMP を明示 deny
- 3 行目 = それ以外は全部許可
permit ip any any が居るりん。これで「暗黙の deny」の代わりに全部通す番人を自分で置いた感じりん?Trying 10.0.20.1, 80 ... Open で接続成立。同じ営業から同じ社内サーバへの ping は U.U.U の 0% で落ちる。送信元も宛先も同じなのに、TCP は通り ICMP は落ちる ── これが標準 ACL では絶対にできなかった分岐だ。host 10.0.20.1(社内サーバ)限定だろ。DMZ の 10.0.21.1 は一致しないから deny を素通りして、3 行目の permit ip any any で通る。「社内サーバへの ICMP は落ちるが DMZ への ICMP は通る」── 宛先単位の分岐も効いてる。Extended IP access list 100
10 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq www (6 matches)
20 deny icmp any host 10.0.20.1 (5 matches)
30 permit ip any any (17 matches)3 行それぞれにカウンタが付く。ここで標準 ACL と違うのは、明示的に書いた deny 行(2 行目)はヒット数が見えること。暗黙 deny は見えなかったけど、書いた deny は見える。対照的だろ。
eq 80 って書いたのに eq www になってるりん。勝手に変わったりん?www。設定時は eq 80 でも eq www でも同じものを指す。番号で書いたのに名前で出てきて戸惑わないように、と押さえておけばいい。細かいけど、実機で必ず「あれ?」となるポイントだよ。10 / 20 / 30 と 10 刻みで自動採番される。この隙間が挿入の余地なんだ。たとえば「ゲストから社内サーバへの TCP/80 を落とす」行を 15 番で入れたい時、ACL 編集モードで 15 deny tcp host 10.0.11.1 host 10.0.20.1 eq www と打つだけ。ACL 全体を作り直さずに 1 行が挿入される。
Extended IP access list NAMED-EXT
10 permit tcp 10.0.10.0 0.0.0.255 host 10.0.20.1 eq www
15 deny tcp host 10.0.11.1 host 10.0.20.1 eq www
20 deny icmp any host 10.0.20.1
30 permit ip any any順序が 10 / 15 / 20 / 30 になって、追加行が正しく間に入った。ACL は順次評価だから、この挿入位置(permit の後・deny icmp の前)がちゃんと意味を持つ。
ACL をインターフェースに付けるときの方向だ。同じ ACL でも方向で「いつ評価するか」が変わる。
- inbound(in) = パケットが IF に入った直後、ルーティング判断の前に評価。deny なら経路表を引く前に捨てる。
- outbound(out) = ルーティングを終えて IF から出る直前に評価。
このラボは R2 Gi2(R1 側)の inbound だから、R1 から入ってくる通信を R2 がルーティングする前に評価してる。
ある。ACL の行に log キーワードを付けると、その行にヒットしたパケットの情報がログに残る。「どの送信元からどの宛先への通信が、いつ落ちたか」が可視化できる。ゲストを log 付き deny してから ping を撃つと ──
%FMANFP-6-IPACCESSLOGDP: ... list 10 denied icmp 10.0.11.1 -> 10.0.20.1 (2048/0), 1 packetlist 10 denied icmp 10.0.11.1 -> 10.0.20.1 で、ゲストから社内サーバへの ICMP を落としたことが記録される。
%FMANFP-6-IPACCESSLOGDP……なんか呪文みたいで長いりん。これ普通のログりん?%SEC-6-IPACCESSLOGP で出る。でもこのラボの csr1000v(IOS-XE)は %FMANFP-6-IPACCESSLOGDP。IOS-XE はデータプレーンが CPP(QFP) っていう専用フォワーディングエンジンで動く構造だから、ACL ログも Forwarding Manager FP が上げてファシリティ名が変わるんだ。logging buffered が無いとローカルのログバッファに残らないから show logging では見えない(console や terminal monitor、remote syslog、SNMP には別途その出力先を有効にすれば送られ得る)。logging buffered は数ある宛先の 1 つで、「これが無い=console だけ」というわけじゃない。それと ACL ログには集約機構があって、しきい値に達するまでまとめる挙動がある。しきい値は ip access-list log-update threshold <マッチ数> で調整できて、小さくするほど早く上がる。監視に流すなら、まず show logging で見たいなら logging buffered、外に飛ばすなら syslog 送信が入ってるかを確認だ。見える。
Standard IP access list 10
10 deny 10.0.11.0, wildcard bits 0.0.0.255 log (10 matches)
20 permit any (14 matches)10 deny ... log (10 matches) のとおりだ。ここでも「明示的に書いた deny は見える、暗黙 deny は見えない」が繰り返される。この対比だけは体に入れておくといい。