手当たり次第に書くんだ

飽きっぽいのは本能

Ubuntu 26.04 KVM VM の ACL – OVN logical port 単位で通信を制御する

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_Port

virtualportinterfaceid と、OVN 側の logical switch port 名を対応させます。この環境では UUID 形式の interface ID を使い、ACL 名にもその一部を使います。

ACL の基本構造

OVN ACL は、logical switch に紐づく rule です。代表的な要素は directionprioritymatchaction です。

  • direction: from-lport または to-lport
  • priority: 数値が高い rule が優先される
  • match: 対象 packet の条件
  • action: allowallow-relateddropreject
  • log: 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: 内部向け通信を許可し、それ以外を drop
  • outbound-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 の ACL – OVN logical port 単位で通信を制御する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る