#!/bin/bash set -e # =============================================== # QEMU 虚拟网络自动配置脚本(支持 NAT + DHCP) # 自动清理旧桥接与 TAP 接口,避免 "Device busy" 错误 # 适用于:openEuler / CentOS / Ubuntu # =============================================== # ---- 用户可配置参数 ---- BR_MAIN="br0" # 外部桥接网桥 BR_INNER="br4" # 内部桥接网桥 TAP_OUT="tapgayu_1" # 外部 TAP TAP_IN="tap_ingayu_1" # 内部 TAP HOST_IP_MAIN="100.0.0.1/24" # 宿主机外部桥 IP HOST_IP_INNER="192.168.56.1/24" # 宿主机内部桥 IP DHCP_RANGE_MAIN="100.0.0.10,100.0.0.10,12h" DHCP_RANGE_INNER="192.168.56.10,192.168.56.100,12h" WAN_IF=$(ip route get 8.8.8.8 | awk '/dev/ {print $5; exit}') # 自动检测外网接口 # ---- 工具检测 ---- for cmd in ip sysctl dnsmasq; do if ! command -v $cmd &>/dev/null; then echo "[-] 缺少命令: $cmd,请先安装" exit 1 fi done # ---- 自动清理旧网络 ---- echo "[*] 清理旧网络配置..." for iface in $TAP_OUT $TAP_IN $BR_MAIN $BR_INNER; do if ip link show "$iface" &>/dev/null; then echo " - 删除接口 $iface" ip link set "$iface" down || true ip link delete "$iface" type bridge 2>/dev/null || ip tuntap del dev "$iface" mode tap 2>/dev/null || true fi done killall dnsmasq 2>/dev/null || true sleep 1 # ---- 加载 tun 模块 ---- echo "[+] 加载 tun 模块" modprobe tun || true # ---- 创建外部桥接网络 ---- echo "[+] 创建外部桥接网络 $BR_MAIN" ip link add name $BR_MAIN type bridge ip addr add $HOST_IP_MAIN dev $BR_MAIN ip link set $BR_MAIN up
echo "[+] 创建 TAP 接口 $TAP_OUT" ip tuntap add dev $TAP_OUT mode tap ip link set $TAP_OUT master $BR_MAIN ip link set $TAP_OUT up # ---- 创建内部桥接网络 ---- echo "[+] 创建内部桥接网络 $BR_INNER" ip link add name $BR_INNER type bridge ip addr add $HOST_IP_INNER dev $BR_INNER ip link set $BR_INNER up
echo "[+] 创建 TAP 接口 $TAP_IN" ip tuntap add dev $TAP_IN mode tap ip link set $TAP_IN master $BR_INNER ip link set $TAP_IN up # ---- 启用 IP 转发和 NAT ---- echo "[+] 启用 IP 转发和 NAT" sysctl -w net.ipv4.ip_forward=1 >/dev/null iptables -t nat -C POSTROUTING -o $WAN_IF -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -o $WAN_IF -j MASQUERADE # ---- 启动 DHCP 服务 (dnsmasq) ---- echo "[+] 启动 DHCP 服务 (dnsmasq)" mkdir -p /var/run/qemu-dhcp dnsmasq --interface=$BR_MAIN \ --bind-interfaces \ --except-interface=lo \ --dhcp-range=$DHCP_RANGE_MAIN \ --pid-file=/var/run/qemu-dhcp/dnsmasq-$BR_MAIN.pid \ --dhcp-option=3,100.0.0.1 \ --log-facility=/var/run/qemu-dhcp/dnsmasq-$BR_MAIN.log \ --conf-file= &
sleep 1 # ---- 检查启动状态 ---- if ! pgrep -f "dnsmasq.*$BR_MAIN" >/dev/null; then echo "[-] DHCP 服务启动失败,请检查日志 /var/run/qemu-dhcp/dnsmasq-$BR_MAIN.log" exit 1 fi # ---- 打印网络状态 ---- echo "[+] 网络配置完成" ip addr show $BR_MAIN ip addr show $BR_INNER echo echo "[+] dnsmasq 已启动,日志目录:/var/run/qemu-dhcp/" echo "[+] 虚拟机连接 tap 接口后,将自动通过 DHCP 获得 IP"
# CONFIG_MODULE_SIG is not set # CONFIG_MODULE_SIG_ALL is not set # CONFIG_MODULE_SIG_FORCE is not set CONFIG_SYSTEM_TRUSTED_KEYS="" CONFIG_SYSTEM_REVOCATION_KEYS=""
尤其是下面的
1
CONFIG_MODULE_SIG=y
要修改为
1
# CONFIG_MODULE_SIG is not set
其次我们编辑.config开启9p文件系统,这样能够支持文件夹的挂载
1 2 3 4 5 6
CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y CONFIG_9P_FS=y CONFIG_9P_FS_POSIX_ACL=y CONFIG_PCI=y # CONFIG_NET_9P_DEBUG is not set
#!/bin/bash set -e # =============================================== # QEMU 虚拟网络自动配置脚本(支持 NAT + DHCP) # 自动清理旧桥接与 TAP 接口,避免 "Device busy" 错误 # 适用于:openEuler / CentOS / Ubuntu # =============================================== # ---- 用户可配置参数 ---- BR_MAIN="br0" # 外部桥接网桥 BR_INNER="br4" # 内部桥接网桥 TAP_OUT="tapgayu_1" # 外部 TAP TAP_IN="tap_ingayu_1" # 内部 TAP HOST_IP_MAIN="100.0.0.1/24" # 宿主机外部桥 IP HOST_IP_INNER="192.168.56.1/24" # 宿主机内部桥 IP DHCP_RANGE_MAIN="100.0.0.10,100.0.0.10,12h" DHCP_RANGE_INNER="192.168.56.10,192.168.56.100,12h" WAN_IF=$(ip route get 8.8.8.8 | awk '/dev/ {print $5; exit}') # 自动检测外网接口 # ---- 工具检测 ---- for cmd in ip sysctl dnsmasq; do if ! command -v $cmd &>/dev/null; then echo "[-] 缺少命令: $cmd,请先安装" exit 1 fi done # ---- 自动清理旧网络 ---- echo "[*] 清理旧网络配置..." for iface in $TAP_OUT $TAP_IN $BR_MAIN $BR_INNER; do if ip link show "$iface" &>/dev/null; then echo " - 删除接口 $iface" ip link set "$iface" down || true ip link delete "$iface" type bridge 2>/dev/null || ip tuntap del dev "$iface" mode tap 2>/dev/null || true fi done killall dnsmasq 2>/dev/null || true sleep 1 # ---- 加载 tun 模块 ---- echo "[+] 加载 tun 模块" modprobe tun || true # ---- 创建外部桥接网络 ---- echo "[+] 创建外部桥接网络 $BR_MAIN" ip link add name $BR_MAIN type bridge ip addr add $HOST_IP_MAIN dev $BR_MAIN ip link set $BR_MAIN up
echo "[+] 创建 TAP 接口 $TAP_OUT" ip tuntap add dev $TAP_OUT mode tap ip link set $TAP_OUT master $BR_MAIN ip link set $TAP_OUT up # ---- 创建内部桥接网络 ---- echo "[+] 创建内部桥接网络 $BR_INNER" ip link add name $BR_INNER type bridge ip addr add $HOST_IP_INNER dev $BR_INNER ip link set $BR_INNER up
echo "[+] 创建 TAP 接口 $TAP_IN" ip tuntap add dev $TAP_IN mode tap ip link set $TAP_IN master $BR_INNER ip link set $TAP_IN up # ---- 启用 IP 转发和 NAT ---- echo "[+] 启用 IP 转发和 NAT" sysctl -w net.ipv4.ip_forward=1 >/dev/null iptables -t nat -C POSTROUTING -o $WAN_IF -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -o $WAN_IF -j MASQUERADE # ---- 启动 DHCP 服务 (dnsmasq) ---- echo "[+] 启动 DHCP 服务 (dnsmasq)" mkdir -p /var/run/qemu-dhcp dnsmasq --interface=$BR_MAIN \ --bind-interfaces \ --except-interface=lo \ --dhcp-range=$DHCP_RANGE_MAIN \ --pid-file=/var/run/qemu-dhcp/dnsmasq-$BR_MAIN.pid \ --dhcp-option=3,100.0.0.1 \ --log-facility=/var/run/qemu-dhcp/dnsmasq-$BR_MAIN.log \ --conf-file= &
sleep 1 # ---- 检查启动状态 ---- if ! pgrep -f "dnsmasq.*$BR_MAIN" >/dev/null; then echo "[-] DHCP 服务启动失败,请检查日志 /var/run/qemu-dhcp/dnsmasq-$BR_MAIN.log" exit 1 fi # ---- 打印网络状态 ---- echo "[+] 网络配置完成" ip addr show $BR_MAIN ip addr show $BR_INNER echo echo "[+] dnsmasq 已启动,日志目录:/var/run/qemu-dhcp/" echo "[+] 虚拟机连接 tap 接口后,将自动通过 DHCP 获得 IP"