Điểm:1

How run a dnsmasq inside QEMU, providing netboot service to other VMs

lá cờ ph

EDIT: WIP: The core reason for the failures explained below is due to me not bringing up the host TAP interfaces at the right time, if I allow QEMU to handle the creation of the tap devices, everything works as expected. I will investigate the failure in more detail and provide a clearer explanation of the problem when I have it. Thank you @anx for the tips!

Goal: Run a dnsmasq inside a host QEMU VM, that services netboots from another QEMU VM running on the host.

I would like the dnsmasq VM to act like a gateway, with one NIC as the upstream WAN interface, with an upstream DHCP server, and the other interface a private LAN interface, to which other VMs will be "plugged", and will netboot from the dnsmasq listening on this private LAN interface.

First, to allow the VMs to talk to one another, I create my own bridge on the host,

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

For the VMs to talk to each other via the host bridge, I will need two tap devices, one for the private LAN interface on the gateway VM, and another for the private VMs single network interface,

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

For the gateway VM, I am using an Arch Linux ISO for testing purposes, the VM is booted with two NICs, thusly,

 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

Once this machine has booted, I see the following in the bridge configuration,

brctl show vivianbr0 

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

I assume tap2 was created by QEMU...

Inside this VM, there are two ifaces. ens4 with MAC DE:AD:BE:EF:00:11, and ens5 with MAC DE:AD:BE:EF:00:12. Inside this VM, I start 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

This starts wtihout error.

Now I try to netboot another VM, started on the host like this,

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

But it fails to boot. I monitor the vivianbr0 using tcpdump and can see the DHCP requests, but there are no responses, nothing reaches the dnsmasq running inside the first VM,

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

