「QEMU/高度なネットワーキング」の版間の差分
(→ブリッジを手動で作成する: 翻訳) |
|||
| (同じ利用者による、間の1版が非表示) | |||
| 1行目: | 1行目: | ||
[[Category:Emulation]] |
[[Category:Emulation]] |
||
[[Category:Hypervisors]] |
[[Category:Hypervisors]] |
||
| + | [[en:QEMU/Advanced networking]] |
||
== 高度なブリッジネットワーク構成 == |
== 高度なブリッジネットワーク構成 == |
||
| 26行目: | 27行目: | ||
* オプションでブリッジを作成します。詳細は [[netctl でブリッジ接続]] を参照してください。ブリッジに {{ic|br0}} という名前を付けるか、以下のスクリプトをブリッジの名前に変更してください。以下の {{ic|run-qemu}} スクリプトでは、リストにない場合は {{ic|br0}} が設定されます。これは、デフォルトではホストがブリッジを介してネットワークにアクセスしていないと想定されているからです。 |
* オプションでブリッジを作成します。詳細は [[netctl でブリッジ接続]] を参照してください。ブリッジに {{ic|br0}} という名前を付けるか、以下のスクリプトをブリッジの名前に変更してください。以下の {{ic|run-qemu}} スクリプトでは、リストにない場合は {{ic|br0}} が設定されます。これは、デフォルトではホストがブリッジを介してネットワークにアクセスしていないと想定されているからです。 |
||
| + | * QEMU が tap アダプターを有効にする際に使用するスクリプトをパーミッション {{ic|root:kvm}} 750 で作成します: |
||
| − | * Create the script that QEMU uses to bring up the tap adapter with {{ic|root:kvm}} 750 permissions: |
||
| − | |||
{{hc|/etc/qemu-ifup|<nowiki> |
{{hc|/etc/qemu-ifup|<nowiki> |
||
#!/bin/sh |
#!/bin/sh |
||
| 39行目: | 39行目: | ||
</nowiki>}} |
</nowiki>}} |
||
| − | * QEMU |
+ | * QEMU が tap アダプターを無効にする際に使用するスクリプトを {{ic|/etc/qemu-ifdown}} にパーミッション {{ic|root:kvm}} 750 で作成します: |
{{hc|/etc/qemu-ifdown|<nowiki> |
{{hc|/etc/qemu-ifdown|<nowiki> |
||
#!/bin/sh |
#!/bin/sh |
||
| 384行目: | 384行目: | ||
そして最後に、[[netctl でブリッジ接続|netctl でブリッジネットワーク]]を作成することが可能です。 |
そして最後に、[[netctl でブリッジ接続|netctl でブリッジネットワーク]]を作成することが可能です。 |
||
| − | {{TranslationStatus|QEMU/Advanced_networking|2025-07-26| |
+ | {{TranslationStatus|QEMU/Advanced_networking|2025-07-26|841852}} |
2025年7月27日 (日) 11:16時点における最新版
目次
高度なブリッジネットワーク構成
ブリッジを手動で作成する
以下では仮想マシンを eth0 などのホストインターフェイスにブリッジする方法を説明しています。おそらく一番よく使われている設定です。この設定では、物理的なホストマシンと同一の Ethernet セグメントに、直接外部ネットワークに仮想マシンが位置するようになります。
通常の Ethernet アダプタをブリッジアダプタで置き換えて、通常の Ethernet アダプタをブリッジアダプタに bind することにします。
- ブリッジを制御するための
brctlが入っている bridge-utils をインストール。
- IPv4 フォワーディングを有効にする:
# sysctl -w net.ipv4.ip_forward=1
変更を永続的にするために、/etc/sysctl.d/99-sysctl.conf の net.ipv4.ip_forward = 0 を net.ipv4.ip_forward = 1 に変えます。
tunモジュールをロードして起動時にロードするように設定してください。詳しくはカーネルモジュールを参照。
- オプションでブリッジを作成します。詳細は netctl でブリッジ接続 を参照してください。ブリッジに
br0という名前を付けるか、以下のスクリプトをブリッジの名前に変更してください。以下のrun-qemuスクリプトでは、リストにない場合はbr0が設定されます。これは、デフォルトではホストがブリッジを介してネットワークにアクセスしていないと想定されているからです。
- QEMU が tap アダプターを有効にする際に使用するスクリプトをパーミッション
root:kvm750 で作成します:
/etc/qemu-ifup
#!/bin/sh echo "Executing /etc/qemu-ifup" echo "Bringing up $1 for bridged mode..." sudo /usr/bin/ip link set $1 up promisc on echo "Adding $1 to br0..." sudo /usr/bin/brctl addif br0 $1 sleep 2
- QEMU が tap アダプターを無効にする際に使用するスクリプトを
/etc/qemu-ifdownにパーミッションroot:kvm750 で作成します:
/etc/qemu-ifdown
#!/bin/sh echo "Executing /etc/qemu-ifdown" sudo /usr/bin/ip link set $1 down sudo /usr/bin/brctl delif br0 $1 sudo /usr/bin/ip link delete dev $1
visudoを使ってsudoersファイルに以下を追加します:
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl %kvm ALL=NOPASSWD: QEMU
- 以下の
run-qemuスクリプトを使って QEMU を起動します:
run-qemu
#!/bin/bash
: '
e.g. with img created via:
qemu-img create -f qcow2 example.img 90G
run-qemu -cdrom archlinux-x86_64.iso -boot order=d -drive file=example.img,format=qcow2 -m 4G -enable-kvm -cpu host -smp 4
run-qemu -drive file=example.img,format=qcow2 -m 4G -enable-kvm -cpu host -smp 4
'
nicbr0() {
sudo ip link set dev $1 promisc on up &> /dev/null
sudo ip addr flush dev $1 scope host &>/dev/null
sudo ip addr flush dev $1 scope site &>/dev/null
sudo ip addr flush dev $1 scope global &>/dev/null
sudo ip link set dev $1 master br0 &> /dev/null
}
_nicbr0() {
sudo ip link set $1 promisc off down &> /dev/null
sudo ip link set dev $1 nomaster &> /dev/null
}
HASBR0="$( ip link show | grep br0 )"
if [ -z $HASBR0 ] ; then
ROUTER="192.168.1.1"
SUBNET="192.168.1."
NIC=$(ip link show | grep en | grep 'state UP' | head -n 1 | cut -d":" -f 2 | xargs)
IPADDR=$(ip addr show | grep -o "inet $SUBNET\([0-9]*\)" | cut -d ' ' -f2)
sudo ip link add name br0 type bridge &> /dev/null
sudo ip link set dev br0 up
sudo ip addr add $IPADDR/24 brd + dev br0
sudo ip route del default &> /dev/null
sudo ip route add default via $ROUTER dev br0 onlink
nicbr0 $NIC
sudo iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
fi
USERID=$(whoami)
precreationg=$(ip tuntap list | cut -d: -f1 | sort)
sudo ip tuntap add user $USERID mode tap
postcreation=$(ip tuntap list | cut -d: -f1 | sort)
TAP=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))
nicbr0 $TAP
printf -v MACADDR "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
qemu-system-x86_64 -net nic,macaddr=$MACADDR,model=virtio \
-net tap,ifname=$TAP,script=no,downscript=no,vhost=on \
$@
_nicbr0 $TAP
sudo ip link set dev $TAP down &> /dev/null
sudo ip tuntap del $TAP mode tap
if [ -z $HASBR0 ] ; then
_nicbr0 $NIC
sudo ip addr del dev br0 $IPADDR/24 &> /dev/null
sudo ip link set dev br0 down
sudo ip link delete br0 type bridge &> /dev/null
sudo ip route del default &> /dev/null
sudo ip link set dev $NIC up
sudo ip route add default via $ROUTER dev $NIC onlink &> /dev/null
fi
それから仮想マシンを起動するために、以下のようにコマンドを実行して下さい
$ run-qemu -hda myvm.img -m 512
- パフォーマンスとセキュリティ上の理由で ブリッジ上のファイアウォール は無効にすることをお勧めします:
/etc/sysctl.d/10-disable-firewall-on-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
起動時に上記のパラメータを適用するには、ブート時に br-netfilter モジュールをロードする必要があります。そうしないと、sysctl がパラメータを変更しようとしたときに、そのパラメータが存在しないことになります。
/etc/modules-load.d/br_netfilter.conf
br_netfilter
すぐに変更を適用するには sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf を実行してください。
libvirt wiki や Fedora bug 512206 を参照。起動中にファイルが存在しないというエラーが起こるときは、起動時に bridge モジュールをロードするようにしてください。カーネルモジュール#systemd を参照。
または、次のようにルールを追加することで全てのトラフィックをブリッジで通すように iptables を設定することができます:
-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT
iptables による物理デバイスと Tap デバイスのネットワーク共有
ブリッジネットワークは、有線インターフェイス (eth0 など) 間では正常に動作し、セットアップも簡単です。ただし、ホストがワイヤレスデバイスを介してネットワークに接続されている場合、ブリッジはできません。
参考として ネットワークブリッジ#ブリッジ上の無線インターフェイス を参照。
これを克服する1つの方法は、tap デバイスに静的 IP を設定し、linux に自動的にルーティングを処理させ、iptables ルールで tap インターフェイスとネットワークに接続されたデバイス間のトラフィックを転送することです。
参考として インターネット共有 を参照。
tap や tun など、デバイス間でネットワークを共有するために必要なものを見つけることができます。次に、必要なホスト構成のヒントを示します。上記の例で示したように、クライアントは、tap インターフェイスに割り当てられた IP をゲートウェイとして、静的 IP を設定する必要があります。注意点は、DNS サーバーがネットワークに接続されているホストデバイスから別のホストデバイスに変更された場合は、クライアント上の DNS サーバーを手動で編集する必要があることです。
起動毎に IP 転送を行うようにするには、/etc/sysctl.d 内の sysctl 設定ファイルに次の行を追加する必要があります:
net.ipv4.ip_forward = 1 net.ipv6.conf.default.forwarding = 1 net.ipv6.conf.all.forwarding = 1
iptables のルールは以下のようになります:
# Forwarding from/to outside
iptables -A FORWARD -i ${INT} -o ${EXT_0} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_1} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_2} -j ACCEPT
iptables -A FORWARD -i ${EXT_0} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_1} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_2} -o ${INT} -j ACCEPT
# NAT/Masquerade (network address translation)
iptables -t nat -A POSTROUTING -o ${EXT_0} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_1} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_2} -j MASQUERADE
上記は、ネットワークに接続された3つのデバイスが、1つの内部デバイスとトラフィックを共有していると仮定しています。例えば次のようなものです:
INT=tap0 EXT_0=eth0 EXT_1=wlan0 EXT_2=tun0
上記は、tap デバイスとの有線および無線接続の共有を可能にする転送を示しています。
示されている転送ルールはステートレスであり、純粋な転送のためのものです。特定のトラフィックを制限し、ゲストや他の人を保護するためにファイアウォールを設置することを考えることができます。しかし、これらはネットワークパフォーマンスを低下させます。一方、シンプルなブリッジにはそのようなものはありません。
おまけ: 接続が有線または無線のいずれであっても、tun デバイスを使用してリモートサイトに VPN 経由で接続された場合、その接続用にオープンされた tun デバイスが tun0 であり、事前のiptablesルールが適用されていると仮定すると、リモート接続もゲストと共有されます。これにより、ゲストも VPN 接続をオープンする必要がなくなります。繰り返しますが、ゲストネットワークは静的である必要があるため、この方法でホストをリモート接続する場合、おそらくゲスト上の DNS サーバーを編集する必要あります。
VDE2 によるネットワーク
VDE とは?
VDE は Virtual Distributed Ethernet の略です。uml_switch の拡張として始まりました。仮想ネットワークを管理するためのツールボックスです。
基本的にはソケットである仮想スイッチを作成して、物理マシンと仮想マシンを両方ともスイッチに"接続"するという考えになります。以下で説明する設定はとてもシンプルです。ただし、VDE はさらに強力な力を持っており、仮想スイッチ同士を接続したり、別のホストでスイッチを動作させスイッチのトラフィックを監視することなどができます。プロジェクトのドキュメント を読むことを推奨。
この方法の利点はユーザーに sudo 権限を与える必要がないということです。通常ユーザーに modprobe の実行を許可する必要はありません。
基本
VDE サポートは vde2 パッケージでインストールできます。
この設定では、tun/tap を使ってホストに仮想インターフェイスを作成します。tun モジュールをロード (詳しくはカーネルモジュールを参照):
# modprobe tun
仮想スイッチを作成:
# vde_switch -tap tap0 -daemon -mod 660 -group users
上記のコマンドでスイッチと tap0 が作成され、接続され、そして users グループのユーザーがスイッチを使えるようにします。
インターフェイスは接続されてもまだ設定がされていません。設定するには、次のコマンドを実行:
# ip addr add 192.168.100.254/24 dev tap0
そして、通常ユーザーで -net オプションを使って KVM を実行してください:
$ qemu-system-x86_64 -net nic -net vde -hda [...]
物理ネットワークでやるのと同じようにゲストのネットワークを設定してください。
起動スクリプト
VDE を起動するメインスクリプトの例:
/etc/systemd/scripts/qemu-network-env
#!/bin/sh
# QEMU/VDE network environment preparation script
# The IP configuration for the tap device that will be used for
# the virtual machine network:
TAP_DEV=tap0
TAP_IP=192.168.100.254
TAP_MASK=24
TAP_NETWORK=192.168.100.0
# Host interface
NIC=eth0
case "$1" in
start)
echo -n "Starting VDE network for QEMU: "
# If you want tun kernel module to be loaded by script uncomment here
#modprobe tun 2>/dev/null
## Wait for the module to be loaded
#while ! lsmod | grep -q "^tun"; do echo "Waiting for tun device"; sleep 1; done
# Start tap switch
vde_switch -tap "$TAP_DEV" -daemon -mod 660 -group users
# Bring tap interface up
ip address add "$TAP_IP"/"$TAP_MASK" dev "$TAP_DEV"
ip link set "$TAP_DEV" up
# Start IP Forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE
;;
stop)
echo -n "Stopping VDE network for QEMU: "
# Delete the NAT rules
iptables -t nat -D POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE
# Bring tap interface down
ip link set "$TAP_DEV" down
# Kill VDE switch
pgrep vde_switch | xargs kill -TERM
;;
restart|reload)
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
exit 0
上のスクリプトを使う systemd サービスの例:
/etc/systemd/system/qemu-network-env.service
[Unit] Description=Manage VDE Switch [Service] Type=oneshot ExecStart=/etc/systemd/scripts/qemu-network-env start ExecStop=/etc/systemd/scripts/qemu-network-env stop RemainAfterExit=yes [Install] WantedBy=multi-user.target
qemu-network-env に 実行可能属性 を付与するようにパーミッションを変更。
通常通り qemu-network-env.service を 開始 できます。
他の方法
上の方法が動作しない場合やカーネル設定, TUN, dnsmasq, iptables を変えたくない場合は以下のコマンドで同じ結果になります。
# vde_switch -daemon -mod 660 -group users # slirpvde --dhcp --daemon
ホストのネットワークの接続を使って仮想マシンを起動するには:
$ qemu-system-x86_64 -net nic,macaddr=52:54:00:00:EE:03 -net vde disk_image
VDE2 Bridge
quickhowto: qemu networking using vde, tun/tap, and bridge に基づいています。vde に接続された仮想マシンは外部から参照できる状態になります。例えば、ADSL ルーターから直接 DHCP の設定を個々の仮想マシンが受け取ることが可能です。
基本
tun モジュールと bridge-utils パッケージが必要です。
vde2/tap デバイスを作成:
# vde_switch -tap tap0 -daemon -mod 660 -group users # ip link set tap0 up
ブリッジを作成:
# brctl addbr br0
デバイスを追加:
# brctl addif br0 eth0 # brctl addif br0 tap0
ブリッジインターフェイスを設定:
# dhcpcd br0
起動スクリプト
全てのデバイスを設定する必要があります。ブリッジに必要なのは IP アドレスだけです。ブリッジの物理デバイスは (例: eth0)、netctl でカスタム Ethernet プロファイルを使います:
/etc/netctl/ethernet-noip
Description='A more versatile static Ethernet connection' Interface=eth0 Connection=ethernet IP=no
以下のカスタム systemd サービスを使うことで users ユーザーグループで使用する VDE2 tap インターフェイスを作成することができます。
/etc/systemd/system/vde2@.service
[Unit] Description=Network Connectivity for %i Wants=network.target Before=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/vde_switch -tap %i -daemon -mod 660 -group users ExecStart=/usr/bin/ip link set dev %i up ExecStop=/usr/bin/ip addr flush dev %i ExecStop=/usr/bin/ip link set dev %i down [Install] WantedBy=multi-user.target
そして最後に、netctl でブリッジネットワークを作成することが可能です。