Mímisbrunnr知恵の泉

← コンピュータネットワーク 一覧

🎓 レベル:標準 | 重要度:A(必須) 📎 前提:サブネット化とCIDR・VLSM

要点(BLUF)

標準と拡張

種類判定できる条件番号範囲置き場所の定石
標準送信元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を書かないと全遮断になります。

⚠️ よくある誤解

対応 lab

関連