如何在 QEMU 內運行 dnsmasq,為其他虛擬機器提供網路啟動服務

如何在 QEMU 內運行 dnsmasq,為其他虛擬機器提供網路啟動服務

編輯:WIP:下面解釋的失敗的核心原因是由於我沒有在正確的時間啟動主機 TAP 接口,如果我允許 QEMU 處理 Tap 設備的創建,一切都會按預期進行。當我遇到故障時,我將更詳細地調查故障並提供更清晰的問題解釋。謝謝@anx 的提示!

目標:dnsmasq在主機內部執行 QEMU VM,為主機上執行的另一個 QEMU VM 提供網路啟動服務。

我希望 dnsmasq 虛擬機充當網關,一個 NIC 作為上游 WAN 接口,具有上游 DHCP 伺服器,另一個接口是專用 LAN 接口,其他虛擬機將“插入”到該接口,並從網絡啟動dnsmasq 在此專用LAN 接口上偵聽。

首先,為了允許虛擬機器相互通信,我在主機上建立了自己的網橋,

ip link add name vivianbr0 type bridge
ip link set vivianbr0 up

為了讓虛擬機透過主機橋相互通信,我需要兩個分路設備,一個用於網關虛擬機上的專用 LAN 接口,另一個用於專用虛擬機的單一網絡接口,

ip tuntap add mode tap tap0 user cturner
ip tuntap add mode tap tap1 user cturner
ip link set tap0 up
ip link set tap1 up
ip link set tap0 master vivianbr0
ip link set tap1 master vivianbr0

對於網關 VM,我使用 Arch Linux ISO 進行測試,VM 使用兩個 NIC 啟動,因此,

 qemu-system-x86_64 \
    -drive file=arch-disk.qcow2,if=none,id=nvm \
    -device nvme,serial=deadbeef,drive=nvm \
    -cdrom archlinux-2021.09.01-x86_64.iso \
    -boot d \
    -device virtio-net-pci,romfile=,netdev=net0,mac="DE:AD:BE:EF:00:11" \
    -device virtio-net-pci,romfile=,netdev=net1,mac="DE:AD:BE:EF:00:12" \
    `# Simulate the plugged in "upstream" cable with user-mode networking` \
    -netdev user,id=net0,hostfwd=tcp::60022-:22,hostfwd=tcp::8080-:80,hostfwd=tcp::8081-:8000,hostfwd=tcp::2375-:2375 \
    `# And now the unplugged one with, with TAP networks` \
    -netdev tap,id=net1,ifname=tap0,script=no,downscript=no \
-net bridge,br=vivianbr0 \
    -m 4G \
    -enable-kvm

一旦這台機器啟動,我就會在橋接配置中看到以下內容,

brctl show vivianbr0 

bridge name     bridge id               STP enabled     interfaces
vivianbr0               8000.46954a1ad851       no              tap0
                            tap1
                            tap2

我認為tap2是由 QEMU 創建的...

在這個虛擬機器內部,有兩個 iface。ens4與 MAC DE:AD:BE:EF:00:11 和ens5MAC DE:AD:BE:EF:00:12。在這個虛擬機器中,我開始dnsmasq

ip addr add 10.42.0.1/24 dev ens5
dnsmasq -d --dhcp-range=10.42.0.10,10.42.0.100 --dhcp-script=/bin/echo --enable-tftp=ens5 --interface=ens5

這開始沒有錯誤。

現在我嘗試網路啟動另一個虛擬機,在主機上啟動,如下所示,

qemu-system-x86_64 \
-machine pc-q35-6.0,accel=kvm \
-m 1024 -smp 2,sockets=2,cores=1,threads=1 \
-netdev tap,id=net0,ifname=tap1,script=no,downscript=no \
-device virtio-net-pci,netdev=net0,bootindex=1,mac=DE:AD:BE:EF:00:13 \
-net bridge,br=vivianbr0 \
-enable-kvm \
-vga virtio

但無法啟動。我監控vivianbr0使用情況tcpdump並可以看到 DHCP 請求,但沒有回應,沒有任何內容到達第一個虛擬機器內運行的 dnsmasq,

tcpdump -i vivianbr0 -nN
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vivianbr0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:21:39.585229 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:40.587741 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:40.700038 IP6 fe80::6ce2:2aff:fe94:ba48.5353 > ff02::fb.5353: 0 [7q] PTR (QM)? _nfs._tcp.local. PTR (QM)? _ftp._tcp.local. PTR (QM)? _webdav._tcp.local. PTR (QM)? _webdavs._tcp.local. PTR (QM)? _sftp-ssh._tcp.local. PTR (QM)? _smb._tcp.local. PTR (QM)? _afpovertcp._tcp.local. (118)
12:21:42.619968 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:21:46.684448 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:13, length 397
12:22:30.609555 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289
12:23:33.796148 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289
12:24:38.673364 IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:be:ef:00:12, length 289

de:ad:be:ef:00:13奇怪的是,我看到來自(網路啟動虛擬機器 MAC 位址)的 BOOTP 請求和來自 de:ad:be:ef:00:12(網關虛擬機器的專用網路卡),表示某些配置嚴重錯誤。

我怎樣才能做到這一點?

答案1

您的兩位客人的步驟沒問題,我剛剛複製了您的設置直到租賃地址點。我可以將 IP 從一台運行 dnsmasq 的虛擬機器分發給一台運行 dhcp 用戶端的虛擬機器。

檢查這些:

  • 無法啟動未連接的 Tap 設備
    • 從主機輸出DOWN中的狀態可見(應該說或) ip a lUNKNOWNUP
      • 如果您讓 qemu 建立 Tap 設備,則會qemu-bridge-helper將其調出
      • 如果您使用 script=,請在那裡調出設備
      • 否則,你必須ip link set tapN up在虛擬機器啟動後一段時間
  • MAC 位址必須是唯一的
    • 在客人的ether地址中可見ip a l
    • 列出學習到的(非主機)mac,例如brctl showmacs br0應該有具有非零老化計時器的條目
  • 透過 iptables 丟棄資料包
    • 檢查模組/proc/sys/net/bridge/bridge-nf-call*是否br_netfilter已加載
    • 新增日誌記錄規則,對於 IPv4,例如iptables -A FORWARD -j LOG --log-prefix "forward dropped"在刪除之前或在 FORWARD 表上的 DROP 政策之前新增日誌記錄規則
    • 忽略/sys/class/net/br*/bridge/nf_call_*(我不知道為什麼這些過濾開啟時關閉)

我在測試時發現的其他值得注意的地方:

  • Qemuvnet_hdr在我的 Tap 裝置上新增了該選項。這似乎是合理的,如果需要的話,可以在 qemu 命令列上停用。
  • 有時我的橋(範圍連結)路線會遺失。我還沒有確定這是如何發生的。

關於您嘗試透過綁定到 Tap 裝置來簡化測試。

dnsmasq 將在 QEMU VM 內運行

據我所知,持久點擊設備在實際連接之前無法使用。因此,您只能有意義地測試任一完整設定:

  • 您想在主機上執行 dnsmasq 嗎?
    • 然後將其連接到橋接設備
  • 或者你想在虛擬機器內運行 dnsmasq 嗎?
    • 然後將其連接到相應的網路接口裡面那台虛擬機

--介面=tap0

提示:用於--bind-interfaces指示 dnsmasq 從僅丟棄來自其他介面的流量切換到實際嘗試綁定,從而在以不可用的設定啟動時詳細退出。

相關內容