Ubuntu 26.04 の KVM / OVN 環境で、VM の通信を ACL で制御する考え方を整理します。ここで扱う ACL は、Linux ユーザー権限や libvirt の操作権限ではなく、OVN の logical switch port に対するネットワーク ACL です。
VM 作成時に libvirt XML の virtualport へ指定した interface_id と、OVN の logical switch port を対応させることで、VM の仮想 NIC 単位で通信制御できます。
書籍
作って理解する仮想化技術 ── ハイパーバイザを実装しながら仕組みを学ぶ
ハイパーバイザ、CPU 仮想化支援、メモリ仮想化、割り込み、仮想デバイスなど、VM の性能設計を低レイヤから理解したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
KVM VM の ACL で何を制御するのか
この ACL は、VM を起動できる人を制御するものではありません。VM の仮想 NIC が、どの宛先へ、どの protocol / port で通信できるかを制御します。
- VM 単位ではなく interface 単位で制御する
- OVN logical switch port の
interface_idを対象にする from-lportで VM から出る通信を制御する- private network、link-local、特定 service、internet などを ruleset として分ける
- 最後に drop rule を置いて、許可していない通信を落とす
対象の logical switch port を確認する
まず、VM の interface ID と OVN logical switch port の対応を確認します。ここが一致していないと、ACL を作っても対象 VM の通信には効きません。
VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
sudo virsh --connect qemu:///system dumpxml "$VM_NAME" | sed -n '/<interface/,/<\/interface>/p'
sudo ovn-nbctl show
sudo ovn-nbctl list Logical_Switch_Portvirtualport の interfaceid と、OVN 側の logical switch port 名を対応させます。この環境では UUID 形式の interface ID を使い、ACL 名にもその一部を使います。
ACL の基本構造
OVN ACL は、logical switch に紐づく rule です。代表的な要素は direction、priority、match、action です。
direction:from-lportまたはto-lportpriority: 数値が高い rule が優先されるmatch: 対象 packet の条件action:allow、allow-related、drop、rejectlog: drop などを確認したい場合に有効化する
VM から private network への ICMP を許可する
疎通確認用として、まず private network 宛ての ICMP を許可する例を示します。inport に VM の interface ID を指定することで、その VM NIC から出る通信に限定します。
LOGICAL_SWITCH="ls3032"
INTERFACE_ID="replace-with-interface-uuid"
ACL_NAME="${INTERFACE_ID//-/}"
ACL_NAME="${ACL_NAME:0:8}__allow-private-icmpv4"
sudo ovn-nbctl --id=@acl create ACL \
name="$ACL_NAME" \
direction=from-lport \
priority=4900 \
'match=inport == "'$INTERFACE_ID'" && (ip4 && icmp4 && ip4.dst == 10.0.0.0/8)' \
action=allow-related \
-- add Logical_Switch "$LOGICAL_SWITCH" acls @acl実際には RFC1918 の複数 prefix や IPv6 の private prefix も含めて ruleset 化します。手作業で増やすより、ルールのまとまりを名前付き ruleset として管理する方が破綻しにくくなります。
内部通信を許可して最後に drop する
内部向け通信だけを許可する場合、DHCP、private IPv4、private IPv6 / link-local を許可し、最後に drop rule を置きます。
LOGICAL_SWITCH="ls3032"
INTERFACE_ID="replace-with-interface-uuid"
PREFIX="${INTERFACE_ID//-/}"
PREFIX="${PREFIX:0:8}__"
sudo ovn-nbctl --id=@dhcp create ACL \
name="${PREFIX}allow-dhcpv4" \
direction=from-lport \
priority=5000 \
'match=inport == "'$INTERFACE_ID'" && (ip4 && udp && udp.src == 68 && udp.dst == 67)' \
action=allow \
-- add Logical_Switch "$LOGICAL_SWITCH" acls @dhcp
sudo ovn-nbctl --id=@drop create ACL \
name="${PREFIX}drop" \
direction=from-lport \
priority=1000 \
'match=inport == "'$INTERFACE_ID'" && (ip4 || ip6)' \
action=drop \
log=true \
severity=info \
-- add Logical_Switch "$LOGICAL_SWITCH" acls @drop実際の運用では、このような rule を個別に手入力し続けると危険です。同じ interface に対する既存 ACL を一度整理し、意図した ruleset から再生成する方が一貫性を保てます。
ruleset として考える
ACL は単発 rule ではなく、ruleset として設計すると扱いやすくなります。たとえば、以下のように目的別に分けます。
outbound-icmp-private: private / link-local 宛て ICMP を許可outbound-internal-any: 内部向け通信を許可し、それ以外を dropoutbound-external-restricted: DNS、NTP、proxy、mail、registry など必要な外向き通信だけ許可- VM の interface ごとに必要な ruleset だけを割り当てる
既存 ACL を入れ替える
同じ interface に対する ACL は、追加し続けるのではなく、interface ID 由来の prefix で既存 ACL を探し、削除してから作り直す方が安全です。古いルールが残ると、意図しない通信が許可されたままになります。
INTERFACE_ID="replace-with-interface-uuid"
PREFIX="${INTERFACE_ID//-/}"
PREFIX="${PREFIX:0:8}__"
sudo ovn-nbctl --format=json --columns=_uuid,name find ACL
# 実運用では、name が "$PREFIX" で始まる ACL を抽出し、
# Logical_Switch から remove して ACL を destroy してから再作成する。この考え方にすると、ACL は手で継ぎ足す設定ではなく、VM interface の状態から再生成できる設定になります。構成管理と相性が良いのはこのためです。
確認する
ACL を適用したら、OVN の状態と VM からの疎通を確認します。通信が落ちる場合は、ACL の priority、match、logical switch、interface ID を分けて確認します。
sudo ovn-nbctl list ACL
sudo ovn-nbctl show
VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
sudo virsh --connect qemu:///system domiflist "$VM_NAME"注意点
- この ACL は OVN を使う構成の話であり、通常の Linux bridge だけの KVM にはそのまま適用しない
- interface ID がずれると ACL は効かない
- drop rule を入れる前に、DHCP、DNS、NTP、管理通信など必要な通信を洗い出す
- ログを有効にする場合は量が増えすぎないようにする
- VM 内の firewall と OVN ACL の責務を混同しない
まとめ
Ubuntu 26.04 の KVM / OVN 環境では、VM の通信制御を logical switch port 単位で扱えます。これは一般的な KVM 入門より一段重い構成ですが、VM を複数ネットワークへ接続し、通信の出口を明示的に管理したい場合には有効です。
次は、KVM の HugePages 設定に進み、VM のメモリ割り当てと性能面の前提を整理します。
関連記事
- Ubuntu 26.04 KVM VM の作成 – テンプレート qcow2 から libvirt domain を定義する
- Ubuntu 26.04 KVM Bridge ネットワークの基本設定 – Linux bridge / OVS / OVN の使い分け
- Ubuntu 26.04 KVM の基本構築 – libvirt / OVS / OVN の土台を作る
- Ubuntu 26.04 KVM HugePages の基本
- Ubuntu 26.04 仮想マシンの性能確認
- VM パフォーマンス Day8 – DPDK による高速 dataplane と NFV の基本
- パブリッククラウド上で NFV 型 NF は成立するのか – アンダーレイ / オーバーレイ / 帯域制約で考える


