🎓 レベル:標準 | 重要度:A(必須) 📎 前提:サブネット化とCIDR・VLSM
要点(BLUF)
- ACLは、パケットを条件で**許可(permit)/拒否(deny)**するルールの並び。上から順に評価し、最初に一致した行で確定します。
- 標準ACLは送信元IPだけ、拡張ACLは送信元/宛先IP・プロトコル・ポートまで判定できます。
- 末尾に見えない暗黙のdeny anyがあり、どこにも一致しないパケットは破棄されます。順序と適用方向が命。
標準と拡張
| 種類 | 判定できる条件 | 番号範囲 | 置き場所の定石 |
|---|---|---|---|
| 標準 | 送信元IPのみ | 1-99, 1300-1999 | 宛先に近い側 |
| 拡張 | 送信元/宛先IP・L4プロトコル・ポート | 100-199, 2000-2699 | 送信元に近い側 |
標準は情報が少ないので宛先近くに置かないと、巻き添えで他経路まで止めかねません。拡張は細かく指定できるので、送信元近くで早めに落とせます。
ワイルドカードマスク
ACLはサブネットマスクではなくワイルドカードマスクを使います。これはサブネットマスクのビット反転で、0=一致を要求・1=任意を意味します。
import ipaddress
# /24 のワイルドカード = サブネットマスクのビット反転
net = ipaddress.ip_network("192.168.10.0/24")
wildcard = int(net.netmask) ^ 0xFFFFFFFF
print("subnet mask :", net.netmask)
print("wildcard :", ipaddress.IPv4Address(wildcard))
# access-list 条件 192.168.10.0 0.0.0.255 への一致判定
# ワイルドカードのビット=1(任意)を両辺で1に揃えてから比較する
def acl_match(ip, base, wild):
ip_i = int(ipaddress.IPv4Address(ip))
base_i = int(ipaddress.IPv4Address(base))
wild_i = int(ipaddress.IPv4Address(wild))
return (ip_i | wild_i) == (base_i | wild_i)
for ip in ["192.168.10.55", "192.168.11.55"]:
print(ip, "-> match:", acl_match(ip, "192.168.10.0", "0.0.0.255"))
実行結果:
subnet mask : 255.255.255.0
wildcard : 0.0.0.255
192.168.10.55 -> match: True
192.168.11.55 -> match: False
ワイルドカード 0.0.0.255 は第4オクテットだけ任意なので、192.168.10.x は一致し、第3オクテットが違う 192.168.11.x は不一致になります。/30 のような細かい条件を作るときは、ワイルドカードを 0.0.0.3 のように調整します。
設定例(Cisco IOS)
! 拡張ACL: 192.168.10.0/24 から Webサーバ10.0.0.5 のHTTPSのみ許可、他は暗黙deny
Router(config)# ip access-list extended WEB_ONLY
Router(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 host 10.0.0.5 eq 443
Router(config-ext-nacl)# deny ip any any log
! インターフェースに方向を指定して適用
Router(config)# interface Gi0/1
Router(config-if)# ip access-group WEB_ONLY in
適用は in(入ってくる)/out(出ていく) の方向を必ず指定します。確認:
Router# show access-lists
なぜ「最初の一致で確定」「末尾は暗黙deny」なのか(設計の直観)
ルールを上から順に評価し最初の一致で止めるのは、明示的に許可したものだけを通し、想定外は落とすというホワイトリスト的安全側設計のためです。だから具体的な許可を上、広い拒否を下に並べます(順序を逆にすると許可が死ぬ)。末尾の暗黙denyは「書き忘れた通信は通さない」という保険で、最低1つはpermitを書かないと全遮断になります。
⚠️ よくある誤解
- 「ACLはサブネットマスクで書く」ではない。ワイルドカードマスク(ビット反転)です。
/24→0.0.0.255。 - 「行の順序は自由」ではない。上から評価され最初の一致で確定。広い拒否を上に置くと、後続の許可が一切効きません。
- 「permitを書かなくても通る」ではない。末尾の暗黙deny anyで全部落ちます。許可が必要。
対応 lab
[[networking-study/labs/07-02_acl_wildcard.py]]— ワイルドカードマスク照合の実装と複数条件の確認
関連
- アドレス基礎:
[[03-02_サブネット化とCIDR]]/L4ポート:[[04-03_ポートとソケット]] - 深掘りはセキュリティ分野へ/L2側の防御:
[[07-03_L2セキュリティ]]