Oddly, I see BOOTP requests from de:ad:be:ef:00:13 (the netbooting VMs MAC addr) and from de:ad:be:ef:00:12 (the gateway VM's private NIC), indicating something is badly misconfigured.

How can I make this work?

Nikita Kipriyanov avatar
lá cờ za
Nếu bạn lắng nghe lưu lượng DHCP trên tap0 (cổng cầu) thì sao? Nó sẽ hiển thị thaffic mã cầu chuyển sang cổng đó. Ngoài ra, hãy kiểm tra bảng địa chỉ MAC của cầu trong khi yêu cầu; nó có lấp đầy với các MAC cần thiết không? Nhân tiện, cầu theo mặc định đặt độ trễ STP tiêu chuẩn, có nghĩa là cổng bắt đầu chuyển tiếp lưu lượng chỉ 30 giây sau khi nó bị xé "lên". Trong thiết lập cầu của bạn, tôi không thấy nơi nào bạn thay đổi điều này hoặc tắt STP. Và cuối cùng, máy ảo được cho là khởi động từ máy ảo dnsmasq: nó sử dụng cổng cầu nối nào? Phải có một giao diện nhấn khác bên trong cầu, cho VM thứ hai.
lá cờ ph
@anx Liên quan đến `-netdev brdige`, điều này trả lời câu hỏi như thế nào? Nó cho phép tôi gắn các thiết bị nhấn vào cầu nối *có tên khác*, nhưng vấn đề là tôi cần QEMU ủy quyền thiết bị khách cho cầu nối máy chủ để dnsmasq bên trong máy ảo có thể phục vụ các yêu cầu do cầu nối máy chủ xử lý.
lá cờ ph
@NikitaKipriyanov Tôi đã trả lời câu hỏi đầu tiên của bạn trong một bản chỉnh sửa. STP không chạy trên cầu. Tôi không biết cách kiểm tra bảng địa chỉ MAC của cầu trong khi yêu cầu. Có vẻ như một vấn đề đơn giản hơn về các giao diện không thể được đưa lên.
lá cờ ph
@anx Về lời gọi `dnsmasq`.Việc phân tích hơi phức tạp, nhưng VM cổng của tôi đặt tên cho hai giao diện dựa trên quy tắc này: bất kỳ giao diện nào đáp ứng yêu cầu DHCP, được đặt tên là `công khai`, giao diện còn lại là `riêng tư`. Trong triển khai sản xuất, giao diện chung được kết nối với máy chủ DHCP ngược dòng, giao diện riêng thì không. Sau đó, lệnh `dnsmasq` như tôi đã viết trong câu hỏi của mình, nhưng với `--interface=private`
anx avatar
lá cờ fr
anx
Tôi thích rằng câu hỏi của bạn đề cập đến tất cả các bước đã thử, nhưng tôi nghi ngờ rằng các sự kiện chính có phần bị che khuất bởi các phiên bản khác nhau.. hãy chú ý thêm ảnh chụp nhanh nhất quán về tình huống hiện tại vào câu hỏi của bạn (cả cmdlines qemu, cmdline dnsmasq và cả 3 đầu ra từ `ip a l`)?
lá cờ ph
@anx Có, tôi thực sự cần phải tự mình quản lý các thiết bị nhấn. Tôi đã cố gắng viết ngắn gọn nhất có thể, nhưng không làm tốt ở đó, vì vậy chỉ cần nói rằng... Có lý do :)
lá cờ ph
@anx Đơn giản là "dnsmasq trên máy khách" không thể hoạt động, vì lý do tương tự dnsmasq trên `tap0` chứ không phải `br0` không hoạt động. Đây là một ví dụ tối thiểu hóa theo yêu cầu của bạn. Nếu tôi bắt đầu dnsmasq bên trong máy ảo QEMU với `-netdev tap,id=net1,ifname=tap0,script=no,downscript=no`, thì đó là hành vi tương tự như ví dụ tôi đã đưa ra trong câu hỏi của mình, chỉ có điều khác mức độ gián tiếp giữa mạng iface của khách và máy chủ.
Tom Yan avatar
lá cờ in
Bạn không thực sự có ý nghĩa gì cả. Liên kết dnsmasq với một lần nhấn trên máy chủ (dù sao cũng không có nghĩa là KHÔNG hoạt động) KHÔNG liên quan gì đến việc có một máy ảo đang chạy dnsmasq (liên kết với NIC ảo hóa bên trong máy ảo), bất kể bạn có thể có cái sau hay không đang làm việc. Không có kiểm tra điểm/kiểm tra chéo/khắc phục sự cố với phương pháp "đơn giản hóa" của bạn, vì nó KHÔNG phải là một sự đơn giản hóa nào cả.
Tom Yan avatar
lá cờ in
Điều đầu tiên tôi nghĩ đến là, qemu không liệt kê hoặc sắp xếp ngẫu nhiên địa chỉ MAC của từng máy ảo.Nó luôn là `52:54:00:12:34:56` nếu không được đặt/thay đổi rõ ràng với tùy chọn qemu. Bạn có thể muốn đảm bảo rằng bạn đã sửa lỗi đó, với tùy chọn qemu tương ứng hoặc, định cấu hình hệ thống của máy ảo để tự định cấu hình máy ảo "giả". Đảm bảo rằng bạn sẽ không nhầm lần nữa với địa chỉ MAC của các vòi trên máy chủ.
Tom Yan avatar
lá cờ in
Nhân tiện, bạn thực sự muốn làm rõ câu hỏi của mình (bằng cách loại bỏ tất cả những điều vô nghĩa không liên quan) nếu bạn vẫn muốn/cần trợ giúp thêm.
lá cờ ph
@TomYan Tôi đã viết lại hoàn toàn câu hỏi của mình. Hy vọng rằng nó là rõ ràng hơn cho bạn bây giờ. Tôi đã cố gắng đảm bảo các trình bổ sung MAC là duy nhất, mặc dù có lẽ tôi cũng chưa làm đúng.
Tom Yan avatar
lá cờ in
Trước hết, bạn không cần sử dụng `-net(dev) bridge` *ngoài* `-net(dev) tap`. Chúng không bổ sung cho nhau mà thay vào đó, cái trước sẽ tự động thêm một lần nhấn cho bạn và cái sau sử dụng một lần nhấn hiện có. Tôi khuyên bạn nên sử dụng phím tắt `-nic bridge,model=virtio,mac=SO:ME:MA:CA:DD:RE` để thay thế tất cả các tùy chọn liên quan đến mạng khác mà bạn hiện có. (`-nic` cũng có thể được sử dụng với `user` và `hostfwd btw của nó.)
Tom Yan avatar
lá cờ in
Tiếp theo, `...và từ de:ad:be:ef:00:12 (NIC riêng của cổng VM), cho biết có điều gì đó bị định cấu hình sai nghiêm trọng` đó là một giả định sai. Việc bạn có thấy các yêu cầu DHCP từ "máy chủ cổng" hay không tùy thuộc vào việc nó có chạy ứng dụng khách DHCP hay không. Arch ISO sử dụng `systemd-networkd` cho điều đó và theo mặc định, nó có DHCP (máy khách) được bật trên tất cả các NIC Ethernet IIRC.
Tom Yan avatar
lá cờ in
Cuối cùng, mặc dù tôi không quen thuộc với netboot, nhưng tại sao bạn lại mong đợi nó hoạt động như "vượt trội" miễn là có một máy chủ lưu trữ máy chủ dnsmasq/DHCP trong mạng? Và bất kể, tại sao bạn không bắt đầu khởi động Arch ISO để xác nhận rằng ít nhất phần gán địa chỉ của DHCP hoạt động trước? Xem https://wiki.archlinux.org/title/Netboot btw. (Lưu ý rằng hướng dẫn bên trong không liên quan gì đến ảo hóa, vì vậy tất cả chúng nên được áp dụng *bên trong* máy ảo chứ không phải máy chủ.)
Điểm:0
lá cờ fr
anx

Các bước của bạn cho hai khách đều ổn, tôi vừa sao chép thiết lập của bạn cho đến thời điểm cho thuê địa chỉ.Tôi có thể phân phát IP từ một máy ảo đang chạy dnsmasq cho một máy ảo đang chạy ứng dụng khách dhcp.

Kiểm tra những điều này:

  • không thể hiển thị các thiết bị nhấn chưa được kết nối
    • có thể nhìn thấy từ XUỐNG trạng thái trong ip a l đầu ra của máy chủ (nên nói KHÔNG XÁC ĐỊNH hoặc HƯỚNG LÊN)
      • nếu bạn để qemu tạo thiết bị nhấn, qemu-bridge-helper sẽ đưa nó lên
      • nếu bạn sử dụng tập lệnh =, hãy đưa thiết bị lên đó
      • nếu không, bạn phải thiết lập liên kết ip tapN lên một thời gian sau khi vm bắt đầu
  • Địa chỉ MAC cần phải là duy nhất
    • có thể nhìn thấy trong ête địa chỉ trong ip a l trong khách
    • liệt kê các máy Mac đã học (không phải máy chủ), ví dụ: brctl showmac ​​br0 nên có hai các mục có bộ đếm thời gian lão hóa khác không
  • thả gói qua iptables
    • kiểm tra /proc/sys/net/bridge/bridge-nf-call* và liệu br_netfilter mô-đun được tải
    • thêm quy tắc ghi nhật ký, đối với IPv4, đại loại như iptables -A FORWARD -j LOG --log-prefix "forward drop" trước khi thả hoặc trước chính sách DROP trên bảng FORWARD
    • phớt lờ /sys/class/net/br*/bridge/nf_call_* (Tôi không biết tại sao những có thể tắt khi bật tính năng lọc)

Những điểm đáng chú ý khác mà tôi tìm thấy khi thử nghiệm:

  • Qemu đã thêm vnet_hdr tùy chọn trên thiết bị vòi của tôi. Điều đó có vẻ hợp lý và có thể đã bị vô hiệu hóa trên cmdline qemu nếu muốn.
  • Đôi khi tuyến đường (liên kết phạm vi) của tôi cho cây cầu bị mất. Tôi vẫn chưa xác định làm thế nào điều đó thậm chí có thể xảy ra.

Về nỗ lực của bạn để đơn giản hóa thử nghiệm bằng cách liên kết với thiết bị nhấn..

dnsmasq sẽ chạy bên trong máy ảo QEMU

Các thiết bị nhấn liên tục AFAIK không sử dụng được cho đến khi thực sự được gắn vào. Vì vậy, bạn chỉ có thể kiểm tra thiết lập đầy đủ một cách có ý nghĩa:

  • Bạn có muốn chạy dnsmasq trên máy chủ không?
    • sau đó gắn nó vào thiết bị cầu nối
  • hay bạn muốn chạy dnsmasq bên trong máy ảo?
    • sau đó gắn nó vào giao diện mạng tương ứng phía trong máy ảo đó

--interface=tap0

Gợi ý: Sử dụng --bind-giao diện để hướng dẫn dnsmasq chuyển từ việc chỉ loại bỏ lưu lượng truy cập từ các giao diện khác sang thực sự cố gắng liên kết, do đó thoát ra một cách chi tiết khi bắt đầu với các cài đặt không sử dụng được.

lá cờ ph
Câu hỏi của tôi là tất cả về việc chạy dnsmasq *bên trong máy ảo*, các ví dụ host-dnsmasq chỉ để cung cấp cho bạn ví dụ đơn giản hơn về sự cố. Nếu bạn biết làm thế nào để có một ưu đãi dnsmasq *bên trong máy ảo* cho một máy ảo khởi động qua mạng khác thuê, tôi sẽ rất muốn tìm hiểu!
lá cờ ph
Để rõ ràng hơn nữa, tôi đã chỉnh sửa lại câu hỏi của mình để đưa ra một ví dụ về dnsmasq trong cách tiếp cận của khách mà tôi đang thử
anx avatar
lá cờ fr
anx
Tôi *nghĩ* mình biết cách thực hiện vì tôi đã làm việc đó trong nhiều năm.. nhưng sau đó tôi loay hoay và tìm thấy *ba* lý do lặt vặt khác nhau khiến nó có thể thất bại.
lá cờ ph
Cảm ơn rất nhiều @anx, tôi đã đạt được một số tiến bộ nhờ ghi chú của bạn.Có vẻ như việc tôi không đưa các thiết bị vòi được tạo thủ công vào đúng thời điểm là nguồn gốc của các vấn đề của tôi. Nếu tôi để QEMU xử lý chúng, thì quá trình khởi động mạng thực sự hoạt động. Tôi sẽ cập nhật câu hỏi của mình và có thể đưa ra lời giải thích rõ ràng hơn về lỗi sau khi tôi tìm hiểu thêm một chút về cách xử lý đúng trường hợp sử dụng của mình. Cảm ơn rất nhiều, tôi nợ bạn vài cốc bia!

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.