Linux Bridge:解決 virt-manager 與 AdGuard Home DNS 端口衝突問題

解決 virt-manager 使用時,因 AdGuard Home 佔用 53 port,導致 dnsmasq 無法啟動的問題與解法。

前言

最近友人在使用 virt-manager 遇到了問題

大概會像這篇說的
reddit
dnsmasq: failed to create listening socket for 192.168.122.1: Address already in use

Root Cause

經過詢問後,在同一台機器上面,友人使用 Docker 起了一台 Adguard Home expose port bind 在 0.0.0.0:53,所以 dnsmasq 會報上面的錯誤。

dnsmasq 是甚麼

Dnsmasq 提供小型網路的 DNS、DHCP、路由廣播與網路開機等基礎設施。

dns port 預設會綁定在 53 port 上,所以這時候 dnsmasq 就會跟 docker 的 adguard home 撞。

其實碰撞的原因要講得更多一點會扯到 Linux 中如何判斷 port/addr 可以 bind 成功,這篇有詳細說明。

如果不用 SO_REUSEADDR 的話,如果我們將 socketA 綁定到 0.0.0.0:21,那麼任何將本機其他 socket 綁定到端口 21 的舉動(如綁定到 192.168.1.1:21)都會導致 EADDRINUSE 錯誤。因為 0.0.0.0 是一個通配符 IP 地址,意味著任意一個 IP 地址,所以任何其他本機上的 IP 地址都被系統認為已被佔用。如果設置了 SO_REUSEADDR 選項,因為 0.0.0.0:21 和 192.168.1.1:21 並不是完全相同的地址端口對,所以可以同時綁定。

Sol

  1. 向其他的 Hypervisor 學習,不要起 dnsmasq,去建立一個 br0 讓 VM 直接透過 br0 與家用網路直接連線
flowchart TD eno0---br0 br0---vm1 br0---vm2

可能可以解

  1. 將 adguard home 的 bind address 改成希望外面可以接觸到的 ip e.g. 192.168.0.X:53

    explain : 避免他 bind 在 0.0.0.0 把所有的 53 port 卡住。
    0.0.0.0 表示電腦上所有的 ip

  2. 使用 docker 的 macvlan 功能讓每一台 container 各自擁有自己的 IP

    side effect : 這樣 host 就不能與 container 通訊

updatedupdated2026-01-172026-01-17
載入評論